diff --git a/modules/svg/include/SkSVGFe.h b/modules/svg/include/SkSVGFe.h index ac4d8c4056..a2d990e8af 100644 --- a/modules/svg/include/SkSVGFe.h +++ b/modules/svg/include/SkSVGFe.h @@ -35,7 +35,8 @@ public: * Spec: https://www.w3.org/TR/SVG11/painting.html#ColorInterpolationProperties * 'color-interpolation-filters' property. */ - SkSVGColorspace resolveColorspace(const SkSVGRenderContext&) const; + virtual SkSVGColorspace resolveColorspace(const SkSVGRenderContext&, + const SkSVGFilterContext&) const; /** Propagates any inherited presentation attributes in the given context. */ void applyProperties(SkSVGRenderContext*) const; diff --git a/modules/svg/include/SkSVGFilterContext.h b/modules/svg/include/SkSVGFilterContext.h index 19f1e15050..704d6ca095 100644 --- a/modules/svg/include/SkSVGFilterContext.h +++ b/modules/svg/include/SkSVGFilterContext.h @@ -32,6 +32,11 @@ public: void registerResult(const SkSVGStringType&, const sk_sp&, const SkRect&, SkSVGColorspace); + SkSVGColorspace resolveInputColorspace(const SkSVGRenderContext&, + const SkSVGFeInputType&) const; + + sk_sp resolveInput(const SkSVGRenderContext&, const SkSVGFeInputType&) const; + sk_sp resolveInput(const SkSVGRenderContext&, const SkSVGFeInputType&, SkSVGColorspace) const; private: @@ -43,6 +48,9 @@ private: const Result* findResultById(const SkSVGStringType&) const; + std::tuple, SkSVGColorspace> getInput(const SkSVGRenderContext&, + const SkSVGFeInputType&) const; + SkRect fFilterEffectsRegion; SkSVGObjectBoundingBoxUnits fPrimitiveUnits; diff --git a/modules/svg/src/SkSVGFe.cpp b/modules/svg/src/SkSVGFe.cpp index c2095eb8c3..45db679180 100644 --- a/modules/svg/src/SkSVGFe.cpp +++ b/modules/svg/src/SkSVGFe.cpp @@ -92,7 +92,8 @@ SkRect SkSVGFe::resolveFilterSubregion(const SkSVGRenderContext& ctx, return subregion; } -SkSVGColorspace SkSVGFe::resolveColorspace(const SkSVGRenderContext& ctx) const { +SkSVGColorspace SkSVGFe::resolveColorspace(const SkSVGRenderContext& ctx, + const SkSVGFilterContext&) const { constexpr SkSVGColorspace kDefaultCS = SkSVGColorspace::kSRGB; const SkSVGColorspace cs = *ctx.presentationContext().fInherited.fColorInterpolationFilters; return cs == SkSVGColorspace::kAuto ? kDefaultCS : cs; diff --git a/modules/svg/src/SkSVGFeBlend.cpp b/modules/svg/src/SkSVGFeBlend.cpp index 89490b931b..9bf1e30eab 100644 --- a/modules/svg/src/SkSVGFeBlend.cpp +++ b/modules/svg/src/SkSVGFeBlend.cpp @@ -39,7 +39,7 @@ sk_sp SkSVGFeBlend::onMakeImageFilter(const SkSVGRenderContext& c const SkSVGFilterContext& fctx) const { const SkRect cropRect = this->resolveFilterSubregion(ctx, fctx); const SkBlendMode blendMode = GetBlendMode(this->getMode()); - const SkSVGColorspace colorspace = this->resolveColorspace(ctx); + const SkSVGColorspace colorspace = this->resolveColorspace(ctx, fctx); const sk_sp background = fctx.resolveInput(ctx, fIn2, colorspace); const sk_sp foreground = fctx.resolveInput(ctx, this->getIn(), colorspace); return SkImageFilters::Blend(blendMode, background, foreground, cropRect); diff --git a/modules/svg/src/SkSVGFeColorMatrix.cpp b/modules/svg/src/SkSVGFeColorMatrix.cpp index 9f45bc8028..58c84d3bb3 100644 --- a/modules/svg/src/SkSVGFeColorMatrix.cpp +++ b/modules/svg/src/SkSVGFeColorMatrix.cpp @@ -93,7 +93,7 @@ sk_sp SkSVGFeColorMatrix::onMakeImageFilter(const SkSVGRenderCont const SkSVGFilterContext& fctx) const { return SkImageFilters::ColorFilter( SkColorFilters::Matrix(makeMatrixForType()), - fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx)), + fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx, fctx)), this->resolveFilterSubregion(ctx, fctx)); } diff --git a/modules/svg/src/SkSVGFeComposite.cpp b/modules/svg/src/SkSVGFeComposite.cpp index d21b456d37..3ae12d9f70 100644 --- a/modules/svg/src/SkSVGFeComposite.cpp +++ b/modules/svg/src/SkSVGFeComposite.cpp @@ -47,7 +47,7 @@ SkBlendMode SkSVGFeComposite::BlendModeForOperator(SkSVGFeCompositeOperator op) sk_sp SkSVGFeComposite::onMakeImageFilter(const SkSVGRenderContext& ctx, const SkSVGFilterContext& fctx) const { const SkRect cropRect = this->resolveFilterSubregion(ctx, fctx); - const SkSVGColorspace colorspace = this->resolveColorspace(ctx); + const SkSVGColorspace colorspace = this->resolveColorspace(ctx, fctx); const sk_sp background = fctx.resolveInput(ctx, fIn2, colorspace); const sk_sp foreground = fctx.resolveInput(ctx, this->getIn(), colorspace); if (fOperator == SkSVGFeCompositeOperator::kArithmetic) { diff --git a/modules/svg/src/SkSVGFeGaussianBlur.cpp b/modules/svg/src/SkSVGFeGaussianBlur.cpp index 6ee1399bf0..54ea011acf 100644 --- a/modules/svg/src/SkSVGFeGaussianBlur.cpp +++ b/modules/svg/src/SkSVGFeGaussianBlur.cpp @@ -29,9 +29,10 @@ sk_sp SkSVGFeGaussianBlur::onMakeImageFilter(const SkSVGRenderCon sigmaY *= objBounds.height(); } - return SkImageFilters::Blur(sigmaX, sigmaY, - fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx)), - this->resolveFilterSubregion(ctx, fctx)); + return SkImageFilters::Blur( + sigmaX, sigmaY, + fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx, fctx)), + this->resolveFilterSubregion(ctx, fctx)); } template <> diff --git a/modules/svg/src/SkSVGFeMorphology.cpp b/modules/svg/src/SkSVGFeMorphology.cpp index 2489a5babb..67310c8e9d 100644 --- a/modules/svg/src/SkSVGFeMorphology.cpp +++ b/modules/svg/src/SkSVGFeMorphology.cpp @@ -23,7 +23,7 @@ bool SkSVGFeMorphology::parseAndSetAttribute(const char* name, const char* value sk_sp SkSVGFeMorphology::onMakeImageFilter(const SkSVGRenderContext& ctx, const SkSVGFilterContext& fctx) const { const SkRect cropRect = this->resolveFilterSubregion(ctx, fctx); - const SkSVGColorspace colorspace = this->resolveColorspace(ctx); + const SkSVGColorspace colorspace = this->resolveColorspace(ctx, fctx); sk_sp input = fctx.resolveInput(ctx, this->getIn(), colorspace); SkScalar rx = fRadius.fX; diff --git a/modules/svg/src/SkSVGFeOffset.cpp b/modules/svg/src/SkSVGFeOffset.cpp index fa9204a93f..df29c83fc5 100644 --- a/modules/svg/src/SkSVGFeOffset.cpp +++ b/modules/svg/src/SkSVGFeOffset.cpp @@ -28,6 +28,7 @@ sk_sp SkSVGFeOffset::onMakeImageFilter(const SkSVGRenderContext& dy *= objBounds.height(); } - sk_sp in = fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx)); + sk_sp in = + fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx, fctx)); return SkImageFilters::Offset(dx, dy, std::move(in), this->resolveFilterSubregion(ctx, fctx)); } diff --git a/modules/svg/src/SkSVGFilter.cpp b/modules/svg/src/SkSVGFilter.cpp index fcb325e5e2..01a252be1c 100644 --- a/modules/svg/src/SkSVGFilter.cpp +++ b/modules/svg/src/SkSVGFilter.cpp @@ -46,7 +46,7 @@ sk_sp SkSVGFilter::buildFilterDAG(const SkSVGRenderContext& ctx) feNode.applyProperties(&localCtx); // TODO: there are specific composition rules that need to be followed - cs = feNode.resolveColorspace(ctx); + cs = feNode.resolveColorspace(ctx, fctx); filter = feNode.makeImageFilter(localCtx, fctx); if (!feResultType.isEmpty()) { diff --git a/modules/svg/src/SkSVGFilterContext.cpp b/modules/svg/src/SkSVGFilterContext.cpp index aa15341745..57f2f51393 100644 --- a/modules/svg/src/SkSVGFilterContext.cpp +++ b/modules/svg/src/SkSVGFilterContext.cpp @@ -49,9 +49,8 @@ void SkSVGFilterContext::registerResult(const SkSVGStringType& id, fResults[id] = {result, subregion, resultColorspace}; } -sk_sp SkSVGFilterContext::resolveInput(const SkSVGRenderContext& ctx, - const SkSVGFeInputType& inputType, - SkSVGColorspace colorspace) const { +std::tuple, SkSVGColorspace> SkSVGFilterContext::getInput( + const SkSVGRenderContext& ctx, const SkSVGFeInputType& inputType) const { SkSVGColorspace inputCS = SkSVGColorspace::kSRGB; sk_sp result; switch (inputType.type()) { @@ -81,8 +80,25 @@ sk_sp SkSVGFilterContext::resolveInput(const SkSVGRenderContext& } default: SkDebugf("unhandled filter input type %d\n", inputType.type()); - return nullptr; + break; } + return {result, inputCS}; +} + +SkSVGColorspace SkSVGFilterContext::resolveInputColorspace( + const SkSVGRenderContext& ctx, const SkSVGFeInputType& inputType) const { + return std::get<1>(this->getInput(ctx, inputType)); +} + +sk_sp SkSVGFilterContext::resolveInput(const SkSVGRenderContext& ctx, + const SkSVGFeInputType& inputType) const { + return std::get<0>(this->getInput(ctx, inputType)); +} + +sk_sp SkSVGFilterContext::resolveInput(const SkSVGRenderContext& ctx, + const SkSVGFeInputType& inputType, + SkSVGColorspace colorspace) const { + auto [result, inputCS] = this->getInput(ctx, inputType); return ConvertFilterColorspace(std::move(result), inputCS, colorspace); }