sk_sp<SkImageFilter> FEConvolveMatrix::createImageFilter() { if (!parametersValid()) return createTransparentBlack(); sk_sp<SkImageFilter> input( SkiaImageFilterBuilder::build(inputEffect(0), operatingColorSpace())); SkISize kernelSize( SkISize::Make(m_kernelSize.width(), m_kernelSize.height())); // parametersValid() above checks that the kernel area fits in int. int numElements = safeCast<int>(m_kernelSize.area()); SkScalar gain = SkFloatToScalar(1.0f / m_divisor); SkScalar bias = SkFloatToScalar(m_bias * 255); SkIPoint target = SkIPoint::Make(m_targetOffset.x(), m_targetOffset.y()); SkMatrixConvolutionImageFilter::TileMode tileMode = toSkiaTileMode(m_edgeMode); bool convolveAlpha = !m_preserveAlpha; std::unique_ptr<SkScalar[]> kernel = wrapArrayUnique(new SkScalar[numElements]); for (int i = 0; i < numElements; ++i) kernel[i] = SkFloatToScalar(m_kernelMatrix[numElements - 1 - i]); SkImageFilter::CropRect cropRect = getCropRect(); return SkMatrixConvolutionImageFilter::Make( kernelSize, kernel.get(), gain, bias, target, tileMode, convolveAlpha, std::move(input), &cropRect); }
FloatRect FEConvolveMatrix::mapEffect(const FloatRect& rect) const { if (!parametersValid()) return rect; FloatRect result = rect; result.moveBy(-m_targetOffset); result.expand(FloatSize(m_kernelSize)); return result; }
FloatRect FEConvolveMatrix::mapPaintRect(const FloatRect& rect, bool forward) { FloatRect result = rect; if (parametersValid()) { result.moveBy(forward ? -m_targetOffset : m_targetOffset - m_kernelSize); result.expand(m_kernelSize); } return result; }