void FEDropShadow::determineAbsolutePaintRect() { Filter* filter = this->filter(); ASSERT(filter); FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); FloatRect absoluteOffsetPaintRect(absolutePaintRect); absoluteOffsetPaintRect.move(filter->applyHorizontalScale(m_dx), filter->applyVerticalScale(m_dy)); absolutePaintRect.unite(absoluteOffsetPaintRect); unsigned kernelSizeX = 0; unsigned kernelSizeY = 0; FEGaussianBlur::calculateKernelSize(filter, kernelSizeX, kernelSizeY, m_stdX, m_stdY); // We take the half kernel size and multiply it with three, because we run box blur three times. absolutePaintRect.inflateX(3 * kernelSizeX * 0.5f); absolutePaintRect.inflateY(3 * kernelSizeY * 0.5f); if (clipsToBounds()) absolutePaintRect.intersect(maxEffectRect()); else absolutePaintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
FloatRect FilterEffect::applyBounds(const FloatRect& rect) const { // Filters in SVG clip to primitive subregion, while CSS doesn't. if (!clipsToBounds()) return rect; FloatRect bounds = absoluteBounds(); if (affectsTransparentPixels()) return bounds; return intersection(rect, bounds); }
FloatRect FEComposite::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) { FloatRect requestedRect = originalRequestedRect; if (clipsToBounds()) requestedRect.intersect(maxEffectRect()); // We may be called multiple times if result is used more than once. Return // quickly if nothing new is required. if (absolutePaintRect().contains(enclosingIntRect(requestedRect))) return requestedRect; // No mapPaintRect required for FEComposite. FloatRect input1Rect = inputEffect(1)->determineAbsolutePaintRect(requestedRect); FloatRect affectedRect; switch (m_type) { case FECOMPOSITE_OPERATOR_IN: // 'in' has output only in the intersection of both inputs. affectedRect = intersection(input1Rect, inputEffect(0)->determineAbsolutePaintRect(input1Rect)); break; case FECOMPOSITE_OPERATOR_ATOP: // 'atop' has output only in the extents of the second input. // Make sure first input knows where it needs to produce output. inputEffect(0)->determineAbsolutePaintRect(input1Rect); affectedRect = input1Rect; break; case FECOMPOSITE_OPERATOR_ARITHMETIC: if (k4() > 0) { // Make sure first input knows where it needs to produce output. inputEffect(0)->determineAbsolutePaintRect(requestedRect); // Arithmetic with non-zero k4 may influnce the complete filter primitive // region. So we can't optimize the paint region here. affectedRect = requestedRect; break; } if (k2() <= 0) { // Input 0 does not appear where input 1 is not present. FloatRect input0Rect = inputEffect(0)->determineAbsolutePaintRect(input1Rect); if (k3() > 0) { affectedRect = input1Rect; } else { // Just k1 is positive. Use intersection. affectedRect = intersection(input1Rect, input0Rect); } break; } // else fall through to use union default: // Take the union of both input effects. affectedRect = unionRect(input1Rect, inputEffect(0)->determineAbsolutePaintRect(requestedRect)); break; } affectedRect.intersect(requestedRect); addAbsolutePaintRect(affectedRect); return affectedRect; }
FloatRect FEGaussianBlur::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) { FloatRect requestedRect = originalRequestedRect; if (clipsToBounds()) requestedRect.intersect(maxEffectRect()); FilterEffect* input = inputEffect(0); FloatRect inputRect = input->determineAbsolutePaintRect(mapRect(requestedRect, false)); FloatRect outputRect = mapRect(inputRect, true); outputRect.intersect(requestedRect); addAbsolutePaintRect(outputRect); // Blur needs space for both input and output pixels in the paint area. // Input is also clipped to subregion. if (clipsToBounds()) inputRect.intersect(maxEffectRect()); addAbsolutePaintRect(inputRect); return outputRect; }
void FEOffset::determineAbsolutePaintRect() { FloatRect paintRect = inputEffect(0)->absolutePaintRect(); Filter& filter = this->filter(); paintRect.move(filter.applyHorizontalScale(m_dx), filter.applyVerticalScale(m_dy)); if (clipsToBounds()) paintRect.intersect(maxEffectRect()); else paintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(paintRect)); }
FloatRect FilterEffect::mapInputs(const FloatRect& rect) const { if (!m_inputEffects.size()) { if (clipsToBounds()) return absoluteBounds(); return rect; } FloatRect inputUnion; for (const auto& effect : m_inputEffects) inputUnion.unite(effect->mapRect(rect)); return inputUnion; }
void FEMorphology::determineAbsolutePaintRect() { FloatRect paintRect = inputEffect(0)->absolutePaintRect(); Filter& filter = this->filter(); paintRect.inflateX(filter.applyHorizontalScale(m_radiusX)); paintRect.inflateY(filter.applyVerticalScale(m_radiusY)); if (clipsToBounds()) paintRect.intersect(maxEffectRect()); else paintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(paintRect)); }
void FEDropShadow::determineAbsolutePaintRect() { Filter* filter = this->filter(); ASSERT(filter); FloatRect absolutePaintRect = mapRect(inputEffect(0)->absolutePaintRect()); if (clipsToBounds()) absolutePaintRect.intersect(maxEffectRect()); else absolutePaintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
void FEImage::determineAbsolutePaintRect() { FloatRect paintRect = filter().absoluteTransform().mapRect(filterPrimitiveSubregion()); FloatRect srcRect; if (m_image) { srcRect.setSize(m_image->size()); m_preserveAspectRatio.transformRect(paintRect, srcRect); } else if (RenderElement* renderer = referencedRenderer()) srcRect = filter().absoluteTransform().mapRect(renderer->repaintRectInLocalCoordinates()); if (clipsToBounds()) paintRect.intersect(maxEffectRect()); else paintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(paintRect)); }
void FEGaussianBlur::determineAbsolutePaintRect() { FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); if (clipsToBounds()) absolutePaintRect.intersect(maxEffectRect()); else absolutePaintRect.unite(maxEffectRect()); unsigned kernelSizeX = 0; unsigned kernelSizeY = 0; calculateKernelSize(filter(), kernelSizeX, kernelSizeY, m_stdX, m_stdY); // We take the half kernel size and multiply it with three, because we run box blur three times. absolutePaintRect.inflateX(3 * kernelSizeX * 0.5f); absolutePaintRect.inflateY(3 * kernelSizeY * 0.5f); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
FloatRect FEDisplacementMap::determineAbsolutePaintRect(const FloatRect& requestedRect) { FloatRect rect = requestedRect; if (clipsToBounds()) rect.intersect(maxEffectRect()); if (absolutePaintRect().contains(enclosingIntRect(rect))) return rect; rect = mapPaintRect(rect, false); rect = inputEffect(0)->determineAbsolutePaintRect(rect); rect = mapPaintRect(rect, true); rect.intersect(requestedRect); addAbsolutePaintRect(rect); return rect; }
void FEGaussianBlur::determineAbsolutePaintRect() { IntSize kernelSize = calculateKernelSize(filter(), FloatPoint(m_stdX, m_stdY)); FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); // Edge modes other than 'none' do not inflate the affected paint rect. if (m_edgeMode != EDGEMODE_NONE) { setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); return; } // We take the half kernel size and multiply it with three, because we run box blur three times. absolutePaintRect.inflateX(3 * kernelSize.width() * 0.5f); absolutePaintRect.inflateY(3 * kernelSize.height() * 0.5f); if (clipsToBounds()) absolutePaintRect.intersect(maxEffectRect()); else absolutePaintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
void FEDropShadow::determineAbsolutePaintRect() { Filter& filter = this->filter(); FloatRect absolutePaintRect = inputEffect(0)->absolutePaintRect(); FloatRect absoluteOffsetPaintRect(absolutePaintRect); absoluteOffsetPaintRect.move(filter.applyHorizontalScale(m_dx), filter.applyVerticalScale(m_dy)); absolutePaintRect.unite(absoluteOffsetPaintRect); IntSize kernelSize = FEGaussianBlur::calculateKernelSize(filter, FloatPoint(m_stdX, m_stdY)); // We take the half kernel size and multiply it with three, because we run box blur three times. absolutePaintRect.inflateX(3 * kernelSize.width() * 0.5f); absolutePaintRect.inflateY(3 * kernelSize.height() * 0.5f); if (clipsToBounds()) absolutePaintRect.intersect(maxEffectRect()); else absolutePaintRect.unite(maxEffectRect()); setAbsolutePaintRect(enclosingIntRect(absolutePaintRect)); }
FloatRect FEImage::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) { RenderObject* renderer = referencedRenderer(); if (!m_image && !renderer) return FloatRect(); FloatRect requestedRect = originalRequestedRect; if (clipsToBounds()) requestedRect.intersect(maxEffectRect()); FloatRect destRect = filter()->mapLocalRectToAbsoluteRect(filterPrimitiveSubregion()); FloatRect srcRect; if (renderer) { srcRect = getRendererRepaintRect(renderer); SVGElement* contextNode = toSVGElement(renderer->node()); if (contextNode->hasRelativeLengths()) { // FIXME: This fixes relative lengths but breaks non-relative ones (see crbug/260709). SVGLengthContext lengthContext(contextNode); FloatSize viewportSize; if (lengthContext.determineViewport(viewportSize)) { srcRect = makeMapBetweenRects(FloatRect(FloatPoint(), viewportSize), destRect).mapRect(srcRect); } } else { srcRect = filter()->mapLocalRectToAbsoluteRect(srcRect); srcRect.move(destRect.x(), destRect.y()); } destRect.intersect(srcRect); } else { srcRect = FloatRect(FloatPoint(), m_image->size()); m_preserveAspectRatio->transformRect(destRect, srcRect); } destRect.intersect(requestedRect); addAbsolutePaintRect(destRect); return destRect; }