/* * Copyright 2020 Google Inc. * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "modules/svg/include/SkSVGFeMorphology.h" #include "include/core/SkImageFilter.h" #include "include/core/SkM44.h" #include "include/core/SkRect.h" #include "include/effects/SkImageFilters.h" #include "include/private/base/SkAssert.h" #include "modules/svg/include/SkSVGAttributeParser.h" #include "modules/svg/include/SkSVGFilterContext.h" #include "modules/svg/include/SkSVGRenderContext.h" #include bool SkSVGFeMorphology::parseAndSetAttribute(const char* name, const char* value) { return INHERITED::parseAndSetAttribute(name, value) || this->setOperator(SkSVGAttributeParser::parse( "operator", name, value)) || this->setRadius(SkSVGAttributeParser::parse( "radius", name, 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, fctx); sk_sp input = fctx.resolveInput(ctx, this->getIn(), colorspace); const auto r = SkV2{fRadius.fX, fRadius.fY} * ctx.transformForCurrentOBB(fctx.primitiveUnits()).scale; switch (fOperator) { case Operator::kErode: return SkImageFilters::Erode(r.x, r.y, input, cropRect); case Operator::kDilate: return SkImageFilters::Dilate(r.x, r.y, input, cropRect); } SkUNREACHABLE; } template <> bool SkSVGAttributeParser::parse(SkSVGFeMorphology::Operator* op) { static constexpr std::tuple gMap[] = { { "dilate", SkSVGFeMorphology::Operator::kDilate }, { "erode" , SkSVGFeMorphology::Operator::kErode }, }; return this->parseEnumMap(gMap, op) && this->parseEOSToken(); } template <> bool SkSVGAttributeParser::parse(SkSVGFeMorphology::Radius* radius) { std::vector values; if (!this->parse(&values)) { return false; } radius->fX = values[0]; radius->fY = values.size() > 1 ? values[1] : values[0]; return true; }