SkImageFilter::CropRect FilterEffect::getCropRect(const FloatSize& cropOffset) const { FloatRect rect = filter()->filterRegion(); uint32_t flags = 0; FloatRect boundaries = effectBoundaries(); boundaries.move(cropOffset); if (hasX()) { rect.setX(boundaries.x()); flags |= SkImageFilter::CropRect::kHasLeft_CropEdge; flags |= SkImageFilter::CropRect::kHasRight_CropEdge; } if (hasY()) { rect.setY(boundaries.y()); flags |= SkImageFilter::CropRect::kHasTop_CropEdge; flags |= SkImageFilter::CropRect::kHasBottom_CropEdge; } if (hasWidth()) { rect.setWidth(boundaries.width()); flags |= SkImageFilter::CropRect::kHasRight_CropEdge; } if (hasHeight()) { rect.setHeight(boundaries.height()); flags |= SkImageFilter::CropRect::kHasBottom_CropEdge; } rect.scale(filter()->absoluteTransform().a(), filter()->absoluteTransform().d()); return SkImageFilter::CropRect(rect, flags); }
SkImageFilter::CropRect FilterEffect::getCropRect(const FloatSize& cropOffset) const { FloatRect rect; uint32_t flags = 0; if (!hasConnectedInput() && !filter()->filterRegion().isEmpty()) { rect = filter()->filterRegion(); flags = SkImageFilter::CropRect::kHasAll_CropEdge; } FloatRect boundaries = effectBoundaries(); boundaries.move(cropOffset); if (hasX()) { rect.setX(boundaries.x()); flags |= SkImageFilter::CropRect::kHasLeft_CropEdge; } if (hasY()) { rect.setY(boundaries.y()); flags |= SkImageFilter::CropRect::kHasTop_CropEdge; } if (hasWidth()) { rect.setWidth(boundaries.width()); flags |= SkImageFilter::CropRect::kHasWidth_CropEdge; } if (hasHeight()) { rect.setHeight(boundaries.height()); flags |= SkImageFilter::CropRect::kHasHeight_CropEdge; } rect.scale(filter()->scale()); return SkImageFilter::CropRect(rect, flags); }
FloatRect FilterEffect::getSourceRect(const FloatRect& destRect, const FloatRect& destClipRect) { FloatRect sourceRect = mapRect(destRect, false); FloatRect sourceClipRect = mapRect(destClipRect, false); FloatRect boundaries = filter()->mapLocalRectToAbsoluteRect(effectBoundaries()); if (hasX()) sourceClipRect.setX(boundaries.x()); if (hasY()) sourceClipRect.setY(boundaries.y()); if (hasWidth()) sourceClipRect.setWidth(boundaries.width()); if (hasHeight()) sourceClipRect.setHeight(boundaries.height()); FloatRect result; if (m_inputEffects.size() > 0) { result = m_inputEffects.at(0)->getSourceRect(sourceRect, sourceClipRect); for (unsigned i = 1; i < m_inputEffects.size(); ++i) result.unite(m_inputEffects.at(i)->getSourceRect(sourceRect, sourceClipRect)); } else { result = sourceRect; result.intersect(sourceClipRect); } return result; }
sk_sp<SkShader> FETurbulence::createShader() const { const SkISize size = SkISize::Make(effectBoundaries().width(), effectBoundaries().height()); // Frequency should be scaled by page zoom, but not by primitiveUnits. // So we apply only the transform scale (as Filter::apply*Scale() do) // and not the target bounding box scale (as SVGFilter::apply*Scale() // would do). Note also that we divide by the scale since this is // a frequency, not a period. float baseFrequencyX = m_baseFrequencyX / getFilter()->scale(); float baseFrequencyY = m_baseFrequencyY / getFilter()->scale(); return (type() == FETURBULENCE_TYPE_FRACTALNOISE) ? SkPerlinNoiseShader::MakeFractalNoise(SkFloatToScalar(baseFrequencyX), SkFloatToScalar(baseFrequencyY), numOctaves(), SkFloatToScalar(seed()), stitchTiles() ? &size : 0) : SkPerlinNoiseShader::MakeTurbulence(SkFloatToScalar(baseFrequencyX), SkFloatToScalar(baseFrequencyY), numOctaves(), SkFloatToScalar(seed()), stitchTiles() ? &size : 0); }
void FELighting::getTransform(FloatPoint3D* scale, FloatSize* offset) const { FloatRect initialEffectRect = effectBoundaries(); FloatRect absoluteEffectRect = filter()->mapLocalRectToAbsoluteRect(initialEffectRect); FloatPoint absoluteLocation(absolutePaintRect().location()); FloatSize positionOffset(absoluteLocation - absoluteEffectRect.location()); offset->setWidth(positionOffset.width()); offset->setHeight(positionOffset.height()); scale->setX(initialEffectRect.width() > 0.0f && initialEffectRect.width() > 0.0f ? absoluteEffectRect.width() / initialEffectRect.width() : 1.0f); scale->setY(initialEffectRect.height() > 0.0f && initialEffectRect.height() > 0.0f ? absoluteEffectRect.height() / initialEffectRect.height() : 1.0f); // X and Y scale should be the same, but, if not, do a best effort by averaging the 2 for Z scale scale->setZ(0.5f * (scale->x() + scale->y())); }
FloatRect FilterEffect::determineFilterPrimitiveSubregion(DetermineSubregionFlags flags) { Filter* filter = this->filter(); ASSERT(filter); // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect. FloatRect subregion; if (unsigned numberOfInputEffects = inputEffects().size()) { subregion = inputEffect(0)->determineFilterPrimitiveSubregion(flags); for (unsigned i = 1; i < numberOfInputEffects; ++i) subregion.unite(inputEffect(i)->determineFilterPrimitiveSubregion(flags)); } else { subregion = filter->filterRegion(); } // After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>. if (filterEffectType() == FilterEffectTypeTile) subregion = filter->filterRegion(); if (flags & MapRectForward) { // mapRect works on absolute rectangles. subregion = filter->mapAbsoluteRectToLocalRect(mapRect( filter->mapLocalRectToAbsoluteRect(subregion))); } FloatRect boundaries = effectBoundaries(); if (hasX()) subregion.setX(boundaries.x()); if (hasY()) subregion.setY(boundaries.y()); if (hasWidth()) subregion.setWidth(boundaries.width()); if (hasHeight()) subregion.setHeight(boundaries.height()); setFilterPrimitiveSubregion(subregion); FloatRect absoluteSubregion = filter->mapLocalRectToAbsoluteRect(subregion); // Clip every filter effect to the filter region. if (flags & ClipToFilterRegion) { absoluteSubregion.intersect(filter->absoluteFilterRegion()); } setMaxEffectRect(absoluteSubregion); return subregion; }
FloatRect FilterEffect::determineFilterPrimitiveSubregion() { ASSERT(filter()); // FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect. FloatRect subregion; if (unsigned numberOfInputEffects = inputEffects().size()) { subregion = inputEffect(0)->determineFilterPrimitiveSubregion(); for (unsigned i = 1; i < numberOfInputEffects; ++i) subregion.unite(inputEffect(i)->determineFilterPrimitiveSubregion()); } else subregion = filter()->filterRegion(); // After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>. if (filterEffectType() == FilterEffectTypeTile) subregion = filter()->filterRegion(); subregion = mapRect(subregion); FloatRect boundaries = effectBoundaries(); if (hasX()) subregion.setX(boundaries.x()); if (hasY()) subregion.setY(boundaries.y()); if (hasWidth()) subregion.setWidth(boundaries.width()); if (hasHeight()) subregion.setHeight(boundaries.height()); setFilterPrimitiveSubregion(subregion); FloatRect absoluteSubregion = filter()->absoluteTransform().mapRect(subregion); FloatSize filterResolution = filter()->filterResolution(); absoluteSubregion.scale(filterResolution.width(), filterResolution.height()); setMaxEffectRect(absoluteSubregion); return subregion; }