[svg] Several filter helper tweaks
- Allow resolving inputs without modifying their colorspace - Add helper to get the colorspace of a particular input - Make resolveColorspace() virtual and add filter context to its signature Bug: skia:10841 Change-Id: I2e226ec26205f527c2d171140072f106ec35fbe0 Reviewed-on: https://skia-review.googlesource.com/c/skia/+/356416 Reviewed-by: Florin Malita <fmalita@chromium.org> Commit-Queue: Tyler Denniston <tdenniston@google.com>
This commit is contained in:
parent
b5db4825b8
commit
c7e482441e
@ -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;
|
||||
|
@ -32,6 +32,11 @@ public:
|
||||
|
||||
void registerResult(const SkSVGStringType&, const sk_sp<SkImageFilter>&, const SkRect&, SkSVGColorspace);
|
||||
|
||||
SkSVGColorspace resolveInputColorspace(const SkSVGRenderContext&,
|
||||
const SkSVGFeInputType&) const;
|
||||
|
||||
sk_sp<SkImageFilter> resolveInput(const SkSVGRenderContext&, const SkSVGFeInputType&) const;
|
||||
|
||||
sk_sp<SkImageFilter> resolveInput(const SkSVGRenderContext&, const SkSVGFeInputType&, SkSVGColorspace) const;
|
||||
|
||||
private:
|
||||
@ -43,6 +48,9 @@ private:
|
||||
|
||||
const Result* findResultById(const SkSVGStringType&) const;
|
||||
|
||||
std::tuple<sk_sp<SkImageFilter>, SkSVGColorspace> getInput(const SkSVGRenderContext&,
|
||||
const SkSVGFeInputType&) const;
|
||||
|
||||
SkRect fFilterEffectsRegion;
|
||||
|
||||
SkSVGObjectBoundingBoxUnits fPrimitiveUnits;
|
||||
|
@ -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;
|
||||
|
@ -39,7 +39,7 @@ sk_sp<SkImageFilter> 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<SkImageFilter> background = fctx.resolveInput(ctx, fIn2, colorspace);
|
||||
const sk_sp<SkImageFilter> foreground = fctx.resolveInput(ctx, this->getIn(), colorspace);
|
||||
return SkImageFilters::Blend(blendMode, background, foreground, cropRect);
|
||||
|
@ -93,7 +93,7 @@ sk_sp<SkImageFilter> 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));
|
||||
}
|
||||
|
||||
|
@ -47,7 +47,7 @@ SkBlendMode SkSVGFeComposite::BlendModeForOperator(SkSVGFeCompositeOperator op)
|
||||
sk_sp<SkImageFilter> 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<SkImageFilter> background = fctx.resolveInput(ctx, fIn2, colorspace);
|
||||
const sk_sp<SkImageFilter> foreground = fctx.resolveInput(ctx, this->getIn(), colorspace);
|
||||
if (fOperator == SkSVGFeCompositeOperator::kArithmetic) {
|
||||
|
@ -29,9 +29,10 @@ sk_sp<SkImageFilter> 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 <>
|
||||
|
@ -23,7 +23,7 @@ bool SkSVGFeMorphology::parseAndSetAttribute(const char* name, const char* value
|
||||
sk_sp<SkImageFilter> 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<SkImageFilter> input = fctx.resolveInput(ctx, this->getIn(), colorspace);
|
||||
|
||||
SkScalar rx = fRadius.fX;
|
||||
|
@ -28,6 +28,7 @@ sk_sp<SkImageFilter> SkSVGFeOffset::onMakeImageFilter(const SkSVGRenderContext&
|
||||
dy *= objBounds.height();
|
||||
}
|
||||
|
||||
sk_sp<SkImageFilter> in = fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx));
|
||||
sk_sp<SkImageFilter> in =
|
||||
fctx.resolveInput(ctx, this->getIn(), this->resolveColorspace(ctx, fctx));
|
||||
return SkImageFilters::Offset(dx, dy, std::move(in), this->resolveFilterSubregion(ctx, fctx));
|
||||
}
|
||||
|
@ -46,7 +46,7 @@ sk_sp<SkImageFilter> 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()) {
|
||||
|
@ -49,9 +49,8 @@ void SkSVGFilterContext::registerResult(const SkSVGStringType& id,
|
||||
fResults[id] = {result, subregion, resultColorspace};
|
||||
}
|
||||
|
||||
sk_sp<SkImageFilter> SkSVGFilterContext::resolveInput(const SkSVGRenderContext& ctx,
|
||||
const SkSVGFeInputType& inputType,
|
||||
SkSVGColorspace colorspace) const {
|
||||
std::tuple<sk_sp<SkImageFilter>, SkSVGColorspace> SkSVGFilterContext::getInput(
|
||||
const SkSVGRenderContext& ctx, const SkSVGFeInputType& inputType) const {
|
||||
SkSVGColorspace inputCS = SkSVGColorspace::kSRGB;
|
||||
sk_sp<SkImageFilter> result;
|
||||
switch (inputType.type()) {
|
||||
@ -81,8 +80,25 @@ sk_sp<SkImageFilter> 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<SkImageFilter> SkSVGFilterContext::resolveInput(const SkSVGRenderContext& ctx,
|
||||
const SkSVGFeInputType& inputType) const {
|
||||
return std::get<0>(this->getInput(ctx, inputType));
|
||||
}
|
||||
|
||||
sk_sp<SkImageFilter> 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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user