summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/svg/RenderSVGImage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/rendering/svg/RenderSVGImage.cpp')
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGImage.cpp89
1 files changed, 53 insertions, 36 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGImage.cpp b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
index 58dc14597..cd2386d7a 100644
--- a/Source/WebCore/rendering/svg/RenderSVGImage.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
- * Copyright (C) 2006 Apple Computer, Inc.
+ * Copyright (C) 2006 Apple Inc.
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2007, 2008, 2009 Rob Buis <buis@kde.org>
* Copyright (C) 2009 Google, Inc.
@@ -24,20 +24,17 @@
*/
#include "config.h"
-
-#if ENABLE(SVG)
#include "RenderSVGImage.h"
-#include "Attr.h"
#include "FloatQuad.h"
#include "GraphicsContext.h"
#include "LayoutRepainter.h"
#include "PointerEventsHitRules.h"
#include "RenderImageResource.h"
#include "RenderLayer.h"
+#include "RenderSVGResource.h"
#include "RenderSVGResourceFilter.h"
#include "SVGImageElement.h"
-#include "SVGLength.h"
#include "SVGRenderingContext.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
@@ -45,8 +42,8 @@
namespace WebCore {
-RenderSVGImage::RenderSVGImage(SVGImageElement& element, PassRef<RenderStyle> style)
- : RenderSVGModelObject(element, std::move(style))
+RenderSVGImage::RenderSVGImage(SVGImageElement& element, RenderStyle&& style)
+ : RenderSVGModelObject(element, WTFMove(style))
, m_needsBoundariesUpdate(true)
, m_needsTransformUpdate(true)
, m_imageResource(std::make_unique<RenderImageResource>())
@@ -56,27 +53,48 @@ RenderSVGImage::RenderSVGImage(SVGImageElement& element, PassRef<RenderStyle> st
RenderSVGImage::~RenderSVGImage()
{
+}
+
+void RenderSVGImage::willBeDestroyed()
+{
imageResource().shutdown();
+ RenderSVGModelObject::willBeDestroyed();
}
SVGImageElement& RenderSVGImage::imageElement() const
{
- return toSVGImageElement(RenderSVGModelObject::element());
+ return downcast<SVGImageElement>(RenderSVGModelObject::element());
}
bool RenderSVGImage::updateImageViewport()
{
FloatRect oldBoundaries = m_objectBoundingBox;
+ bool updatedViewport = false;
SVGLengthContext lengthContext(&imageElement());
m_objectBoundingBox = FloatRect(imageElement().x().value(lengthContext), imageElement().y().value(lengthContext), imageElement().width().value(lengthContext), imageElement().height().value(lengthContext));
- if (oldBoundaries == m_objectBoundingBox)
- return false;
+ // Images with preserveAspectRatio=none should force non-uniform scaling. This can be achieved
+ // by setting the image's container size to its intrinsic size.
+ // See: http://www.w3.org/TR/SVG/single-page.html, 7.8 The ‘preserveAspectRatio’ attribute.
+ if (imageElement().preserveAspectRatio().align() == SVGPreserveAspectRatioValue::SVG_PRESERVEASPECTRATIO_NONE) {
+ if (CachedImage* cachedImage = imageResource().cachedImage()) {
+ LayoutSize intrinsicSize = cachedImage->imageSizeForRenderer(0, style().effectiveZoom());
+ if (intrinsicSize != imageResource().imageSize(style().effectiveZoom())) {
+ imageResource().setContainerSizeForRenderer(roundedIntSize(intrinsicSize));
+ updatedViewport = true;
+ }
+ }
+ }
- imageResource().setContainerSizeForRenderer(enclosingIntRect(m_objectBoundingBox).size());
- m_needsBoundariesUpdate = true;
- return true;
+ if (oldBoundaries != m_objectBoundingBox) {
+ if (!updatedViewport)
+ imageResource().setContainerSizeForRenderer(enclosingIntRect(m_objectBoundingBox).size());
+ updatedViewport = true;
+ m_needsBoundariesUpdate = true;
+ }
+
+ return updatedViewport;
}
void RenderSVGImage::layout()
@@ -117,7 +135,8 @@ void RenderSVGImage::layout()
void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
- if (paintInfo.context->paintingDisabled() || style().visibility() == HIDDEN || !imageResource().hasImage())
+ if (paintInfo.context().paintingDisabled() || paintInfo.phase != PaintPhaseForeground
+ || style().visibility() == HIDDEN || !imageResource().hasImage())
return;
FloatRect boundingBox = repaintRectInLocalCoordinates();
@@ -125,36 +144,36 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
return;
PaintInfo childPaintInfo(paintInfo);
- bool drawsOutline = style().outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
- if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
- GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
- childPaintInfo.applyTransform(m_localTransform);
+ GraphicsContextStateSaver stateSaver(childPaintInfo.context());
+ childPaintInfo.applyTransform(m_localTransform);
- if (childPaintInfo.phase == PaintPhaseForeground) {
- SVGRenderingContext renderingContext(*this, childPaintInfo);
+ if (childPaintInfo.phase == PaintPhaseForeground) {
+ SVGRenderingContext renderingContext(*this, childPaintInfo);
- if (renderingContext.isRenderingPrepared()) {
- if (style().svgStyle().bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
- return;
+ if (renderingContext.isRenderingPrepared()) {
+ if (style().svgStyle().bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
+ return;
- paintForeground(childPaintInfo);
- }
+ paintForeground(childPaintInfo);
}
-
- if (drawsOutline)
- paintOutline(childPaintInfo, IntRect(boundingBox));
}
+
+ if (style().outlineWidth())
+ paintOutline(childPaintInfo, IntRect(boundingBox));
}
void RenderSVGImage::paintForeground(PaintInfo& paintInfo)
{
RefPtr<Image> image = imageResource().image();
+ if (!image)
+ return;
+
FloatRect destRect = m_objectBoundingBox;
FloatRect srcRect(0, 0, image->width(), image->height());
imageElement().preserveAspectRatio().transformRect(destRect, srcRect);
- paintInfo.context->drawImage(image.get(), ColorSpaceDeviceRGB, destRect, srcRect);
+ paintInfo.context().drawImage(*image, destRect, srcRect);
}
void RenderSVGImage::invalidateBufferedForeground()
@@ -171,14 +190,14 @@ bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest& request, HitTestResu
PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_IMAGE_HITTESTING, request, style().pointerEvents());
bool isVisible = (style().visibility() == VISIBLE);
if (isVisible || !hitRules.requireVisible) {
- FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent);
+ FloatPoint localPoint = localToParentTransform().inverse().value_or(AffineTransform()).mapPoint(pointInParent);
if (!SVGRenderSupport::pointInClippingArea(*this, localPoint))
return false;
if (hitRules.canHitFill) {
if (m_objectBoundingBox.contains(localPoint)) {
- updateHitTestResult(result, roundedLayoutPoint(localPoint));
+ updateHitTestResult(result, LayoutPoint(localPoint));
return true;
}
}
@@ -191,7 +210,7 @@ void RenderSVGImage::imageChanged(WrappedImagePtr, const IntRect*)
{
// The image resource defaults to nullImage until the resource arrives.
// This empty image may be cached by SVG resources which must be invalidated.
- if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*this))
+ if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this))
resources->removeClientFromCache(*this);
// Eventually notify parent resources, that we've changed.
@@ -207,14 +226,12 @@ void RenderSVGImage::imageChanged(WrappedImagePtr, const IntRect*)
repaint();
}
-void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
+void RenderSVGImage::addFocusRingRects(Vector<LayoutRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
{
// this is called from paint() after the localTransform has already been applied
- IntRect contentRect = enclosingIntRect(repaintRectInLocalCoordinates());
+ LayoutRect contentRect = LayoutRect(repaintRectInLocalCoordinates());
if (!contentRect.isEmpty())
rects.append(contentRect);
}
} // namespace WebCore
-
-#endif // ENABLE(SVG)