FloatRect SourceAlpha::determineAbsolutePaintRect(const FloatRect& requestedRect) { FloatRect srcRect = filter()->sourceImageRect(); srcRect.intersect(requestedRect); addAbsolutePaintRect(srcRect); return srcRect; }
FloatRect FilterEffect::determineAbsolutePaintRect(const FloatRect& originalRequestedRect) { FloatRect requestedRect = originalRequestedRect; // Filters in SVG clip to primitive subregion, while CSS doesn't. if (m_clipsToBounds) requestedRect.intersect(maxEffectRect()); // We may be called multiple times if result is used more than once. Return // quickly if if nothing new is required. if (absolutePaintRect().contains(enclosingIntRect(requestedRect))) return requestedRect; FloatRect inputRect = mapPaintRect(requestedRect, false); FloatRect inputUnion; unsigned size = m_inputEffects.size(); for (unsigned i = 0; i < size; ++i) inputUnion.unite(m_inputEffects.at(i)->determineAbsolutePaintRect(inputRect)); inputUnion = mapPaintRect(inputUnion, true); if (affectsTransparentPixels() || !size) { inputUnion = requestedRect; } else { // Rect may have inflated. Re-intersect with request. inputUnion.intersect(requestedRect); } addAbsolutePaintRect(inputUnion); return inputUnion; }
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; }
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; }
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; }
FloatRect SourceGraphic::determineAbsolutePaintRect(const FloatRect& requestedRect) { FloatRect srcRect = intersection(m_sourceRect, requestedRect); addAbsolutePaintRect(srcRect); return srcRect; }