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); }
sk_sp<SkImageFilter> FETurbulence::createImageFilter() { if (m_baseFrequencyX < 0 || m_baseFrequencyY < 0) return createTransparentBlack(); SkPaint paint; paint.setShader(createShader()); SkImageFilter::CropRect rect = getCropRect(); return SkPaintImageFilter::Make(paint, &rect); }
PassRefPtr<SkImageFilter> FELighting::createImageFilter(SkiaImageFilterBuilder& builder) { if (!m_lightSource) return createTransparentBlack(builder); SkImageFilter::CropRect rect = getCropRect(builder.cropOffset()); Color lightColor = adaptColorToOperatingColorSpace(m_lightingColor); RefPtr<SkImageFilter> input(builder.build(inputEffect(0), operatingColorSpace())); switch (m_lightSource->type()) { case LS_DISTANT: { DistantLightSource* distantLightSource = static_cast<DistantLightSource*>(m_lightSource.get()); float azimuthRad = deg2rad(distantLightSource->azimuth()); float elevationRad = deg2rad(distantLightSource->elevation()); const SkPoint3 direction = SkPoint3::Make(cosf(azimuthRad) * cosf(elevationRad), sinf(azimuthRad) * cosf(elevationRad), sinf(elevationRad)); if (m_specularConstant > 0) return adoptRef(SkLightingImageFilter::CreateDistantLitSpecular(direction, lightColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); return adoptRef(SkLightingImageFilter::CreateDistantLitDiffuse(direction, lightColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); } case LS_POINT: { PointLightSource* pointLightSource = static_cast<PointLightSource*>(m_lightSource.get()); const FloatPoint3D position = pointLightSource->position(); const SkPoint3 skPosition = SkPoint3::Make(position.x(), position.y(), position.z()); if (m_specularConstant > 0) return adoptRef(SkLightingImageFilter::CreatePointLitSpecular(skPosition, lightColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); return adoptRef(SkLightingImageFilter::CreatePointLitDiffuse(skPosition, lightColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); } case LS_SPOT: { SpotLightSource* spotLightSource = static_cast<SpotLightSource*>(m_lightSource.get()); const SkPoint3 location = SkPoint3::Make(spotLightSource->position().x(), spotLightSource->position().y(), spotLightSource->position().z()); const SkPoint3 target = SkPoint3::Make(spotLightSource->direction().x(), spotLightSource->direction().y(), spotLightSource->direction().z()); float specularExponent = spotLightSource->specularExponent(); float limitingConeAngle = spotLightSource->limitingConeAngle(); if (!limitingConeAngle || limitingConeAngle > 90 || limitingConeAngle < -90) limitingConeAngle = 90; if (m_specularConstant > 0) return adoptRef(SkLightingImageFilter::CreateSpotLitSpecular(location, target, specularExponent, limitingConeAngle, lightColor.rgb(), m_surfaceScale, m_specularConstant, m_specularExponent, input.get(), &rect)); return adoptRef(SkLightingImageFilter::CreateSpotLitDiffuse(location, target, specularExponent, limitingConeAngle, lightColor.rgb(), m_surfaceScale, m_diffuseConstant, input.get(), &rect)); } default: ASSERT_NOT_REACHED(); return nullptr; } }
sk_sp<SkImageFilter> FEImage::createImageFilter() { if (auto* layoutObject = referencedLayoutObject()) return createImageFilterForLayoutObject(*layoutObject); sk_sp<SkImage> image = m_image ? toSkSp(m_image->imageForCurrentFrame()) : nullptr; if (!image) { // "A href reference that is an empty image (zero width or zero height), that fails // to download, is non-existent, or that cannot be displayed (e.g. because it is // not in a supported image format) fills the filter primitive subregion with // transparent black." return createTransparentBlack(); } FloatRect srcRect = FloatRect(FloatPoint(), FloatSize(m_image->size())); FloatRect dstRect = filterPrimitiveSubregion(); m_preserveAspectRatio->transformRect(dstRect, srcRect); return SkImageSource::Make(std::move(image), srcRect, dstRect, kHigh_SkFilterQuality); }