summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/svg
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@digia.com>2013-09-13 12:51:20 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-09-19 20:50:05 +0200
commitd441d6f39bb846989d95bcf5caf387b42414718d (patch)
treee367e64a75991c554930278175d403c072de6bb8 /Source/WebCore/rendering/svg
parent0060b2994c07842f4c59de64b5e3e430525c4b90 (diff)
downloadqtwebkit-d441d6f39bb846989d95bcf5caf387b42414718d.tar.gz
Import Qt5x2 branch of QtWebkit for Qt 5.2
Importing a new snapshot of webkit. Change-Id: I2d01ad12cdc8af8cb015387641120a9d7ea5f10c Reviewed-by: Allan Sandfeld Jensen <allan.jensen@digia.com>
Diffstat (limited to 'Source/WebCore/rendering/svg')
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp1
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGBlock.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGBlock.h2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGContainer.cpp13
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGContainer.h7
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGEllipse.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGEllipse.h4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp5
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGForeignObject.h2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGGradientStop.h3
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp1
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGImage.cpp38
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGImage.h16
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInline.cpp8
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInline.h4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.cpp5
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.h4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGModelObject.cpp14
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGModelObject.h2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGPath.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGPath.h10
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRect.cpp1
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResource.cpp2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp19
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp18
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceContainer.h1
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp41
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilter.h14
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp6
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp9
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp19
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMarker.h2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp8
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp10
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.cpp56
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.h14
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGShape.cpp24
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGShape.h15
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTSpan.cpp4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTSpan.h2
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGText.cpp9
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGText.h6
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTextPath.cpp6
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTextPath.h4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp10
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp19
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.h6
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp8
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineFlowBox.h8
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.cpp30
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.h14
-rw-r--r--Source/WebCore/rendering/svg/SVGMarkerData.h18
-rw-r--r--Source/WebCore/rendering/svg/SVGPathData.cpp3
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderSupport.cpp25
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderSupport.h2
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp12
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderingContext.cpp78
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderingContext.h6
-rw-r--r--Source/WebCore/rendering/svg/SVGResources.cpp12
-rw-r--r--Source/WebCore/rendering/svg/SVGResourcesCache.cpp49
-rw-r--r--Source/WebCore/rendering/svg/SVGResourcesCache.h4
-rw-r--r--Source/WebCore/rendering/svg/SVGRootInlineBox.cpp30
-rw-r--r--Source/WebCore/rendering/svg/SVGRootInlineBox.h2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp24
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp3
-rw-r--r--Source/WebCore/rendering/svg/SVGTextQuery.cpp12
-rw-r--r--Source/WebCore/rendering/svg/SVGTextQuery.h7
-rw-r--r--Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp12
72 files changed, 508 insertions, 340 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp b/Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp
index a6bcd0296..234e7ce6c 100644
--- a/Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp
@@ -77,3 +77,4 @@
#include "SVGTextMetrics.cpp"
#include "SVGTextMetricsBuilder.cpp"
#include "SVGTextQuery.cpp"
+
diff --git a/Source/WebCore/rendering/svg/RenderSVGBlock.cpp b/Source/WebCore/rendering/svg/RenderSVGBlock.cpp
index 9f39357c1..f120b9946 100644
--- a/Source/WebCore/rendering/svg/RenderSVGBlock.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGBlock.cpp
@@ -31,8 +31,8 @@
namespace WebCore {
-RenderSVGBlock::RenderSVGBlock(SVGElement* node)
- : RenderBlock(node)
+RenderSVGBlock::RenderSVGBlock(SVGElement* element)
+ : RenderBlock(element)
{
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGBlock.h b/Source/WebCore/rendering/svg/RenderSVGBlock.h
index 222d5ee20..0bd300c1c 100644
--- a/Source/WebCore/rendering/svg/RenderSVGBlock.h
+++ b/Source/WebCore/rendering/svg/RenderSVGBlock.h
@@ -41,6 +41,8 @@ private:
virtual void setStyle(PassRefPtr<RenderStyle>);
virtual void updateFromStyle() OVERRIDE;
+ virtual bool isRenderSVGBlock() const OVERRIDE { return true; };
+
virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
index 5069f41aa..9305dc6b3 100644
--- a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
@@ -35,6 +35,7 @@
#include "SVGResources.h"
#include "SVGResourcesCache.h"
#include "SVGStyledElement.h"
+#include <wtf/StackStats.h>
namespace WebCore {
@@ -137,7 +138,7 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
}
if (continueRendering) {
- childPaintInfo.updatePaintingRootForChildren(this);
+ childPaintInfo.updateSubtreePaintRootForChildren(this);
for (RenderObject* child = firstChild(); child; child = child->nextSibling())
child->paint(childPaintInfo, IntPoint());
}
@@ -150,12 +151,12 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
// We should instead disable our clip during PaintPhaseOutline
if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style()->outlineWidth() && style()->visibility() == VISIBLE) {
IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRect));
- paintOutline(paintInfo.context, paintRectInParent);
+ paintOutline(paintInfo, paintRectInParent);
}
}
// addFocusRingRects is called from paintOutline and needs to be in the same coordinates as the paintOuline call
-void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&)
+void RenderSVGContainer::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
{
IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRectInLocalCoordinates()));
if (!paintRectInParent.isEmpty())
@@ -186,6 +187,12 @@ bool RenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTest
}
}
+ // Accessibility wants to return SVG containers, if appropriate.
+ if (request.type() & HitTestRequest::AccessibilityHitTest && m_objectBoundingBox.contains(localPoint)) {
+ updateHitTestResult(result, roundedLayoutPoint(localPoint));
+ return true;
+ }
+
// Spec: Only graphical elements can be targeted by the mouse, period.
// 16.4: "If there are no graphics elements whose relevant graphics content is under the pointer (i.e., there is no target element), the event is not dispatched."
return false;
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.h b/Source/WebCore/rendering/svg/RenderSVGContainer.h
index 3c0fa9814..70e1ec8d5 100644
--- a/Source/WebCore/rendering/svg/RenderSVGContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.h
@@ -44,6 +44,7 @@ public:
virtual void paint(PaintInfo&, const LayoutPoint&);
virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
+ virtual bool needsBoundariesUpdate() OVERRIDE { return m_needsBoundariesUpdate; }
virtual bool didTransformToRootUpdate() { return false; }
bool isObjectBoundingBoxValid() const { return m_objectBoundingBoxValid; }
@@ -58,7 +59,7 @@ protected:
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) OVERRIDE;
virtual void removeChild(RenderObject*) OVERRIDE;
- virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+ virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
virtual FloatRect objectBoundingBox() const { return m_objectBoundingBox; }
virtual FloatRect strokeBoundingBox() const { return m_strokeBoundingBox; }
@@ -90,13 +91,13 @@ private:
inline RenderSVGContainer* toRenderSVGContainer(RenderObject* object)
{
- ASSERT(!object || object->isSVGContainer());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGContainer());
return static_cast<RenderSVGContainer*>(object);
}
inline const RenderSVGContainer* toRenderSVGContainer(const RenderObject* object)
{
- ASSERT(!object || object->isSVGContainer());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGContainer());
return static_cast<const RenderSVGContainer*>(object);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp b/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp
index b4a76531e..8c1df2da4 100644
--- a/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp
@@ -31,12 +31,12 @@
#include "SVGCircleElement.h"
#include "SVGEllipseElement.h"
+#include "SVGGraphicsElement.h"
#include "SVGNames.h"
-#include "SVGStyledTransformableElement.h"
namespace WebCore {
-RenderSVGEllipse::RenderSVGEllipse(SVGStyledTransformableElement* node)
+RenderSVGEllipse::RenderSVGEllipse(SVGGraphicsElement* node)
: RenderSVGShape(node)
, m_usePathFallback(false)
{
diff --git a/Source/WebCore/rendering/svg/RenderSVGEllipse.h b/Source/WebCore/rendering/svg/RenderSVGEllipse.h
index f5129df90..a5af34bc4 100644
--- a/Source/WebCore/rendering/svg/RenderSVGEllipse.h
+++ b/Source/WebCore/rendering/svg/RenderSVGEllipse.h
@@ -29,13 +29,13 @@
#if ENABLE(SVG)
#include "RenderSVGShape.h"
-#include "SVGStyledTransformableElement.h"
+#include "SVGGraphicsElement.h"
namespace WebCore {
class RenderSVGEllipse : public RenderSVGShape {
public:
- explicit RenderSVGEllipse(SVGStyledTransformableElement*);
+ explicit RenderSVGEllipse(SVGGraphicsElement*);
virtual ~RenderSVGEllipse();
private:
diff --git a/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp b/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp
index 408d887f0..9bd4672ed 100644
--- a/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp
@@ -35,6 +35,7 @@
#include "SVGResourcesCache.h"
#include "SVGSVGElement.h"
#include "TransformState.h"
+#include <wtf/StackStats.h>
namespace WebCore {
@@ -193,9 +194,9 @@ bool RenderSVGForeignObject::nodeAtPoint(const HitTestRequest&, HitTestResult&,
return false;
}
-void RenderSVGForeignObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
+void RenderSVGForeignObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
{
- SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, mode & SnapOffsetForTransforms, wasFixed);
+ SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
}
const RenderObject* RenderSVGForeignObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
diff --git a/Source/WebCore/rendering/svg/RenderSVGForeignObject.h b/Source/WebCore/rendering/svg/RenderSVGForeignObject.h
index 00979de61..02c29cc05 100644
--- a/Source/WebCore/rendering/svg/RenderSVGForeignObject.h
+++ b/Source/WebCore/rendering/svg/RenderSVGForeignObject.h
@@ -54,7 +54,7 @@ public:
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) OVERRIDE;
virtual bool isSVGForeignObject() const { return true; }
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
diff --git a/Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp b/Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp
index 31d5da5ca..9b41ae319 100644
--- a/Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp
@@ -27,6 +27,7 @@
#include "SVGNames.h"
#include "SVGResourcesCache.h"
#include "SVGStopElement.h"
+#include <wtf/StackStats.h>
namespace WebCore {
@@ -72,7 +73,7 @@ SVGGradientElement* RenderSVGGradientStop::gradientElement() const
{
ContainerNode* parentNode = node()->parentNode();
if (parentNode->hasTagName(linearGradientTag) || parentNode->hasTagName(radialGradientTag))
- return static_cast<SVGGradientElement*>(parentNode);
+ return toSVGGradientElement(parentNode);
return 0;
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGGradientStop.h b/Source/WebCore/rendering/svg/RenderSVGGradientStop.h
index 1c0e4033b..ac8b97ac9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGGradientStop.h
+++ b/Source/WebCore/rendering/svg/RenderSVGGradientStop.h
@@ -47,6 +47,7 @@ public:
virtual FloatRect objectBoundingBox() const { return FloatRect(); }
virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction) OVERRIDE { return false; }
protected:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
@@ -57,7 +58,7 @@ private:
inline const RenderSVGGradientStop* toRenderSVGGradientStop(const RenderObject* object)
{
- ASSERT(!object || object->isSVGGradientStop());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGGradientStop());
return static_cast<const RenderSVGGradientStop*>(object);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp
index 4d37e13d7..2a015a5c0 100644
--- a/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp
@@ -24,6 +24,7 @@
#include "RenderSVGPath.h"
#include "SVGStyledElement.h"
+#include <wtf/StackStats.h>
namespace WebCore {
diff --git a/Source/WebCore/rendering/svg/RenderSVGImage.cpp b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
index 45db954df..76d7c5c2e 100644
--- a/Source/WebCore/rendering/svg/RenderSVGImage.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
@@ -44,6 +44,7 @@
#include "SVGRenderingContext.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
+#include <wtf/StackStats.h>
namespace WebCore {
@@ -63,7 +64,7 @@ RenderSVGImage::~RenderSVGImage()
bool RenderSVGImage::updateImageViewport()
{
- SVGImageElement* image = static_cast<SVGImageElement*>(node());
+ SVGImageElement* image = toSVGImageElement(node());
FloatRect oldBoundaries = m_objectBoundingBox;
SVGLengthContext lengthContext(image);
@@ -87,7 +88,7 @@ void RenderSVGImage::layout()
bool transformOrBoundariesUpdate = m_needsTransformUpdate || m_needsBoundariesUpdate;
if (m_needsTransformUpdate) {
- m_localTransform = static_cast<SVGImageElement*>(node())->animatedLocalTransform();
+ m_localTransform = toSVGImageElement(node())->animatedLocalTransform();
m_needsTransformUpdate = false;
}
@@ -132,22 +133,35 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
SVGRenderingContext renderingContext(this, childPaintInfo);
if (renderingContext.isRenderingPrepared()) {
- RefPtr<Image> image = m_imageResource->image();
- FloatRect destRect = m_objectBoundingBox;
- FloatRect srcRect(0, 0, image->width(), image->height());
+ if (style()->svgStyle()->bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
+ return;
- SVGImageElement* imageElement = static_cast<SVGImageElement*>(node());
- imageElement->preserveAspectRatio().transformRect(destRect, srcRect);
-
- childPaintInfo.context->drawImage(image.get(), ColorSpaceDeviceRGB, destRect, srcRect);
+ paintForeground(childPaintInfo);
}
}
if (drawsOutline)
- paintOutline(childPaintInfo.context, IntRect(boundingBox));
+ paintOutline(childPaintInfo, IntRect(boundingBox));
}
}
+void RenderSVGImage::paintForeground(PaintInfo& paintInfo)
+{
+ RefPtr<Image> image = m_imageResource->image();
+ FloatRect destRect = m_objectBoundingBox;
+ FloatRect srcRect(0, 0, image->width(), image->height());
+
+ SVGImageElement* imageElement = toSVGImageElement(node());
+ imageElement->preserveAspectRatio().transformRect(destRect, srcRect);
+
+ paintInfo.context->drawImage(image.get(), ColorSpaceDeviceRGB, destRect, srcRect);
+}
+
+void RenderSVGImage::invalidateBufferedForeground()
+{
+ m_bufferedForeground.clear();
+}
+
bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
// We only draw in the forground phase, so we only hit-test then.
@@ -188,10 +202,12 @@ void RenderSVGImage::imageChanged(WrappedImagePtr, const IntRect*)
m_objectBoundingBox = FloatRect();
updateImageViewport();
+ invalidateBufferedForeground();
+
repaint();
}
-void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&)
+void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
{
// this is called from paint() after the localTransform has already been applied
IntRect contentRect = enclosingIntRect(repaintRectInLocalCoordinates());
diff --git a/Source/WebCore/rendering/svg/RenderSVGImage.h b/Source/WebCore/rendering/svg/RenderSVGImage.h
index 905a8d37d..af85b895b 100644
--- a/Source/WebCore/rendering/svg/RenderSVGImage.h
+++ b/Source/WebCore/rendering/svg/RenderSVGImage.h
@@ -43,14 +43,18 @@ public:
bool updateImageViewport();
virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
+ virtual bool needsBoundariesUpdate() OVERRIDE { return m_needsBoundariesUpdate; }
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
RenderImageResource* imageResource() { return m_imageResource.get(); }
const RenderImageResource* imageResource() const { return m_imageResource.get(); }
+ // Note: Assumes the PaintInfo context has had all local transforms applied.
+ void paintForeground(PaintInfo&);
+
private:
virtual const char* renderName() const { return "RenderSVGImage"; }
- virtual bool isSVGImage() const { return true; }
+ virtual bool isSVGImage() const OVERRIDE { return true; }
virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
@@ -59,13 +63,15 @@ private:
virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
virtual FloatRect repaintRectInLocalCoordinatesExcludingSVGShadow() const OVERRIDE { return m_repaintBoundingBoxExcludingShadow; }
- virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+ virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
virtual void layout();
virtual void paint(PaintInfo&, const LayoutPoint&);
+ void invalidateBufferedForeground();
+
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
virtual AffineTransform localTransform() const { return m_localTransform; }
@@ -78,17 +84,19 @@ private:
FloatRect m_repaintBoundingBox;
FloatRect m_repaintBoundingBoxExcludingShadow;
OwnPtr<RenderImageResource> m_imageResource;
+
+ OwnPtr<ImageBuffer> m_bufferedForeground;
};
inline RenderSVGImage* toRenderSVGImage(RenderObject* object)
{
- ASSERT(!object || object->isSVGImage());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGImage());
return static_cast<RenderSVGImage*>(object);
}
inline const RenderSVGImage* toRenderSVGImage(const RenderObject* object)
{
- ASSERT(!object || object->isSVGImage());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGImage());
return static_cast<const RenderSVGImage*>(object);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGInline.cpp b/Source/WebCore/rendering/svg/RenderSVGInline.cpp
index 9252c54f3..e8dfe03e4 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInline.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInline.cpp
@@ -32,8 +32,8 @@
namespace WebCore {
-RenderSVGInline::RenderSVGInline(Node* n)
- : RenderInline(n)
+RenderSVGInline::RenderSVGInline(Element* element)
+ : RenderInline(element)
{
setAlwaysCreateLineBoxes();
}
@@ -79,9 +79,9 @@ void RenderSVGInline::computeFloatRectForRepaint(const RenderLayerModelObject* r
SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed);
}
-void RenderSVGInline::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
+void RenderSVGInline::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
{
- SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, mode & SnapOffsetForTransforms, wasFixed);
+ SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
}
const RenderObject* RenderSVGInline::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
diff --git a/Source/WebCore/rendering/svg/RenderSVGInline.h b/Source/WebCore/rendering/svg/RenderSVGInline.h
index 50dec2ddd..dbeb0d3ed 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInline.h
+++ b/Source/WebCore/rendering/svg/RenderSVGInline.h
@@ -30,7 +30,7 @@ namespace WebCore {
class RenderSVGInline : public RenderInline {
public:
- explicit RenderSVGInline(Node*);
+ explicit RenderSVGInline(Element*);
virtual const char* renderName() const { return "RenderSVGInline"; }
virtual bool requiresLayer() const { return false; }
@@ -47,7 +47,7 @@ public:
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
index 2371d1abf..4bf0ec595 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
@@ -185,7 +185,7 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point)
if (!box->isSVGInlineTextBox())
continue;
- SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(box);
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned textFragmentsSize = fragments.size();
@@ -228,8 +228,7 @@ void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, c
Document* document = renderer->document();
ASSERT(document);
- StyleResolver* styleResolver = document->styleResolver();
- ASSERT(styleResolver);
+ StyleResolver* styleResolver = document->ensureStyleResolver();
// Alter font-size to the right on-screen value to avoid scaling the glyphs themselves, except when GeometricPrecision is specified
scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer);
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.h b/Source/WebCore/rendering/svg/RenderSVGInlineText.h
index 7643cf1ab..b6fc83008 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.h
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.h
@@ -69,13 +69,13 @@ private:
inline RenderSVGInlineText* toRenderSVGInlineText(RenderObject* object)
{
- ASSERT(!object || object->isSVGInlineText());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGInlineText());
return static_cast<RenderSVGInlineText*>(object);
}
inline const RenderSVGInlineText* toRenderSVGInlineText(const RenderObject* object)
{
- ASSERT(!object || object->isSVGInlineText());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGInlineText());
return static_cast<const RenderSVGInlineText*>(object);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
index 019204e4e..6733a2e05 100644
--- a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
@@ -57,9 +57,9 @@ void RenderSVGModelObject::computeFloatRectForRepaint(const RenderLayerModelObje
SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed);
}
-void RenderSVGModelObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
+void RenderSVGModelObject::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
{
- SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, mode & SnapOffsetForTransforms, wasFixed);
+ SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
}
const RenderObject* RenderSVGModelObject::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
@@ -131,8 +131,8 @@ static void getElementCTM(SVGElement* element, AffineTransform& transform)
Node* current = element;
while (current && current->isSVGElement()) {
- SVGElement* currentElement = static_cast<SVGElement*>(current);
- if (currentElement->isStyled()) {
+ SVGElement* currentElement = toSVGElement(current);
+ if (currentElement->isSVGStyledElement()) {
localTransform = currentElement->renderer()->localToParentTransform();
transform = localTransform.multiply(transform);
}
@@ -140,7 +140,7 @@ static void getElementCTM(SVGElement* element, AffineTransform& transform)
if (currentElement == stopAtElement)
break;
- current = current->parentOrHostNode();
+ current = current->parentOrShadowHostNode();
}
}
@@ -180,7 +180,7 @@ bool RenderSVGModelObject::checkIntersection(RenderObject* renderer, const Float
if (!isGraphicsElement(renderer))
return false;
AffineTransform ctm;
- SVGElement* svgElement = static_cast<SVGElement*>(renderer->node());
+ SVGElement* svgElement = toSVGElement(renderer->node());
getElementCTM(svgElement, ctm);
ASSERT(svgElement->renderer());
return intersectsAllowingEmpty(rect, ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
@@ -193,7 +193,7 @@ bool RenderSVGModelObject::checkEnclosure(RenderObject* renderer, const FloatRec
if (!isGraphicsElement(renderer))
return false;
AffineTransform ctm;
- SVGElement* svgElement = static_cast<SVGElement*>(renderer->node());
+ SVGElement* svgElement = toSVGElement(renderer->node());
getElementCTM(svgElement, ctm);
ASSERT(svgElement->renderer());
return rect.contains(ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.h b/Source/WebCore/rendering/svg/RenderSVGModelObject.h
index dc2d5da39..0511f2772 100644
--- a/Source/WebCore/rendering/svg/RenderSVGModelObject.h
+++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.h
@@ -58,7 +58,7 @@ public:
virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
virtual void styleWillChange(StyleDifference, const RenderStyle* newStyle);
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
diff --git a/Source/WebCore/rendering/svg/RenderSVGPath.cpp b/Source/WebCore/rendering/svg/RenderSVGPath.cpp
index cf658359d..97f713012 100644
--- a/Source/WebCore/rendering/svg/RenderSVGPath.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGPath.cpp
@@ -30,13 +30,13 @@
#if ENABLE(SVG)
#include "RenderSVGPath.h"
+#include "SVGGraphicsElement.h"
#include "SVGPathElement.h"
-#include "SVGStyledTransformableElement.h"
#include "SVGSubpathData.h"
namespace WebCore {
-RenderSVGPath::RenderSVGPath(SVGStyledTransformableElement* node)
+RenderSVGPath::RenderSVGPath(SVGGraphicsElement* node)
: RenderSVGShape(node)
{
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGPath.h b/Source/WebCore/rendering/svg/RenderSVGPath.h
index ab1cf1c0b..674289564 100644
--- a/Source/WebCore/rendering/svg/RenderSVGPath.h
+++ b/Source/WebCore/rendering/svg/RenderSVGPath.h
@@ -33,11 +33,11 @@ namespace WebCore {
class RenderSVGPath : public RenderSVGShape {
public:
- explicit RenderSVGPath(SVGStyledTransformableElement*);
+ explicit RenderSVGPath(SVGGraphicsElement*);
virtual ~RenderSVGPath();
private:
- virtual bool isSVGPath() const { return true; }
+ virtual bool isSVGPath() const OVERRIDE { return true; }
virtual const char* renderName() const { return "RenderSVGPath"; }
virtual void updateShapeFromElement() OVERRIDE;
@@ -54,6 +54,12 @@ private:
Vector<FloatPoint> m_zeroLengthLinecapLocations;
};
+inline RenderSVGPath* toRenderSVGPath(RenderObject* object)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGPath());
+ return static_cast<RenderSVGPath*>(object);
+}
+
}
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGRect.cpp b/Source/WebCore/rendering/svg/RenderSVGRect.cpp
index c7f9c5b7b..1fa46a4a1 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRect.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRect.cpp
@@ -32,7 +32,6 @@
#include "SVGNames.h"
#include "SVGRectElement.h"
-#include <wtf/Platform.h>
namespace WebCore {
diff --git a/Source/WebCore/rendering/svg/RenderSVGResource.cpp b/Source/WebCore/rendering/svg/RenderSVGResource.cpp
index fd16ef29d..6ced1c79c 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResource.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResource.cpp
@@ -180,7 +180,7 @@ static inline void removeFromCacheAndInvalidateDependencies(RenderObject* object
if (!object->node() || !object->node()->isSVGElement())
return;
- HashSet<SVGElement*>* dependencies = object->document()->accessSVGExtensions()->setOfElementsReferencingTarget(static_cast<SVGElement*>(object->node()));
+ HashSet<SVGElement*>* dependencies = object->document()->accessSVGExtensions()->setOfElementsReferencingTarget(toSVGElement(object->node()));
if (!dependencies)
return;
HashSet<SVGElement*>::iterator end = dependencies->end();
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
index 7339e2859..9967d70ed 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
@@ -39,16 +39,15 @@
#include "RenderStyle.h"
#include "SVGClipPathElement.h"
#include "SVGElement.h"
+#include "SVGGraphicsElement.h"
#include "SVGNames.h"
#include "SVGRenderSupport.h"
#include "SVGRenderingContext.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
#include "SVGStyledElement.h"
-#include "SVGStyledTransformableElement.h"
#include "SVGUnitTypes.h"
#include "SVGUseElement.h"
-#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -117,9 +116,9 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const
// Only shapes or paths are supported for direct clipping. We need to fallback to masking for texts.
if (renderer->isSVGText())
return false;
- if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyledTransformable())
+ if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGGraphicsElement())
continue;
- SVGStyledTransformableElement* styled = static_cast<SVGStyledTransformableElement*>(childNode);
+ SVGGraphicsElement* styled = toSVGGraphicsElement(childNode);
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
continue;
@@ -169,7 +168,7 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderObject* object, cons
}
AffineTransform absoluteTransform;
- SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform);
if (shouldCreateClipData && !repaintRect.isEmpty()) {
if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, clipperData->clipMaskImage, ColorSpaceDeviceRGB, Unaccelerated))
@@ -234,7 +233,7 @@ bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData
// Draw all clipPath children into a global mask.
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
+ if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGStyledElement() || !renderer)
continue;
if (renderer->needsLayout()) {
frame()->view()->setPaintBehavior(oldBehavior);
@@ -247,7 +246,7 @@ bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData
WindRule newClipRule = style->svgStyle()->clipRule();
bool isUseElement = childNode->hasTagName(SVGNames::useTag);
if (isUseElement) {
- SVGUseElement* useElement = static_cast<SVGUseElement*>(childNode);
+ SVGUseElement* useElement = toSVGUseElement(childNode);
renderer = useElement->rendererClipChild();
if (!renderer)
continue;
@@ -276,7 +275,7 @@ void RenderSVGResourceClipper::calculateClipContentRepaintRect()
// This is a rough heuristic to appraise the clip size and doesn't consider clip on clip.
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
+ if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGStyledElement() || !renderer)
continue;
if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
continue;
@@ -306,13 +305,13 @@ bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundin
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
+ if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGStyledElement() || !renderer)
continue;
if (!renderer->isSVGShape() && !renderer->isSVGText() && !childNode->hasTagName(SVGNames::useTag))
continue;
IntPoint hitPoint;
HitTestResult result(hitPoint);
- if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent), result, point, HitTestForeground))
+ if (renderer->nodeAtFloatPoint(HitTestRequest(HitTestRequest::SVGClipContent | HitTestRequest::DisallowShadowContent), result, point, HitTestForeground))
return true;
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
index e311c1c21..38bd67a63 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
@@ -25,9 +25,10 @@
#include "RenderLayer.h"
#include "RenderSVGRoot.h"
#include "RenderView.h"
+#include "SVGGraphicsElement.h"
#include "SVGRenderingContext.h"
#include "SVGResourcesCache.h"
-#include "SVGStyledTransformableElement.h"
+#include <wtf/StackStats.h>
namespace WebCore {
@@ -86,7 +87,7 @@ void RenderSVGResourceContainer::idChanged()
// Remove old id, that is guaranteed to be present in cache.
SVGDocumentExtensions* extensions = svgExtensionsFromNode(node());
extensions->removeResource(m_id);
- m_id = static_cast<Element*>(node())->getIdAttribute();
+ m_id = toElement(node())->getIdAttribute();
registerResource();
}
@@ -114,13 +115,18 @@ void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode
RenderSVGResource::markForLayoutAndParentResourceInvalidation(client, needsLayout);
}
+ markAllClientLayersForInvalidation();
+
+ m_isInvalidating = false;
+}
+
+void RenderSVGResourceContainer::markAllClientLayersForInvalidation()
+{
#if ENABLE(CSS_FILTERS)
HashSet<RenderLayer*>::iterator layerEnd = m_clientLayers.end();
for (HashSet<RenderLayer*>::iterator it = m_clientLayers.begin(); it != layerEnd; ++it)
(*it)->filterNeedsRepaint();
#endif
-
- m_isInvalidating = false;
}
void RenderSVGResourceContainer::markClientForInvalidation(RenderObject* client, InvalidationMode mode)
@@ -184,7 +190,7 @@ void RenderSVGResourceContainer::registerResource()
const SVGDocumentExtensions::SVGPendingElements::const_iterator end = clients->end();
for (SVGDocumentExtensions::SVGPendingElements::const_iterator it = clients->begin(); it != end; ++it) {
ASSERT((*it)->hasPendingResources());
- (*it)->clearHasPendingResourcesIfPossible();
+ extensions->clearHasPendingResourcesIfPossible(*it);
RenderObject* renderer = (*it)->renderer();
if (!renderer)
continue;
@@ -220,7 +226,7 @@ AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderOb
if (!object->isSVGShape())
return resourceTransform;
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
+ SVGGraphicsElement* element = toSVGGraphicsElement(object->node());
AffineTransform transform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate);
transform *= resourceTransform;
return transform;
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
index 0f074863b..0f425cd45 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
@@ -57,6 +57,7 @@ protected:
// Used from the invalidateClient/invalidateClients methods from classes, inheriting from us.
void markAllClientsForInvalidation(InvalidationMode);
+ void markAllClientLayersForInvalidation();
void markClientForInvalidation(RenderObject*, InvalidationMode);
private:
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
index 7d4eedfc9..c5e6bbb26 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
@@ -49,8 +49,6 @@
#include "Settings.h"
#include "SourceAlpha.h"
#include "SourceGraphic.h"
-
-#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
using namespace std;
@@ -99,7 +97,7 @@ void RenderSVGResourceFilter::removeClientFromCache(RenderObject* client, bool m
PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter* filter)
{
- SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
+ SVGFilterElement* filterElement = toSVGFilterElement(node());
FloatRect targetBoundingBox = filter->targetBoundingBox();
// Add effects to the builder
@@ -108,7 +106,7 @@ PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter*
if (!node->isSVGElement())
continue;
- SVGElement* element = static_cast<SVGElement*>(node);
+ SVGElement* element = toSVGElement(node);
if (!element->isFilterEffect())
continue;
@@ -121,8 +119,8 @@ PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter*
builder->appendEffectToEffectReferences(effect, effectElement->renderer());
effectElement->setStandardAttributes(effect.get());
effect->setEffectBoundaries(SVGLengthContext::resolveRectangle<SVGFilterPrimitiveStandardAttributes>(effectElement, filterElement->primitiveUnits(), targetBoundingBox));
- effect->setColorSpace(effectElement->renderer()->style()->svgStyle()->colorInterpolationFilters() == CI_LINEARRGB
- ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB);
+ effect->setOperatingColorSpace(
+ effectElement->renderer()->style()->svgStyle()->colorInterpolationFilters() == CI_LINEARRGB ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB);
builder->add(effectElement->result(), effect);
}
return builder.release();
@@ -159,14 +157,14 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
OwnPtr<FilterData> filterData(adoptPtr(new FilterData));
FloatRect targetBoundingBox = object->objectBoundingBox();
- SVGFilterElement* filterElement = static_cast<SVGFilterElement*>(node());
+ SVGFilterElement* filterElement = toSVGFilterElement(node());
filterData->boundaries = SVGLengthContext::resolveRectangle<SVGFilterElement>(filterElement, filterElement->filterUnits(), targetBoundingBox);
if (filterData->boundaries.isEmpty())
return false;
// Determine absolute transformation matrix for filter.
AffineTransform absoluteTransform;
- SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform);
if (!absoluteTransform.isInvertible())
return false;
@@ -175,9 +173,9 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
// Determine absolute boundaries of the filter and the drawing region.
FloatRect absoluteFilterBoundaries = filterData->shearFreeAbsoluteTransform.mapRect(filterData->boundaries);
- FloatRect drawingRegion = object->strokeBoundingBox();
- drawingRegion.intersect(filterData->boundaries);
- FloatRect absoluteDrawingRegion = filterData->shearFreeAbsoluteTransform.mapRect(drawingRegion);
+ filterData->drawingRegion = object->strokeBoundingBox();
+ filterData->drawingRegion.intersect(filterData->boundaries);
+ FloatRect absoluteDrawingRegion = filterData->shearFreeAbsoluteTransform.mapRect(filterData->drawingRegion);
// Create the SVGFilter object.
bool primitiveBoundingBoxMode = filterElement->primitiveUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX;
@@ -222,7 +220,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
// If the drawingRegion is empty, we have something like <g filter=".."/>.
// Even if the target objectBoundingBox() is empty, we still have to draw the last effect result image in postApplyResource.
- if (drawingRegion.isEmpty()) {
+ if (filterData->drawingRegion.isEmpty()) {
ASSERT(!m_filter.contains(object));
filterData->savedContext = context;
m_filter.set(object, filterData.leakPtr());
@@ -236,7 +234,7 @@ bool RenderSVGResourceFilter::applyResource(RenderObject* object, RenderStyle*,
OwnPtr<ImageBuffer> sourceGraphic;
RenderingMode renderingMode = object->document()->page()->settings()->acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
- if (!SVGRenderingContext::createImageBuffer(drawingRegion, effectiveTransform, sourceGraphic, ColorSpaceLinearRGB, renderingMode)) {
+ if (!SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, sourceGraphic, ColorSpaceLinearRGB, renderingMode)) {
ASSERT(!m_filter.contains(object));
filterData->savedContext = context;
m_filter.set(object, filterData.leakPtr());
@@ -309,13 +307,9 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
// Always true if filterData is just built (filterData->state == FilterData::Built).
if (!lastEffect->hasResult()) {
filterData->state = FilterData::Applying;
- lastEffect->apply();
+ lastEffect->applyAll();
lastEffect->correctFilterResultIfNeeded();
-#if !USE(CG)
- ImageBuffer* resultImage = lastEffect->asImageBuffer();
- if (resultImage)
- resultImage->transformColorSpace(lastEffect->colorSpace(), ColorSpaceDeviceRGB);
-#endif
+ lastEffect->transformResultColorSpace(ColorSpaceDeviceRGB);
}
filterData->state = FilterData::Built;
@@ -335,7 +329,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderObject* object, GraphicsCo
FloatRect RenderSVGResourceFilter::resourceBoundingBox(RenderObject* object)
{
- if (SVGFilterElement* element = static_cast<SVGFilterElement*>(node()))
+ if (SVGFilterElement* element = toSVGFilterElement(node()))
return SVGLengthContext::resolveRectangle<SVGFilterElement>(element, element->filterUnits(), object->objectBoundingBox());
return FloatRect();
@@ -365,6 +359,13 @@ void RenderSVGResourceFilter::primitiveAttributeChanged(RenderObject* object, co
// Repaint the image on the screen.
markClientForInvalidation(it->key, RepaintInvalidation);
}
+ markAllClientLayersForInvalidation();
+}
+
+FloatRect RenderSVGResourceFilter::drawingRegion(RenderObject* object) const
+{
+ FilterData* filterData = m_filter.get(object);
+ return filterData ? filterData->drawingRegion : FloatRect();
}
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
index db422c17e..4ad9ad037 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
@@ -56,6 +56,7 @@ public:
GraphicsContext* savedContext;
AffineTransform shearFreeAbsoluteTransform;
FloatRect boundaries;
+ FloatRect drawingRegion;
FloatSize scale;
FilterDataState state;
};
@@ -68,7 +69,7 @@ public:
virtual ~RenderSVGResourceFilter();
virtual const char* renderName() const { return "RenderSVGResourceFilter"; }
- virtual bool isSVGResourceFilter() const { return true; }
+ virtual bool isSVGResourceFilter() const OVERRIDE { return true; }
virtual void removeAllClientsFromCache(bool markForInvalidation = true);
virtual void removeClientFromCache(RenderObject*, bool markForInvalidation = true);
@@ -80,20 +81,27 @@ public:
PassRefPtr<SVGFilterBuilder> buildPrimitives(SVGFilter*);
- SVGUnitTypes::SVGUnitType filterUnits() const { return static_cast<SVGFilterElement*>(node())->filterUnits(); }
- SVGUnitTypes::SVGUnitType primitiveUnits() const { return static_cast<SVGFilterElement*>(node())->primitiveUnits(); }
+ SVGUnitTypes::SVGUnitType filterUnits() const { return toSVGFilterElement(node())->filterUnits(); }
+ SVGUnitTypes::SVGUnitType primitiveUnits() const { return toSVGFilterElement(node())->primitiveUnits(); }
void primitiveAttributeChanged(RenderObject*, const QualifiedName&);
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
static RenderSVGResourceType s_resourceType;
+ FloatRect drawingRegion(RenderObject*) const;
private:
bool fitsInMaximumImageSize(const FloatSize&, FloatSize&);
HashMap<RenderObject*, FilterData*> m_filter;
};
+inline RenderSVGResourceFilter* toRenderSVGFilter(RenderObject* object)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGResourceFilter());
+ return static_cast<RenderSVGResourceFilter*>(object);
+}
+
}
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
index f3da929ef..b5177fad9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
@@ -53,12 +53,12 @@ void RenderSVGResourceFilterPrimitive::styleDidChange(StyleDifference diff, cons
const SVGRenderStyle* newStyle = this->style()->svgStyle();
if (node()->hasTagName(SVGNames::feFloodTag)) {
if (newStyle->floodColor() != oldStyle->svgStyle()->floodColor())
- static_cast<RenderSVGResourceFilter*>(filter)->primitiveAttributeChanged(this, SVGNames::flood_colorAttr);
+ toRenderSVGFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_colorAttr);
if (newStyle->floodOpacity() != oldStyle->svgStyle()->floodOpacity())
- static_cast<RenderSVGResourceFilter*>(filter)->primitiveAttributeChanged(this, SVGNames::flood_opacityAttr);
+ toRenderSVGFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_opacityAttr);
} else if (node()->hasTagName(SVGNames::feDiffuseLightingTag) || node()->hasTagName(SVGNames::feSpecularLightingTag)) {
if (newStyle->lightingColor() != oldStyle->svgStyle()->lightingColor())
- static_cast<RenderSVGResourceFilter*>(filter)->primitiveAttributeChanged(this, SVGNames::lighting_colorAttr);
+ toRenderSVGFilter(filter)->primitiveAttributeChanged(this, SVGNames::lighting_colorAttr);
}
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
index 30ce1b8cb..25a61239f 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
@@ -31,7 +31,6 @@
#include "RenderSVGText.h"
#include "SVGRenderSupport.h"
#include "SVGRenderingContext.h"
-#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -68,7 +67,7 @@ static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& con
ASSERT(textRootBlock);
AffineTransform absoluteTransform;
- SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform);
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(textRootBlock, absoluteTransform);
FloatRect repaintRect = textRootBlock->repaintRectInLocalCoordinates();
OwnPtr<ImageBuffer> maskImage;
@@ -95,7 +94,7 @@ static inline AffineTransform clipToTextMask(GraphicsContext* context,
ASSERT(textRootBlock);
AffineTransform absoluteTransform;
- SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(textRootBlock, absoluteTransform);
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(textRootBlock, absoluteTransform);
targetRect = textRootBlock->repaintRectInLocalCoordinates();
SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, targetRect, imageBuffer, false);
@@ -122,12 +121,12 @@ bool RenderSVGResourceGradient::applyResource(RenderObject* object, RenderStyle*
// Otherwhise the call to collectGradientAttributes() in createTileImage(), may cause the SVG DOM property
// synchronization to kick in, which causes removeAllClientsFromCache() to be called, which in turn deletes our
// GradientData object! Leaving out the line below will cause svg/dynamic-updates/SVG*GradientElement-svgdom* to crash.
- SVGGradientElement* gradientElement = static_cast<SVGGradientElement*>(node());
+ SVGGradientElement* gradientElement = toSVGGradientElement(node());
if (!gradientElement)
return false;
if (m_shouldCollectGradientAttributes) {
- gradientElement->updateAnimatedSVGAttribute(anyQName());
+ gradientElement->synchronizeAnimatedSVGAttribute(anyQName());
if (!collectGradientAttributes(gradientElement))
return false;
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
index 7aaef0e9e..bcf517aef 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
@@ -28,10 +28,11 @@
#include "RenderSVGContainer.h"
#include "RenderSVGRoot.h"
#include "SVGElement.h"
+#include "SVGGraphicsElement.h"
#include "SVGMarkerElement.h"
#include "SVGRenderSupport.h"
#include "SVGStyledElement.h"
-#include "SVGStyledTransformableElement.h"
+#include <wtf/StackStats.h>
namespace WebCore {
@@ -96,7 +97,7 @@ const AffineTransform& RenderSVGResourceMarker::localToParentTransform() const
FloatPoint RenderSVGResourceMarker::referencePoint() const
{
- SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ SVGMarkerElement* marker = toSVGMarkerElement(node());
ASSERT(marker);
SVGLengthContext lengthContext(marker);
@@ -105,7 +106,7 @@ FloatPoint RenderSVGResourceMarker::referencePoint() const
float RenderSVGResourceMarker::angle() const
{
- SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ SVGMarkerElement* marker = toSVGMarkerElement(node());
ASSERT(marker);
float angle = -1;
@@ -117,7 +118,7 @@ float RenderSVGResourceMarker::angle() const
AffineTransform RenderSVGResourceMarker::markerTransformation(const FloatPoint& origin, float autoAngle, float strokeWidth) const
{
- SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ SVGMarkerElement* marker = toSVGMarkerElement(node());
ASSERT(marker);
float markerAngle = angle();
@@ -132,6 +133,12 @@ AffineTransform RenderSVGResourceMarker::markerTransformation(const FloatPoint&
void RenderSVGResourceMarker::draw(PaintInfo& paintInfo, const AffineTransform& transform)
{
+ // An empty viewBox disables rendering.
+ SVGMarkerElement* marker = toSVGMarkerElement(toSVGElement(node()));
+ ASSERT(marker);
+ if (marker->hasAttribute(SVGNames::viewBoxAttr) && marker->viewBoxIsValid() && marker->viewBox().isEmpty())
+ return;
+
PaintInfo info(paintInfo);
GraphicsContextStateSaver stateSaver(*info.context);
info.applyTransform(transform);
@@ -153,7 +160,7 @@ AffineTransform RenderSVGResourceMarker::markerContentTransformation(const Affin
AffineTransform RenderSVGResourceMarker::viewportTransform() const
{
- SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ SVGMarkerElement* marker = toSVGMarkerElement(node());
ASSERT(marker);
return marker->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
@@ -164,7 +171,7 @@ void RenderSVGResourceMarker::calcViewport()
if (!selfNeedsLayout())
return;
- SVGMarkerElement* marker = static_cast<SVGMarkerElement*>(node());
+ SVGMarkerElement* marker = toSVGMarkerElement(node());
ASSERT(marker);
SVGLengthContext lengthContext(marker);
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.h b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.h
index 26fbc6f93..1838450cf 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.h
@@ -60,7 +60,7 @@ public:
FloatPoint referencePoint() const;
float angle() const;
- SVGMarkerUnitsType markerUnits() const { return static_cast<SVGMarkerElement*>(node())->markerUnits(); }
+ SVGMarkerUnitsType markerUnits() const { return toSVGMarkerElement(node())->markerUnits(); }
virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
static RenderSVGResourceType s_resourceType;
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
index 1f501a88b..fa66dfa7b 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
@@ -36,8 +36,6 @@
#include "SVGRenderingContext.h"
#include "SVGStyledElement.h"
#include "SVGUnitTypes.h"
-
-#include <wtf/UnusedParam.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -92,7 +90,7 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
MaskerData* maskerData = m_masker.get(object);
AffineTransform absoluteTransform;
- SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransform);
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransform);
FloatRect repaintRect = object->repaintRectInLocalCoordinates();
@@ -137,7 +135,7 @@ bool RenderSVGResourceMasker::drawContentIntoMaskImage(MaskerData* maskerData, C
// Draw the content into the ImageBuffer.
for (Node* node = maskElement->firstChild(); node; node = node->nextSibling()) {
RenderObject* renderer = node->renderer();
- if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !renderer)
+ if (!node->isSVGElement() || !toSVGElement(node)->isSVGStyledElement() || !renderer)
continue;
if (renderer->needsLayout())
return false;
@@ -166,7 +164,7 @@ void RenderSVGResourceMasker::calculateMaskContentRepaintRect()
{
for (Node* childNode = node()->firstChild(); childNode; childNode = childNode->nextSibling()) {
RenderObject* renderer = childNode->renderer();
- if (!childNode->isSVGElement() || !static_cast<SVGElement*>(childNode)->isStyled() || !renderer)
+ if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGStyledElement() || !renderer)
continue;
RenderStyle* style = renderer->style();
if (!style || style->display() == NONE || style->visibility() != VISIBLE)
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
index 55dbb8319..4df4c22a9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
@@ -66,7 +66,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
return 0;
if (m_shouldCollectPatternAttributes) {
- patternElement->updateAnimatedSVGAttribute(anyQName());
+ patternElement->synchronizeAnimatedSVGAttribute(anyQName());
m_attributes = PatternAttributes();
patternElement->collectPatternAttributes(m_attributes);
@@ -77,6 +77,10 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
if (!m_attributes.patternContentElement())
return 0;
+ // An empty viewBox disables rendering.
+ if (m_attributes.hasViewBox() && m_attributes.viewBox().isEmpty())
+ return 0;
+
// Compute all necessary transformations to build the tile image & the pattern.
FloatRect tileBoundaries;
AffineTransform tileImageTransform;
@@ -84,7 +88,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsign
return 0;
AffineTransform absoluteTransformIgnoringRotation;
- SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(object, absoluteTransformIgnoringRotation);
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransformIgnoringRotation);
// Ignore 2D rotation, as it doesn't affect the size of the tile.
SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
@@ -269,7 +273,7 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternA
// Draw the content into the ImageBuffer.
for (Node* node = attributes.patternContentElement()->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement() || !static_cast<SVGElement*>(node)->isStyled() || !node->renderer())
+ if (!node->isSVGElement() || !toSVGElement(node)->isSVGStyledElement() || !node->renderer())
continue;
if (node->renderer()->needsLayout())
return nullptr;
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
index a81c3698d..ca5cad4c5 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
@@ -29,10 +29,6 @@
#include "RenderStyle.h"
#include "SVGRenderSupport.h"
-#if USE(SKIA)
-#include "PlatformContextSkia.h"
-#endif
-
namespace WebCore {
RenderSVGResourceType RenderSVGResourceSolidColor::s_resourceType = SolidColorResourceType;
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
index 048c4f604..c3d159734 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
@@ -46,6 +46,7 @@
#include "SVGStyledElement.h"
#include "SVGViewSpec.h"
#include "TransformState.h"
+#include <wtf/StackStats.h>
#if ENABLE(FILTERS)
#include "RenderSVGResourceFilter.h"
@@ -77,7 +78,8 @@ void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, d
// the same as the CSS width and height properties. Specifically, percentage values do not provide an intrinsic width or height,
// and do not indicate a percentage of the containing block. Rather, once the viewport is established, they indicate the portion
// of the viewport that is actually covered by image data.
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ SVGSVGElement* svg = toSVGSVGElement(node());
+ ASSERT(svg);
Length intrinsicWidthAttribute = svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties);
Length intrinsicHeightAttribute = svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);
@@ -128,10 +130,10 @@ bool RenderSVGRoot::isEmbeddedThroughSVGImage() const
return false;
// Test whether we're embedded through an img.
- if (!frame->page() || !frame->page()->chrome())
+ if (!frame->page())
return false;
- ChromeClient* chromeClient = frame->page()->chrome()->client();
+ ChromeClient* chromeClient = frame->page()->chrome().client();
if (!chromeClient || !chromeClient->isSVGImageChromeClient())
return false;
@@ -159,9 +161,9 @@ static inline LayoutUnit resolveLengthAttributeForSVG(const Length& length, floa
return static_cast<LayoutUnit>(valueForLength(length, maxSize, renderView) * (length.isFixed() ? scale : 1));
}
-LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(bool includeMaxWidth) const
+LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
{
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ SVGSVGElement* svg = toSVGSVGElement(node());
ASSERT(svg);
// When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size.
@@ -169,7 +171,7 @@ LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(bool includeMaxWidth) cons
return m_containerSize.width();
if (style()->logicalWidth().isSpecified() || style()->logicalMaxWidth().isSpecified())
- return RenderReplaced::computeReplacedLogicalWidth(includeMaxWidth);
+ return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred);
if (svg->widthAttributeEstablishesViewport())
return resolveLengthAttributeForSVG(svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties), style()->effectiveZoom(), containingBlock()->availableLogicalWidth(), view());
@@ -179,12 +181,12 @@ LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(bool includeMaxWidth) cons
return document()->frame()->ownerRenderer()->availableLogicalWidth();
// SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
- return RenderReplaced::computeReplacedLogicalWidth(includeMaxWidth);
+ return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred);
}
LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const
{
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ SVGSVGElement* svg = toSVGSVGElement(node());
ASSERT(svg);
// When we're embedded through SVGImage (border-image/background-image/<html:img>/...) we're forced to resize to a specific size.
@@ -206,12 +208,12 @@ LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const
} else
RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot*>(this));
- return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), containingBlock()->availableLogicalHeight(), view());
+ return resolveLengthAttributeForSVG(height, style()->effectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding), view());
}
// SVG embedded through object/embed/iframe.
if (isEmbeddedThroughFrameContainingSVGDocument())
- return document()->frame()->ownerRenderer()->availableLogicalHeight();
+ return document()->frame()->ownerRenderer()->availableLogicalHeight(IncludeMarginBorderPadding);
// SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
return RenderReplaced::computeReplacedLogicalHeight();
@@ -235,7 +237,8 @@ void RenderSVGRoot::layout()
updateLogicalHeight();
buildLocalToBorderBoxTransform();
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ SVGSVGElement* svg = toSVGSVGElement(node());
+ ASSERT(svg);
m_isLayoutSizeChanged = needsLayout || (svg->hasRelativeLengths() && oldSize != size());
SVGRenderSupport::layoutChildren(this, needsLayout || SVGRenderSupport::filtersForceContainerLayout(this));
@@ -256,6 +259,8 @@ void RenderSVGRoot::layout()
m_needsBoundariesOrTransformUpdate = false;
}
+ updateLayerTransform();
+
repainter.repaintAfterLayout();
setNeedsLayout(false);
@@ -267,10 +272,17 @@ void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint
if (pixelSnappedBorderBoxRect().isEmpty())
return;
- // Don't paint, if the context explicitely disabled it.
+ // Don't paint, if the context explicitly disabled it.
if (paintInfo.context->paintingDisabled())
return;
+ // An empty viewBox also disables rendering.
+ // (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute)
+ SVGSVGElement* svg = toSVGSVGElement(node());
+ ASSERT(svg);
+ if (svg->hasEmptyViewBox())
+ return;
+
Page* page = 0;
if (Frame* frame = this->frame())
page = frame->page();
@@ -354,12 +366,13 @@ void RenderSVGRoot::removeChild(RenderObject* child)
// relative to our borderBox origin. This method gives us exactly that.
void RenderSVGRoot::buildLocalToBorderBoxTransform()
{
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ SVGSVGElement* svg = toSVGSVGElement(node());
+ ASSERT(svg);
float scale = style()->effectiveZoom();
- FloatPoint translate = svg->currentTranslate();
+ SVGPoint translate = svg->currentTranslate();
LayoutSize borderAndPadding(borderLeft() + paddingLeft(), borderTop() + paddingTop());
m_localToBorderBoxTransform = svg->viewBoxToViewTransform(contentWidth() / scale, contentHeight() / scale);
- if (borderAndPadding.isEmpty() && scale == 1 && translate == FloatPoint::zero())
+ if (borderAndPadding.isEmpty() && scale == 1 && translate == SVGPoint::zero())
return;
m_localToBorderBoxTransform = AffineTransform(scale, 0, 0, scale, borderAndPadding.width() + translate.x(), borderAndPadding.height() + translate.y()) * m_localToBorderBoxTransform;
}
@@ -463,15 +476,22 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
bool RenderSVGRoot::hasRelativeDimensions() const
{
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ SVGSVGElement* svg = toSVGSVGElement(node());
ASSERT(svg);
return svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent() || svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties).isPercent();
}
+bool RenderSVGRoot::hasRelativeIntrinsicLogicalWidth() const
+{
+ SVGSVGElement* svg = toSVGSVGElement(node());
+ ASSERT(svg);
+ return svg->intrinsicWidth(SVGSVGElement::IgnoreCSSProperties).isPercent();
+}
+
bool RenderSVGRoot::hasRelativeLogicalHeight() const
{
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ SVGSVGElement* svg = toSVGSVGElement(node());
ASSERT(svg);
return svg->intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent();
@@ -484,7 +504,7 @@ void RenderSVGRoot::addResourceForClientInvalidation(RenderSVGResourceContainer*
svgRoot = svgRoot->parent();
if (!svgRoot)
return;
- static_cast<RenderSVGRoot*>(svgRoot)->m_resourcesNeedingToInvalidateClients.add(resource);
+ toRenderSVGRoot(svgRoot)->m_resourcesNeedingToInvalidateClients.add(resource);
}
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.h b/Source/WebCore/rendering/svg/RenderSVGRoot.h
index 38e89179e..e218e291e 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.h
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.h
@@ -52,13 +52,15 @@ public:
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
virtual void setNeedsBoundariesUpdate() { m_needsBoundariesOrTransformUpdate = true; }
+ virtual bool needsBoundariesUpdate() OVERRIDE { return m_needsBoundariesOrTransformUpdate; }
virtual void setNeedsTransformUpdate() { m_needsBoundariesOrTransformUpdate = true; }
IntSize containerSize() const { return m_containerSize; }
void setContainerSize(const IntSize& containerSize) { m_containerSize = containerSize; }
- virtual bool hasRelativeDimensions() const;
- virtual bool hasRelativeLogicalHeight() const;
+ virtual bool hasRelativeDimensions() const OVERRIDE;
+ virtual bool hasRelativeIntrinsicLogicalWidth() const OVERRIDE;
+ virtual bool hasRelativeLogicalHeight() const OVERRIDE;
// localToBorderBoxTransform maps local SVG viewport coordinates to local CSS box coordinates.
const AffineTransform& localToBorderBoxTransform() const { return m_localToBorderBoxTransform; }
@@ -77,7 +79,7 @@ private:
virtual bool isSVGRoot() const { return true; }
virtual const char* renderName() const { return "RenderSVGRoot"; }
- virtual LayoutUnit computeReplacedLogicalWidth(bool includeMaxWidth = true) const;
+ virtual LayoutUnit computeReplacedLogicalWidth(ShouldComputePreferred = ComputeActual) const OVERRIDE;
virtual LayoutUnit computeReplacedLogicalHeight() const;
virtual void layout();
virtual void paintReplaced(PaintInfo&, const LayoutPoint&);
@@ -103,7 +105,7 @@ private:
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const OVERRIDE;
virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const OVERRIDE;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
virtual bool canBeSelectionLeaf() const { return false; }
@@ -129,13 +131,13 @@ private:
inline RenderSVGRoot* toRenderSVGRoot(RenderObject* object)
{
- ASSERT(!object || object->isSVGRoot());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGRoot());
return static_cast<RenderSVGRoot*>(object);
}
inline const RenderSVGRoot* toRenderSVGRoot(const RenderObject* object)
{
- ASSERT(!object || object->isSVGRoot());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGRoot());
return static_cast<const RenderSVGRoot*>(object);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.cpp b/Source/WebCore/rendering/svg/RenderSVGShape.cpp
index 7e329b2b7..8070a392a 100644
--- a/Source/WebCore/rendering/svg/RenderSVGShape.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGShape.cpp
@@ -39,23 +39,24 @@
#include "RenderSVGContainer.h"
#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceSolidColor.h"
+#include "SVGGraphicsElement.h"
#include "SVGPathData.h"
#include "SVGRenderingContext.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
-#include "SVGStyledTransformableElement.h"
#include "SVGTransformList.h"
#include "SVGURIReference.h"
#include "StrokeStyleApplier.h"
#include <wtf/MathExtras.h>
+#include <wtf/StackStats.h>
namespace WebCore {
-RenderSVGShape::RenderSVGShape(SVGStyledTransformableElement* node)
+RenderSVGShape::RenderSVGShape(SVGGraphicsElement* node)
: RenderSVGModelObject(node)
, m_needsBoundariesUpdate(false) // Default is false, the cached rects are empty from the beginning.
- , m_needsShapeUpdate(true) // Default is true, so we grab a Path object once from SVGStyledTransformableElement.
- , m_needsTransformUpdate(true) // Default is true, so we grab a AffineTransform object once from SVGStyledTransformableElement.
+ , m_needsShapeUpdate(true) // Default is true, so we grab a Path object once from SVGGraphicsElement.
+ , m_needsTransformUpdate(true) // Default is true, so we grab a AffineTransform object once from SVGGraphicsElement.
{
}
@@ -69,7 +70,7 @@ void RenderSVGShape::updateShapeFromElement()
m_path = adoptPtr(new Path);
ASSERT(RenderSVGShape::isEmpty());
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+ SVGGraphicsElement* element = toSVGGraphicsElement(node());
updatePathFromGraphicsElement(element, path());
processMarkerPositions();
@@ -146,7 +147,7 @@ void RenderSVGShape::layout()
{
StackStats::LayoutCheckPoint layoutCheckPoint;
LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(this) && selfNeedsLayout());
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+ SVGGraphicsElement* element = toSVGGraphicsElement(node());
bool updateCachedBoundariesInParents = false;
@@ -198,7 +199,7 @@ bool RenderSVGShape::setupNonScalingStrokeContext(AffineTransform& strokeTransfo
AffineTransform RenderSVGShape::nonScalingStrokeTransform() const
{
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+ SVGGraphicsElement* element = toSVGGraphicsElement(node());
return element->getScreenCTM(SVGLocatable::DisallowStyleUpdate);
}
@@ -207,7 +208,7 @@ bool RenderSVGShape::shouldGenerateMarkerPositions() const
if (!style()->svgStyle()->hasMarkers())
return false;
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+ SVGGraphicsElement* element = toSVGGraphicsElement(node());
if (!element->supportsMarkers())
return false;
@@ -258,7 +259,6 @@ void RenderSVGShape::fillAndStrokeShape(GraphicsContext* context)
return;
GraphicsContextStateSaver stateSaver(*context, false);
- AffineTransform nonScalingTransform;
if (hasNonScalingStroke()) {
AffineTransform nonScalingTransform = nonScalingStrokeTransform();
@@ -298,13 +298,13 @@ void RenderSVGShape::paint(PaintInfo& paintInfo, const LayoutPoint&)
}
if (drawsOutline)
- paintOutline(childPaintInfo.context, IntRect(boundingBox));
+ paintOutline(childPaintInfo, IntRect(boundingBox));
}
}
// This method is called from inside paintOutline() since we call paintOutline()
// while transformed to our coord system, return local coords
-void RenderSVGShape::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&)
+void RenderSVGShape::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint&, const RenderLayerModelObject*)
{
IntRect rect = enclosingIntRect(repaintRectInLocalCoordinates());
if (!rect.isEmpty())
@@ -416,7 +416,7 @@ void RenderSVGShape::updateRepaintBoundingBox()
float RenderSVGShape::strokeWidth() const
{
- SVGElement* svgElement = static_cast<SVGElement*>(node());
+ SVGElement* svgElement = toSVGElement(node());
SVGLengthContext lengthContext(svgElement);
return style()->svgStyle()->strokeWidth().value(lengthContext);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.h b/Source/WebCore/rendering/svg/RenderSVGShape.h
index 60a2daeb4..289369698 100644
--- a/Source/WebCore/rendering/svg/RenderSVGShape.h
+++ b/Source/WebCore/rendering/svg/RenderSVGShape.h
@@ -42,7 +42,7 @@ class GraphicsContextStateSaver;
class RenderSVGContainer;
class RenderSVGPath;
class RenderSVGResource;
-class SVGStyledTransformableElement;
+class SVGGraphicsElement;
class BoundingRectStrokeStyleApplier : public StrokeStyleApplier {
public:
@@ -66,16 +66,18 @@ private:
class RenderSVGShape : public RenderSVGModelObject {
public:
- explicit RenderSVGShape(SVGStyledTransformableElement*);
- RenderSVGShape(SVGStyledTransformableElement*, Path*, bool);
+ explicit RenderSVGShape(SVGGraphicsElement*);
+ RenderSVGShape(SVGGraphicsElement*, Path*, bool);
virtual ~RenderSVGShape();
void setNeedsShapeUpdate() { m_needsShapeUpdate = true; }
virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
+ virtual bool needsBoundariesUpdate() OVERRIDE { return m_needsBoundariesUpdate; }
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
virtual void fillShape(GraphicsContext*) const;
virtual void strokeShape(GraphicsContext*) const;
+ bool hasPath() const { return m_path.get(); }
Path& path() const
{
ASSERT(m_path);
@@ -88,7 +90,6 @@ protected:
virtual bool shapeDependentStrokeContains(const FloatPoint&);
virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
float strokeWidth() const;
- bool hasPath() const { return m_path.get(); }
bool hasSmoothStroke() const;
bool hasNonScalingStroke() const { return style()->svgStyle()->vectorEffect() == VE_NON_SCALING_STROKE; }
@@ -113,7 +114,7 @@ private:
virtual void layout();
virtual void paint(PaintInfo&, const LayoutPoint&);
- virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint&);
+ virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) OVERRIDE;
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
@@ -148,13 +149,13 @@ private:
inline RenderSVGShape* toRenderSVGShape(RenderObject* object)
{
- ASSERT(!object || object->isSVGShape());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGShape());
return static_cast<RenderSVGShape*>(object);
}
inline const RenderSVGShape* toRenderSVGShape(const RenderObject* object)
{
- ASSERT(!object || object->isSVGShape());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGShape());
return static_cast<const RenderSVGShape*>(object);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGTSpan.cpp b/Source/WebCore/rendering/svg/RenderSVGTSpan.cpp
index 872d07642..0831b2409 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTSpan.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGTSpan.cpp
@@ -27,8 +27,8 @@
namespace WebCore {
-RenderSVGTSpan::RenderSVGTSpan(Node* n)
- : RenderSVGInline(n)
+RenderSVGTSpan::RenderSVGTSpan(Element* element)
+ : RenderSVGInline(element)
{
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGTSpan.h b/Source/WebCore/rendering/svg/RenderSVGTSpan.h
index d5e2ed768..bd9ce9abe 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTSpan.h
+++ b/Source/WebCore/rendering/svg/RenderSVGTSpan.h
@@ -28,7 +28,7 @@
namespace WebCore {
class RenderSVGTSpan : public RenderSVGInline {
public:
- explicit RenderSVGTSpan(Node*);
+ explicit RenderSVGTSpan(Element*);
virtual const char* renderName() const { return "RenderSVGTSpan"; }
};
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp
index fd49f9b46..a65a3e498 100644
--- a/Source/WebCore/rendering/svg/RenderSVGText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp
@@ -52,6 +52,7 @@
#include "SimpleFontData.h"
#include "TransformState.h"
#include "VisiblePosition.h"
+#include <wtf/StackStats.h>
namespace WebCore {
@@ -111,9 +112,9 @@ void RenderSVGText::computeFloatRectForRepaint(const RenderLayerModelObject* rep
SVGRenderSupport::computeFloatRectForRepaint(this, repaintContainer, repaintRect, fixed);
}
-void RenderSVGText::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags mode, bool* wasFixed) const
+void RenderSVGText::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
{
- SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, mode & SnapOffsetForTransforms, wasFixed);
+ SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
}
const RenderObject* RenderSVGText::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
@@ -472,7 +473,7 @@ VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInConten
if (!rootBox)
return createVisiblePosition(0, DOWNSTREAM);
- ASSERT(rootBox->isSVGRootInlineBox());
+ ASSERT_WITH_SECURITY_IMPLICATION(rootBox->isSVGRootInlineBox());
ASSERT(!rootBox->nextRootBox());
ASSERT(childrenInline());
@@ -513,7 +514,7 @@ FloatRect RenderSVGText::strokeBoundingBox() const
ASSERT(node());
ASSERT(node()->isSVGElement());
- SVGLengthContext lengthContext(static_cast<SVGElement*>(node()));
+ SVGLengthContext lengthContext(toSVGElement(node()));
strokeBoundaries.inflate(svgStyle->strokeWidth().value(lengthContext));
return strokeBoundaries;
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.h b/Source/WebCore/rendering/svg/RenderSVGText.h
index cae5ba721..4d4f4ae3d 100644
--- a/Source/WebCore/rendering/svg/RenderSVGText.h
+++ b/Source/WebCore/rendering/svg/RenderSVGText.h
@@ -75,7 +75,7 @@ private:
virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const OVERRIDE;
virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const OVERRIDE;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip | SnapOffsetForTransforms, bool* wasFixed = 0) const OVERRIDE;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const OVERRIDE;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const OVERRIDE;
virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void removeChild(RenderObject*) OVERRIDE;
@@ -104,13 +104,13 @@ private:
inline RenderSVGText* toRenderSVGText(RenderObject* object)
{
- ASSERT(!object || object->isSVGText());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGText());
return static_cast<RenderSVGText*>(object);
}
inline const RenderSVGText* toRenderSVGText(const RenderObject* object)
{
- ASSERT(!object || object->isSVGText());
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGText());
return static_cast<const RenderSVGText*>(object);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp b/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
index 15b48f590..e816f9e47 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
@@ -34,8 +34,8 @@
namespace WebCore {
-RenderSVGTextPath::RenderSVGTextPath(Node* n)
- : RenderSVGInline(n)
+RenderSVGTextPath::RenderSVGTextPath(Element* element)
+ : RenderSVGInline(element)
{
}
@@ -46,7 +46,7 @@ Path RenderSVGTextPath::layoutPath() const
if (!targetElement || !targetElement->hasTagName(SVGNames::pathTag))
return Path();
- SVGPathElement* pathElement = static_cast<SVGPathElement*>(targetElement);
+ SVGPathElement* pathElement = toSVGPathElement(targetElement);
Path pathData;
updatePathFromGraphicsElement(pathElement, pathData);
diff --git a/Source/WebCore/rendering/svg/RenderSVGTextPath.h b/Source/WebCore/rendering/svg/RenderSVGTextPath.h
index 2758a0692..f1c872138 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTextPath.h
+++ b/Source/WebCore/rendering/svg/RenderSVGTextPath.h
@@ -28,7 +28,7 @@ namespace WebCore {
class RenderSVGTextPath : public RenderSVGInline {
public:
- RenderSVGTextPath(Node*);
+ RenderSVGTextPath(Element*);
Path layoutPath() const;
float startOffset() const;
@@ -45,7 +45,7 @@ private:
inline RenderSVGTextPath* toRenderSVGTextPath(RenderObject* object)
{
- ASSERT(!object || !strcmp(object->renderName(), "RenderSVGTextPath"));
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGTextPath());
return static_cast<RenderSVGTextPath*>(object);
}
diff --git a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
index ee4d74e24..06df24dc6 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
@@ -24,14 +24,14 @@
#if ENABLE(SVG)
#include "RenderSVGTransformableContainer.h"
+#include "SVGGraphicsElement.h"
#include "SVGNames.h"
#include "SVGRenderSupport.h"
-#include "SVGStyledTransformableElement.h"
#include "SVGUseElement.h"
namespace WebCore {
-RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransformableElement* node)
+RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGGraphicsElement* node)
: RenderSVGContainer(node)
, m_needsTransformUpdate(true)
, m_didTransformToRootUpdate(false)
@@ -40,18 +40,18 @@ RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGStyledTransf
bool RenderSVGTransformableContainer::calculateLocalTransform()
{
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(node());
+ SVGGraphicsElement* element = toSVGGraphicsElement(node());
// If we're either the renderer for a <use> element, or for any <g> element inside the shadow
// tree, that was created during the use/symbol/svg expansion in SVGUseElement. These containers
// need to respect the translations induced by their corresponding use elements x/y attributes.
SVGUseElement* useElement = 0;
if (element->hasTagName(SVGNames::useTag))
- useElement = static_cast<SVGUseElement*>(element);
+ useElement = toSVGUseElement(element);
else if (element->isInShadowTree() && element->hasTagName(SVGNames::gTag)) {
SVGElement* correspondingElement = element->correspondingElement();
if (correspondingElement && correspondingElement->hasTagName(SVGNames::useTag))
- useElement = static_cast<SVGUseElement*>(correspondingElement);
+ useElement = toSVGUseElement(correspondingElement);
}
if (useElement) {
diff --git a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
index c10a08dc2..b59327efd 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
@@ -26,10 +26,10 @@
namespace WebCore {
-class SVGStyledTransformableElement;
+class SVGGraphicsElement;
class RenderSVGTransformableContainer : public RenderSVGContainer {
public:
- explicit RenderSVGTransformableContainer(SVGStyledTransformableElement*);
+ explicit RenderSVGTransformableContainer(SVGGraphicsElement*);
virtual bool isSVGTransformableContainer() const { return true; }
virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
index 27a319f28..834452d20 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
@@ -47,7 +47,7 @@ void RenderSVGViewportContainer::determineIfLayoutSizeChanged()
if (!node()->hasTagName(SVGNames::svgTag))
return;
- m_isLayoutSizeChanged = static_cast<SVGSVGElement*>(node())->hasRelativeLengths() && selfNeedsLayout();
+ m_isLayoutSizeChanged = toSVGSVGElement(node())->hasRelativeLengths() && selfNeedsLayout();
}
void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
@@ -58,10 +58,10 @@ void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
void RenderSVGViewportContainer::calcViewport()
{
- SVGElement* element = static_cast<SVGElement*>(node());
+ SVGElement* element = toSVGElement(node());
if (!element->hasTagName(SVGNames::svgTag))
return;
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(element);
+ SVGSVGElement* svg = toSVGSVGElement(element);
FloatRect oldViewport = m_viewport;
SVGLengthContext lengthContext(element);
@@ -133,7 +133,7 @@ bool RenderSVGViewportContainer::calculateLocalTransform()
AffineTransform RenderSVGViewportContainer::viewportTransform() const
{
if (node()->hasTagName(SVGNames::svgTag)) {
- SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
+ SVGSVGElement* svg = toSVGSVGElement(node());
return svg->viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
}
@@ -149,6 +149,17 @@ bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& poi
return m_viewport.contains(pointInParent);
}
+void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
+{
+ // An empty viewBox disables rendering.
+ if (node()->hasTagName(SVGNames::svgTag)) {
+ if (toSVGSVGElement(node())->hasEmptyViewBox())
+ return;
+ }
+
+ RenderSVGContainer::paint(paintInfo, paintOffset);
+}
+
}
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
index eb7041a30..427e423da 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
@@ -41,6 +41,8 @@ public:
virtual void determineIfLayoutSizeChanged();
virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ virtual void paint(PaintInfo&, const LayoutPoint&) OVERRIDE;
+
private:
virtual bool isSVGViewportContainer() const { return true; }
virtual const char* renderName() const { return "RenderSVGViewportContainer"; }
@@ -63,13 +65,13 @@ private:
inline RenderSVGViewportContainer* toRenderSVGViewportContainer(RenderObject* object)
{
- ASSERT(!object || !strcmp(object->renderName(), "RenderSVGViewportContainer"));
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGViewportContainer());
return static_cast<RenderSVGViewportContainer*>(object);
}
inline const RenderSVGViewportContainer* toRenderSVGViewportContainer(const RenderObject* object)
{
- ASSERT(!object || !strcmp(object->renderName(), "RenderSVGViewportContainer"));
+ ASSERT_WITH_SECURITY_IMPLICATION(!object || object->isSVGViewportContainer());
return static_cast<const RenderSVGViewportContainer*>(object);
}
diff --git a/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp b/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp
index 21a909224..3e97b6722 100644
--- a/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp
@@ -43,9 +43,9 @@ void SVGInlineFlowBox::paintSelectionBackground(PaintInfo& paintInfo)
PaintInfo childPaintInfo(paintInfo);
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
if (child->isSVGInlineTextBox())
- static_cast<SVGInlineTextBox*>(child)->paintSelectionBackground(childPaintInfo);
+ toSVGInlineTextBox(child)->paintSelectionBackground(childPaintInfo);
else if (child->isSVGInlineFlowBox())
- static_cast<SVGInlineFlowBox*>(child)->paintSelectionBackground(childPaintInfo);
+ toSVGInlineFlowBox(child)->paintSelectionBackground(childPaintInfo);
}
}
@@ -61,7 +61,7 @@ void SVGInlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
if (renderingContext.isRenderingPrepared()) {
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
if (child->isSVGInlineTextBox())
- computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(static_cast<SVGInlineTextBox*>(child)->textRenderer()));
+ computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(toSVGInlineTextBox(child)->textRenderer()));
child->paint(paintInfo, LayoutPoint(), 0, 0);
}
@@ -107,7 +107,7 @@ void SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(RenderSVGInlineText
if (!box->isSVGInlineTextBox())
continue;
- SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(box);
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
int markerStartPosition = max<int>(marker->startOffset() - textBox->start(), 0);
int markerEndPosition = min<int>(marker->endOffset() - textBox->start(), textBox->len());
diff --git a/Source/WebCore/rendering/svg/SVGInlineFlowBox.h b/Source/WebCore/rendering/svg/SVGInlineFlowBox.h
index bc44c7e55..18b8a527f 100644
--- a/Source/WebCore/rendering/svg/SVGInlineFlowBox.h
+++ b/Source/WebCore/rendering/svg/SVGInlineFlowBox.h
@@ -28,7 +28,7 @@ namespace WebCore {
class RenderSVGInlineText;
-class SVGInlineFlowBox : public InlineFlowBox {
+class SVGInlineFlowBox FINAL : public InlineFlowBox {
public:
SVGInlineFlowBox(RenderObject* obj)
: InlineFlowBox(obj)
@@ -51,6 +51,12 @@ private:
float m_logicalHeight;
};
+inline SVGInlineFlowBox* toSVGInlineFlowBox(InlineBox* box)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!box || box->isSVGInlineFlowBox());
+ return static_cast<SVGInlineFlowBox*>(box);
+}
+
} // namespace WebCore
#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 7864d4ee8..08a9e14c7 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -318,10 +318,10 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
// Spec: All text decorations except line-through should be drawn before the text is filled and stroked; thus, the text is rendered on top of these decorations.
int decorations = style->textDecorationsInEffect();
- if (decorations & UNDERLINE)
- paintDecoration(paintInfo.context, UNDERLINE, fragment);
- if (decorations & OVERLINE)
- paintDecoration(paintInfo.context, OVERLINE, fragment);
+ if (decorations & TextDecorationUnderline)
+ paintDecoration(paintInfo.context, TextDecorationUnderline, fragment);
+ if (decorations & TextDecorationOverline)
+ paintDecoration(paintInfo.context, TextDecorationOverline, fragment);
// Fill text
if (hasFill) {
@@ -336,8 +336,8 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
}
// Spec: Line-through should be drawn after the text is filled and stroked; thus, the line-through is rendered on top of the text.
- if (decorations & LINE_THROUGH)
- paintDecoration(paintInfo.context, LINE_THROUGH, fragment);
+ if (decorations & TextDecorationLineThrough)
+ paintDecoration(paintInfo.context, TextDecorationLineThrough, fragment);
m_paintingResourceMode = ApplyToDefaultMode;
}
@@ -478,22 +478,22 @@ bool SVGInlineTextBox::mapStartEndPositionsIntoFragmentCoordinates(const SVGText
return true;
}
-static inline float positionOffsetForDecoration(ETextDecoration decoration, const FontMetrics& fontMetrics, float thickness)
+static inline float positionOffsetForDecoration(TextDecoration decoration, const FontMetrics& fontMetrics, float thickness)
{
// FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified.
// Compatible with Batik/Opera.
- if (decoration == UNDERLINE)
+ if (decoration == TextDecorationUnderline)
return fontMetrics.floatAscent() + thickness * 1.5f;
- if (decoration == OVERLINE)
+ if (decoration == TextDecorationOverline)
return thickness;
- if (decoration == LINE_THROUGH)
+ if (decoration == TextDecorationLineThrough)
return fontMetrics.floatAscent() * 5 / 8.0f;
ASSERT_NOT_REACHED();
return 0.0f;
}
-static inline float thicknessForDecoration(ETextDecoration, const Font& font)
+static inline float thicknessForDecoration(TextDecoration, const Font& font)
{
// FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified.
// Compatible with Batik/Opera
@@ -507,7 +507,7 @@ static inline RenderObject* findRenderObjectDefininingTextDecoration(InlineFlowB
while (parentBox) {
renderer = parentBox->renderer();
- if (renderer->style() && renderer->style()->textDecoration() != TDNONE)
+ if (renderer->style() && renderer->style()->textDecoration() != TextDecorationNone)
break;
parentBox = parentBox->parent();
@@ -517,9 +517,9 @@ static inline RenderObject* findRenderObjectDefininingTextDecoration(InlineFlowB
return renderer;
}
-void SVGInlineTextBox::paintDecoration(GraphicsContext* context, ETextDecoration decoration, const SVGTextFragment& fragment)
+void SVGInlineTextBox::paintDecoration(GraphicsContext* context, TextDecoration decoration, const SVGTextFragment& fragment)
{
- if (textRenderer()->style()->textDecorationsInEffect() == TDNONE)
+ if (textRenderer()->style()->textDecorationsInEffect() == TextDecorationNone)
return;
// Find out which render style defined the text-decoration, as its fill/stroke properties have to be used for drawing instead of ours.
@@ -547,7 +547,7 @@ void SVGInlineTextBox::paintDecoration(GraphicsContext* context, ETextDecoration
}
}
-void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, ETextDecoration decoration, const SVGTextFragment& fragment, RenderObject* decorationRenderer)
+void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, TextDecoration decoration, const SVGTextFragment& fragment, RenderObject* decorationRenderer)
{
ASSERT(!m_paintingResource);
ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.h b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
index ef399c724..6fea28db3 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.h
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
@@ -31,7 +31,7 @@ namespace WebCore {
class RenderSVGResource;
class SVGRootInlineBox;
-class SVGInlineTextBox : public InlineTextBox {
+class SVGInlineTextBox FINAL : public InlineTextBox {
public:
SVGInlineTextBox(RenderObject*);
@@ -57,7 +57,7 @@ public:
Vector<SVGTextFragment>& textFragments() { return m_textFragments; }
const Vector<SVGTextFragment>& textFragments() const { return m_textFragments; }
- void dirtyLineBoxes() OVERRIDE;
+ virtual void dirtyLineBoxes() OVERRIDE;
bool startsNewTextChunk() const { return m_startsNewTextChunk; }
void setStartsNewTextChunk(bool newTextChunk) { m_startsNewTextChunk = newTextChunk; }
@@ -74,8 +74,8 @@ private:
bool prepareGraphicsContextForTextPainting(GraphicsContext*&, float scalingFactor, TextRun&, RenderStyle*);
void restoreGraphicsContextAfterTextPainting(GraphicsContext*&, TextRun&);
- void paintDecoration(GraphicsContext*, ETextDecoration, const SVGTextFragment&);
- void paintDecorationWithStyle(GraphicsContext*, ETextDecoration, const SVGTextFragment&, RenderObject* decorationRenderer);
+ void paintDecoration(GraphicsContext*, TextDecoration, const SVGTextFragment&);
+ void paintDecorationWithStyle(GraphicsContext*, TextDecoration, const SVGTextFragment&, RenderObject* decorationRenderer);
void paintTextWithShadows(GraphicsContext*, RenderStyle*, TextRun&, const SVGTextFragment&, int startPosition, int endPosition);
void paintText(GraphicsContext*, RenderStyle*, RenderStyle* selectionStyle, const SVGTextFragment&, bool hasSelection, bool paintSelectedTextOnly);
@@ -89,6 +89,12 @@ private:
Vector<SVGTextFragment> m_textFragments;
};
+inline SVGInlineTextBox* toSVGInlineTextBox(InlineBox* box)
+{
+ ASSERT_WITH_SECURITY_IMPLICATION(!box || box->isSVGInlineTextBox());
+ return static_cast<SVGInlineTextBox*>(box);
+}
+
} // namespace WebCore
#endif
diff --git a/Source/WebCore/rendering/svg/SVGMarkerData.h b/Source/WebCore/rendering/svg/SVGMarkerData.h
index 7e2ce0edc..6c70f4297 100644
--- a/Source/WebCore/rendering/svg/SVGMarkerData.h
+++ b/Source/WebCore/rendering/svg/SVGMarkerData.h
@@ -82,19 +82,23 @@ public:
private:
float currentAngle(SVGMarkerType type) const
{
- FloatSize inslopeChange = m_inslopePoints[1] - m_inslopePoints[0];
- FloatSize outslopeChange = m_outslopePoints[1] - m_outslopePoints[0];
+ // For details of this calculation, see: http://www.w3.org/TR/SVG/single-page.html#painting-MarkerElement
+ FloatPoint inSlope(m_inslopePoints[1] - m_inslopePoints[0]);
+ FloatPoint outSlope(m_outslopePoints[1] - m_outslopePoints[0]);
- double inslope = rad2deg(atan2(inslopeChange.height(), inslopeChange.width()));
- double outslope = rad2deg(atan2(outslopeChange.height(), outslopeChange.width()));
+ double inAngle = rad2deg(inSlope.slopeAngleRadians());
+ double outAngle = rad2deg(outSlope.slopeAngleRadians());
switch (type) {
case StartMarker:
- return narrowPrecisionToFloat(outslope);
+ return narrowPrecisionToFloat(outAngle);
case MidMarker:
- return narrowPrecisionToFloat((inslope + outslope) / 2);
+ // WK193015: Prevent bugs due to angles being non-continuous.
+ if (fabs(inAngle - outAngle) > 180)
+ inAngle += 360;
+ return narrowPrecisionToFloat((inAngle + outAngle) / 2);
case EndMarker:
- return narrowPrecisionToFloat(inslope);
+ return narrowPrecisionToFloat(inAngle);
}
ASSERT_NOT_REACHED();
diff --git a/Source/WebCore/rendering/svg/SVGPathData.cpp b/Source/WebCore/rendering/svg/SVGPathData.cpp
index 98c80b22f..234122510 100644
--- a/Source/WebCore/rendering/svg/SVGPathData.cpp
+++ b/Source/WebCore/rendering/svg/SVGPathData.cpp
@@ -73,8 +73,7 @@ static void updatePathFromLineElement(SVGElement* element, Path& path)
static void updatePathFromPathElement(SVGElement* element, Path& path)
{
- ASSERT(element->hasTagName(SVGNames::pathTag));
- buildPathFromByteStream(static_cast<SVGPathElement*>(element)->pathByteStream(), path);
+ buildPathFromByteStream(toSVGPathElement(element)->pathByteStream(), path);
}
static void updatePathFromPolygonElement(SVGElement* element, Path& path)
diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
index c75015d57..4fba77407 100644
--- a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
@@ -42,7 +42,6 @@
#include "SVGResourcesCache.h"
#include "SVGStyledElement.h"
#include "TransformState.h"
-#include <wtf/UnusedParam.h>
namespace WebCore {
@@ -50,6 +49,7 @@ FloatRect SVGRenderSupport::repaintRectForRendererInLocalCoordinatesExcludingSVG
{
// FIXME: Add support for RenderSVGBlock.
+ // FIXME: This should use a safer cast such as toRenderSVGModelObject().
if (object->isSVGShape() || object->isSVGImage() || object->isSVGContainer())
return static_cast<const RenderSVGModelObject*>(object)->repaintRectInLocalCoordinatesExcludingSVGShadow();
@@ -84,7 +84,7 @@ void SVGRenderSupport::computeFloatRectForRepaint(const RenderObject* object, co
object->parent()->computeFloatRectForRepaint(repaintContainer, repaintRect, fixed);
}
-void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, const RenderLayerModelObject* repaintContainer, TransformState& transformState, bool snapOffsetForTransforms, bool* wasFixed)
+void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, const RenderLayerModelObject* repaintContainer, TransformState& transformState, bool* wasFixed)
{
transformState.applyTransform(object->localToParentTransform());
@@ -97,8 +97,6 @@ void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, const Ren
transformState.applyTransform(toRenderSVGRoot(parent)->localToBorderBoxTransform());
MapCoordinatesFlags mode = UseTransforms;
- if (snapOffsetForTransforms)
- mode |= SnapOffsetForTransforms;
parent->mapLocalToContainer(repaintContainer, transformState, mode, wasFixed);
}
@@ -231,12 +229,21 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
{
bool layoutSizeChanged = layoutSizeOfNearestViewportChanged(start);
bool transformChanged = transformToRootChanged(start);
+ bool hasSVGShadow = rendererHasSVGShadow(start);
+ bool needsBoundariesUpdate = start->needsBoundariesUpdate();
HashSet<RenderObject*> notlayoutedObjects;
for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
bool needsLayout = selfNeedsLayout;
bool childEverHadLayout = child->everHadLayout();
+ if (needsBoundariesUpdate && hasSVGShadow) {
+ // If we have a shadow, our shadow is baked into our children's cached boundaries,
+ // so they need to update.
+ child->setNeedsBoundariesUpdate();
+ needsLayout = true;
+ }
+
if (transformChanged) {
// If the transform changed we need to update the text metrics (note: this also happens for layoutSizeChanged=true).
if (child->isSVGText())
@@ -246,8 +253,8 @@ void SVGRenderSupport::layoutChildren(RenderObject* start, bool selfNeedsLayout)
if (layoutSizeChanged) {
// When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths
- if (SVGElement* element = child->node()->isSVGElement() ? static_cast<SVGElement*>(child->node()) : 0) {
- if (element->isStyled() && static_cast<SVGStyledElement*>(element)->hasRelativeLengths()) {
+ if (SVGElement* element = child->node()->isSVGElement() ? toSVGElement(child->node()) : 0) {
+ if (element->isSVGStyledElement() && toSVGStyledElement(element)->hasRelativeLengths()) {
// When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object
if (child->isSVGShape())
toRenderSVGShape(child)->setNeedsShapeUpdate();
@@ -307,11 +314,12 @@ bool SVGRenderSupport::rendererHasSVGShadow(const RenderObject* object)
{
// FIXME: Add support for RenderSVGBlock.
+ // FIXME: This should use a safer cast such as toRenderSVGModelObject().
if (object->isSVGShape() || object->isSVGImage() || object->isSVGContainer())
return static_cast<const RenderSVGModelObject*>(object)->hasSVGShadow();
if (object->isSVGRoot())
- return static_cast<const RenderSVGRoot*>(object)->hasSVGShadow();
+ return toRenderSVGRoot(object)->hasSVGShadow();
return false;
}
@@ -320,6 +328,7 @@ void SVGRenderSupport::setRendererHasSVGShadow(RenderObject* object, bool hasSha
{
// FIXME: Add support for RenderSVGBlock.
+ // FIXME: This should use a safer cast such as toRenderSVGModelObject().
if (object->isSVGShape() || object->isSVGImage() || object->isSVGContainer())
return static_cast<RenderSVGModelObject*>(object)->setHasSVGShadow(hasShadow);
@@ -424,7 +433,7 @@ void SVGRenderSupport::applyStrokeStyleToContext(GraphicsContext* context, const
const SVGRenderStyle* svgStyle = style->svgStyle();
ASSERT(svgStyle);
- SVGLengthContext lengthContext(static_cast<SVGElement*>(object->node()));
+ SVGLengthContext lengthContext(toSVGElement(object->node()));
context->setStrokeThickness(svgStyle->strokeWidth().value(lengthContext));
context->setLineCap(svgStyle->capStyle());
context->setLineJoin(svgStyle->joinStyle());
diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.h b/Source/WebCore/rendering/svg/SVGRenderSupport.h
index f7375e43b..0b1871617 100644
--- a/Source/WebCore/rendering/svg/SVGRenderSupport.h
+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.h
@@ -68,7 +68,7 @@ public:
static FloatRect repaintRectForRendererInLocalCoordinatesExcludingSVGShadow(const RenderObject*);
static LayoutRect clippedOverflowRectForRepaint(const RenderObject*, const RenderLayerModelObject* repaintContainer);
static void computeFloatRectForRepaint(const RenderObject*, const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed);
- static void mapLocalToContainer(const RenderObject*, const RenderLayerModelObject* repaintContainer, TransformState&, bool snapOffsetForTransforms = true, bool* wasFixed = 0);
+ static void mapLocalToContainer(const RenderObject*, const RenderLayerModelObject* repaintContainer, TransformState&, bool* wasFixed = 0);
static const RenderObject* pushMappingToContainer(const RenderObject*, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&);
static bool checkForSVGRepaintDuringLayout(RenderObject*);
diff --git a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
index 12352ae72..532db27c6 100644
--- a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
@@ -262,7 +262,7 @@ static void writeSVGPaintingResource(TextStream& ts, RenderSVGResource* resource
else if (resource->resourceType() == RadialGradientResourceType)
ts << "[type=RADIAL-GRADIENT]";
- ts << " [id=\"" << static_cast<SVGElement*>(node)->getIdAttribute() << "\"]";
+ ts << " [id=\"" << toSVGElement(node)->getIdAttribute() << "\"]";
}
static void writeStyle(TextStream& ts, const RenderObject& object)
@@ -285,7 +285,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
ts << " [stroke={" << s;
writeSVGPaintingResource(ts, strokePaintingResource);
- SVGLengthContext lengthContext(static_cast<SVGElement*>(shape.node()));
+ SVGLengthContext lengthContext(toSVGElement(shape.node()));
double dashOffset = svgStyle->strokeDashOffset().value(lengthContext);
double strokeWidth = svgStyle->strokeWidth().value(lengthContext);
const Vector<SVGLength>& dashes = svgStyle->strokeDashArray();
@@ -336,7 +336,7 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
writePositionAndStyle(ts, shape);
ASSERT(shape.node()->isSVGElement());
- SVGElement* svgElement = static_cast<SVGElement*>(shape.node());
+ SVGElement* svgElement = toSVGElement(shape.node());
SVGLengthContext lengthContext(svgElement);
if (svgElement->hasTagName(SVGNames::rectTag)) {
@@ -366,7 +366,7 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
SVGPolyElement* element = static_cast<SVGPolyElement*>(svgElement);
writeNameAndQuotedValue(ts, "points", element->pointList().valueAsString());
} else if (svgElement->hasTagName(SVGNames::pathTag)) {
- SVGPathElement* element = static_cast<SVGPathElement*>(svgElement);
+ SVGPathElement* element = toSVGPathElement(svgElement);
String pathString;
// FIXME: We should switch to UnalteredParsing here - this will affect the path dumping output of dozens of tests.
buildStringFromByteStream(element->pathByteStream(), pathString, NormalizedParsing);
@@ -459,7 +459,7 @@ static inline void writeSVGInlineTextBoxes(TextStream& ts, const RenderText& tex
if (!box->isSVGInlineTextBox())
continue;
- writeSVGInlineTextBox(ts, static_cast<SVGInlineTextBox*>(box), indent);
+ writeSVGInlineTextBox(ts, toSVGInlineTextBox(box), indent);
}
}
@@ -493,7 +493,7 @@ void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int i
{
writeStandardPrefix(ts, object, indent);
- Element* element = static_cast<Element*>(object.node());
+ Element* element = toElement(object.node());
const AtomicString& id = element->getIdAttribute();
writeNameAndQuotedValue(ts, "id", id);
diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
index 041aed418..a65d39fe6 100644
--- a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
@@ -30,6 +30,8 @@
#include "BasicShapes.h"
#include "Frame.h"
#include "FrameView.h"
+#include "RenderLayer.h"
+#include "RenderSVGImage.h"
#include "RenderSVGResource.h"
#include "RenderSVGResourceClipper.h"
#include "RenderSVGResourceFilter.h"
@@ -59,8 +61,9 @@ SVGRenderingContext::~SVGRenderingContext()
#if ENABLE(FILTERS)
if (m_renderingFlags & EndFilterLayer) {
ASSERT(m_filter);
- m_filter->postApplyResource(static_cast<RenderSVGShape*>(m_object), m_paintInfo->context, ApplyToDefaultMode, 0, 0);
+ m_filter->postApplyResource(m_object, m_paintInfo->context, ApplyToDefaultMode, 0, 0);
m_paintInfo->context = m_savedContext;
+ m_paintInfo->rect = m_savedPaintRect;
}
#endif
@@ -117,7 +120,7 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderObject* object, PaintI
if (shadow) {
m_paintInfo->context->clip(repaintRect);
- m_paintInfo->context->setShadow(IntSize(roundToInt(shadow->x()), roundToInt(shadow->y())), shadow->blur(), shadow->color(), style->colorSpace());
+ m_paintInfo->context->setShadow(IntSize(roundToInt(shadow->x()), roundToInt(shadow->y())), shadow->radius(), shadow->color(), style->colorSpace());
m_paintInfo->context->beginTransparencyLayer(1);
m_renderingFlags |= EndShadowLayer;
}
@@ -157,11 +160,18 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderObject* object, PaintI
m_filter = resources->filter();
if (m_filter) {
m_savedContext = m_paintInfo->context;
+ m_savedPaintRect = m_paintInfo->rect;
// Return with false here may mean that we don't need to draw the content
// (because it was either drawn before or empty) but we still need to apply the filter.
m_renderingFlags |= EndFilterLayer;
if (!m_filter->applyResource(m_object, style, m_paintInfo->context, ApplyToDefaultMode))
return;
+
+ // Since we're caching the resulting bitmap and do not invalidate it on repaint rect
+ // changes, we need to paint the whole filter region. Otherwise, elements not visible
+ // at the time of the initial paint (due to scrolling, window size, etc.) will never
+ // be drawn.
+ m_paintInfo->rect = IntRect(m_filter->drawingRegion(m_object));
}
}
#endif
@@ -180,21 +190,34 @@ float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObje
ASSERT(renderer);
AffineTransform ctm;
- calculateTransformationToOutermostSVGCoordinateSystem(renderer, ctm);
+ calculateTransformationToOutermostCoordinateSystem(renderer, ctm);
return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
}
-void SVGRenderingContext::calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform)
+void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform)
{
- const RenderObject* current = renderer;
- ASSERT(current);
-
+ ASSERT(renderer);
absoluteTransform = currentContentTransformation();
- while (current) {
- absoluteTransform = current->localToParentTransform() * absoluteTransform;
- if (current->isSVGRoot())
+
+ // Walk up the render tree, accumulating SVG transforms.
+ while (renderer) {
+ absoluteTransform = renderer->localToParentTransform() * absoluteTransform;
+ if (renderer->isSVGRoot())
break;
- current = current->parent();
+ renderer = renderer->parent();
+ }
+
+ // Continue walking up the layer tree, accumulating CSS transforms.
+ RenderLayer* layer = renderer ? renderer->enclosingLayer() : 0;
+ while (layer) {
+ if (TransformationMatrix* layerTransform = layer->transform())
+ absoluteTransform = layerTransform->toAffineTransform() * absoluteTransform;
+
+ // We can stop at compositing layers, to match the backing resolution.
+ if (layer->isComposited())
+ break;
+
+ layer = layer->parent();
}
}
@@ -251,7 +274,7 @@ void SVGRenderingContext::renderSubtreeToImageBuffer(ImageBuffer* image, RenderO
ASSERT(image);
ASSERT(image->context());
- PaintInfo info(image->context(), PaintInfo::infiniteRect(), PaintPhaseForeground, 0, 0, 0, 0);
+ PaintInfo info(image->context(), PaintInfo::infiniteRect(), PaintPhaseForeground, PaintBehaviorNormal);
AffineTransform& contentTransformation = currentContentTransformation();
AffineTransform savedContentTransformation = contentTransformation;
@@ -302,6 +325,37 @@ void SVGRenderingContext::clear2DRotation(AffineTransform& transform)
transform.recompose(decomposition);
}
+bool SVGRenderingContext::bufferForeground(OwnPtr<ImageBuffer>& imageBuffer)
+{
+ ASSERT(m_paintInfo);
+ ASSERT(m_object->isSVGImage());
+ FloatRect boundingBox = m_object->objectBoundingBox();
+
+ // Invalidate an existing buffer if the scale is not correct.
+ if (imageBuffer) {
+ AffineTransform transform = m_paintInfo->context->getCTM(GraphicsContext::DefinitelyIncludeDeviceScale);
+ IntSize expandedBoundingBox = expandedIntSize(boundingBox.size());
+ IntSize bufferSize(static_cast<int>(ceil(expandedBoundingBox.width() * transform.xScale())), static_cast<int>(ceil(expandedBoundingBox.height() * transform.yScale())));
+ if (bufferSize != imageBuffer->internalSize())
+ imageBuffer.clear();
+ }
+
+ // Create a new buffer and paint the foreground into it.
+ if (!imageBuffer) {
+ if ((imageBuffer = m_paintInfo->context->createCompatibleBuffer(expandedIntSize(boundingBox.size()), true))) {
+ GraphicsContext* bufferedRenderingContext = imageBuffer->context();
+ bufferedRenderingContext->translate(-boundingBox.x(), -boundingBox.y());
+ PaintInfo bufferedInfo(*m_paintInfo);
+ bufferedInfo.context = bufferedRenderingContext;
+ toRenderSVGImage(m_object)->paintForeground(bufferedInfo);
+ } else
+ return false;
+ }
+
+ m_paintInfo->context->drawImageBuffer(imageBuffer.get(), ColorSpaceDeviceRGB, boundingBox);
+ return true;
+}
+
}
#endif
diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.h b/Source/WebCore/rendering/svg/SVGRenderingContext.h
index c88168968..1fc3f1a2e 100644
--- a/Source/WebCore/rendering/svg/SVGRenderingContext.h
+++ b/Source/WebCore/rendering/svg/SVGRenderingContext.h
@@ -83,7 +83,7 @@ public:
static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& targetRect, OwnPtr<ImageBuffer>&, bool safeToClear);
static float calculateScreenFontSizeScalingFactor(const RenderObject*);
- static void calculateTransformationToOutermostSVGCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform);
+ static void calculateTransformationToOutermostCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform);
static IntSize clampedAbsoluteSize(const IntSize&);
static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect);
static void clear2DRotation(AffineTransform&);
@@ -93,6 +93,9 @@ public:
return enclosingIntRect(absoluteTransform.mapRect(targetRect));
}
+ // Support for the buffered-rendering hint.
+ bool bufferForeground(OwnPtr<ImageBuffer>&);
+
private:
// To properly revert partially successful initializtions in the destructor, we record all successful steps.
enum RenderingFlags {
@@ -111,6 +114,7 @@ private:
RenderObject* m_object;
PaintInfo* m_paintInfo;
GraphicsContext* m_savedContext;
+ IntRect m_savedPaintRect;
#if ENABLE(FILTERS)
RenderSVGResourceFilter* m_filter;
#endif
diff --git a/Source/WebCore/rendering/svg/SVGResources.cpp b/Source/WebCore/rendering/svg/SVGResources.cpp
index d9097409d..015190d27 100644
--- a/Source/WebCore/rendering/svg/SVGResources.cpp
+++ b/Source/WebCore/rendering/svg/SVGResources.cpp
@@ -146,10 +146,10 @@ static inline String targetReferenceFromResource(SVGElement* element)
if (element->hasTagName(SVGNames::patternTag))
target = static_cast<SVGPatternElement*>(element)->href();
else if (element->hasTagName(SVGNames::linearGradientTag) || element->hasTagName(SVGNames::radialGradientTag))
- target = static_cast<SVGGradientElement*>(element)->href();
+ target = toSVGGradientElement(element)->href();
#if ENABLE(FILTERS)
else if (element->hasTagName(SVGNames::filterTag))
- target = static_cast<SVGFilterElement*>(element)->href();
+ target = toSVGFilterElement(element)->href();
#endif
else
ASSERT_NOT_REACHED();
@@ -179,8 +179,8 @@ static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document*
static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, SVGElement* element)
{
ASSERT(element);
- ASSERT(element->isStyled());
- extensions->addPendingResource(id, static_cast<SVGStyledElement*>(element));
+ ASSERT_WITH_SECURITY_IMPLICATION(element->isSVGStyledElement());
+ extensions->addPendingResource(id, toSVGStyledElement(element));
}
bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRenderStyle* style)
@@ -190,9 +190,9 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
Node* node = object->node();
ASSERT(node);
- ASSERT(node->isSVGElement());
+ ASSERT_WITH_SECURITY_IMPLICATION(node->isSVGElement());
- SVGElement* element = static_cast<SVGElement*>(node);
+ SVGElement* element = toSVGElement(node);
if (!element)
return false;
diff --git a/Source/WebCore/rendering/svg/SVGResourcesCache.cpp b/Source/WebCore/rendering/svg/SVGResourcesCache.cpp
index 8b48cf53e..3f6e7dee1 100644
--- a/Source/WebCore/rendering/svg/SVGResourcesCache.cpp
+++ b/Source/WebCore/rendering/svg/SVGResourcesCache.cpp
@@ -36,7 +36,6 @@ SVGResourcesCache::SVGResourcesCache()
SVGResourcesCache::~SVGResourcesCache()
{
- deleteAllValues(m_cache);
}
void SVGResourcesCache::addResourcesFromRenderObject(RenderObject* object, const RenderStyle* style)
@@ -49,14 +48,12 @@ void SVGResourcesCache::addResourcesFromRenderObject(RenderObject* object, const
ASSERT(svgStyle);
// Build a list of all resources associated with the passed RenderObject
- SVGResources* resources = new SVGResources;
- if (!resources->buildCachedResources(object, svgStyle)) {
- delete resources;
+ OwnPtr<SVGResources> newResources = adoptPtr(new SVGResources);
+ if (!newResources->buildCachedResources(object, svgStyle))
return;
- }
// Put object in cache.
- m_cache.set(object, resources);
+ SVGResources* resources = m_cache.set(object, newResources.release()).iterator->value.get();
// Run cycle-detection _afterwards_, so self-references can be caught as well.
SVGResourcesCycleSolver solver(object, resources);
@@ -76,7 +73,7 @@ void SVGResourcesCache::removeResourcesFromRenderObject(RenderObject* object)
if (!m_cache.contains(object))
return;
- SVGResources* resources = m_cache.get(object);
+ OwnPtr<SVGResources> resources = m_cache.take(object);
// Walk resources and register the render object at each resources.
HashSet<RenderSVGResourceContainer*> resourceSet;
@@ -85,8 +82,6 @@ void SVGResourcesCache::removeResourcesFromRenderObject(RenderObject* object)
HashSet<RenderSVGResourceContainer*>::iterator end = resourceSet.end();
for (HashSet<RenderSVGResourceContainer*>::iterator it = resourceSet.begin(); it != end; ++it)
(*it)->removeClient(object);
-
- delete m_cache.take(object);
}
static inline SVGResourcesCache* resourcesCacheFromRenderObject(const RenderObject* renderer)
@@ -106,11 +101,7 @@ static inline SVGResourcesCache* resourcesCacheFromRenderObject(const RenderObje
SVGResources* SVGResourcesCache::cachedResourcesForRenderObject(const RenderObject* renderer)
{
ASSERT(renderer);
- SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
- if (!cache->m_cache.contains(renderer))
- return 0;
-
- return cache->m_cache.get(renderer);
+ return resourcesCacheFromRenderObject(renderer)->m_cache.get(renderer);
}
void SVGResourcesCache::clientLayoutChanged(RenderObject* object)
@@ -125,6 +116,12 @@ void SVGResourcesCache::clientLayoutChanged(RenderObject* object)
resources->removeClientFromCache(object);
}
+static inline bool rendererCanHaveResources(RenderObject* renderer)
+{
+ ASSERT(renderer);
+ return renderer->node() && renderer->node()->isSVGElement() && !renderer->isSVGInlineText();
+}
+
void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifference diff, const RenderStyle* newStyle)
{
ASSERT(renderer);
@@ -132,24 +129,22 @@ void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifferen
return;
// In this case the proper SVGFE*Element will decide whether the modified CSS properties require a relayout or repaint.
- if (renderer->isSVGResourceFilterPrimitive() && diff == StyleDifferenceRepaint)
+ if (renderer->isSVGResourceFilterPrimitive() && (diff == StyleDifferenceRepaint || diff == StyleDifferenceRepaintIfText))
return;
// Dynamic changes of CSS properties like 'clip-path' may require us to recompute the associated resources for a renderer.
// FIXME: Avoid passing in a useless StyleDifference, but instead compare oldStyle/newStyle to see which resources changed
// to be able to selectively rebuild individual resources, instead of all of them.
- SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
- cache->removeResourcesFromRenderObject(renderer);
- cache->addResourcesFromRenderObject(renderer, newStyle);
+ if (rendererCanHaveResources(renderer)) {
+ SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
+ cache->removeResourcesFromRenderObject(renderer);
+ cache->addResourcesFromRenderObject(renderer, newStyle);
+ }
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
-}
-static inline bool rendererCanHaveResources(RenderObject* renderer)
-{
- ASSERT(renderer);
- ASSERT(renderer->parent());
- return renderer->node() && !renderer->isSVGInlineText();
+ if (renderer->node() && !renderer->node()->isSVGElement())
+ renderer->node()->setNeedsStyleRecalc(SyntheticStyleChange);
}
void SVGResourcesCache::clientWasAddedToTree(RenderObject* renderer, const RenderStyle* newStyle)
@@ -196,13 +191,13 @@ void SVGResourcesCache::resourceDestroyed(RenderSVGResourceContainer* resource)
// The resource itself may have clients, that need to be notified.
cache->removeResourcesFromRenderObject(resource);
- HashMap<const RenderObject*, SVGResources*>::iterator end = cache->m_cache.end();
- for (HashMap<const RenderObject*, SVGResources*>::iterator it = cache->m_cache.begin(); it != end; ++it) {
+ CacheMap::iterator end = cache->m_cache.end();
+ for (CacheMap::iterator it = cache->m_cache.begin(); it != end; ++it) {
it->value->resourceDestroyed(resource);
// Mark users of destroyed resources as pending resolution based on the id of the old resource.
Element* resourceElement = toElement(resource->node());
- SVGStyledElement* clientElement = toSVGStyledElement(it->key->node());
+ Element* clientElement = toElement(it->key->node());
SVGDocumentExtensions* extensions = clientElement->document()->accessSVGExtensions();
extensions->addPendingResource(resourceElement->fastGetAttribute(HTMLNames::idAttr), clientElement);
diff --git a/Source/WebCore/rendering/svg/SVGResourcesCache.h b/Source/WebCore/rendering/svg/SVGResourcesCache.h
index 633fcd73d..67a01059c 100644
--- a/Source/WebCore/rendering/svg/SVGResourcesCache.h
+++ b/Source/WebCore/rendering/svg/SVGResourcesCache.h
@@ -23,6 +23,7 @@
#if ENABLE(SVG)
#include "RenderStyleConstants.h"
#include <wtf/HashMap.h>
+#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -61,7 +62,8 @@ private:
void addResourcesFromRenderObject(RenderObject*, const RenderStyle*);
void removeResourcesFromRenderObject(RenderObject*);
- HashMap<const RenderObject*, SVGResources*> m_cache;
+ typedef HashMap<const RenderObject*, OwnPtr<SVGResources> > CacheMap;
+ CacheMap m_cache;
};
}
diff --git a/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp b/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp
index 546fec26c..d2df3f16d 100644
--- a/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp
@@ -51,9 +51,9 @@ void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
if (hasSelection) {
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
if (child->isSVGInlineTextBox())
- static_cast<SVGInlineTextBox*>(child)->paintSelectionBackground(childPaintInfo);
+ toSVGInlineTextBox(child)->paintSelectionBackground(childPaintInfo);
else if (child->isSVGInlineFlowBox())
- static_cast<SVGInlineFlowBox*>(child)->paintSelectionBackground(childPaintInfo);
+ toSVGInlineFlowBox(child)->paintSelectionBackground(childPaintInfo);
}
}
@@ -61,7 +61,7 @@ void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUni
if (renderingContext.isRenderingPrepared()) {
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
if (child->isSVGInlineTextBox())
- SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(static_cast<SVGInlineTextBox*>(child)->textRenderer()));
+ SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(toRenderSVGInlineText(toSVGInlineTextBox(child)->textRenderer()));
child->paint(paintInfo, LayoutPoint(), 0, 0);
}
@@ -101,7 +101,7 @@ void SVGRootInlineBox::layoutCharactersInTextBoxes(InlineFlowBox* start, SVGText
ASSERT(child->renderer());
ASSERT(child->renderer()->isSVGInlineText());
- SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(child);
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
characterLayout.layoutInlineTextBox(textBox);
} else {
// Skip generated content.
@@ -109,9 +109,9 @@ void SVGRootInlineBox::layoutCharactersInTextBoxes(InlineFlowBox* start, SVGText
if (!node)
continue;
- ASSERT(child->isInlineFlowBox());
+ ASSERT_WITH_SECURITY_IMPLICATION(child->isInlineFlowBox());
- SVGInlineFlowBox* flowBox = static_cast<SVGInlineFlowBox*>(child);
+ SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
bool isTextPath = node->hasTagName(SVGNames::textPathTag);
if (isTextPath) {
// Build text chunks for all <textPath> children, using the line layout algorithm.
@@ -138,7 +138,7 @@ void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRe
ASSERT(child->renderer());
ASSERT(child->renderer()->isSVGInlineText());
- SVGInlineTextBox* textBox = static_cast<SVGInlineTextBox*>(child);
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
boxRect = textBox->calculateBoundaries();
textBox->setX(boxRect.x());
textBox->setY(boxRect.y());
@@ -149,9 +149,9 @@ void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRe
if (!child->renderer()->node())
continue;
- ASSERT(child->isInlineFlowBox());
+ ASSERT_WITH_SECURITY_IMPLICATION(child->isInlineFlowBox());
- SVGInlineFlowBox* flowBox = static_cast<SVGInlineFlowBox*>(child);
+ SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
layoutChildBoxes(flowBox);
boxRect = flowBox->calculateBoundaries();
@@ -171,9 +171,9 @@ void SVGRootInlineBox::layoutRootBox(const FloatRect& childRect)
ASSERT(parentBlock);
// Finally, assign the root block position, now that all content is laid out.
- IntRect roundedChildRect = enclosingIntRect(childRect);
- parentBlock->setLocation(roundedChildRect.location());
- parentBlock->setSize(roundedChildRect.size());
+ LayoutRect boundingRect = enclosingLayoutRect(childRect);
+ parentBlock->setLocation(boundingRect.location());
+ parentBlock->setSize(boundingRect.size());
// Position all children relative to the parent block.
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
@@ -188,7 +188,7 @@ void SVGRootInlineBox::layoutRootBox(const FloatRect& childRect)
setY(0);
setLogicalWidth(childRect.width());
setLogicalHeight(childRect.height());
- setLineTopBottomPositions(0, roundedChildRect.height(), 0, roundedChildRect.height());
+ setLineTopBottomPositions(0, boundingRect.height(), 0, boundingRect.height());
}
InlineBox* SVGRootInlineBox::closestLeafChildForPosition(const LayoutPoint& point)
@@ -278,8 +278,8 @@ static inline void reverseInlineBoxRangeAndValueListsIfNeeded(void* userData, Ve
continue;
}
- SVGInlineTextBox* firstTextBox = static_cast<SVGInlineTextBox*>(*first);
- SVGInlineTextBox* lastTextBox = static_cast<SVGInlineTextBox*>(*last);
+ SVGInlineTextBox* firstTextBox = toSVGInlineTextBox(*first);
+ SVGInlineTextBox* lastTextBox = toSVGInlineTextBox(*last);
// Reordering is only necessary for BiDi text that is _absolutely_ positioned.
if (firstTextBox->len() == 1 && firstTextBox->len() == lastTextBox->len()) {
diff --git a/Source/WebCore/rendering/svg/SVGRootInlineBox.h b/Source/WebCore/rendering/svg/SVGRootInlineBox.h
index 7aec8d888..5bab4f784 100644
--- a/Source/WebCore/rendering/svg/SVGRootInlineBox.h
+++ b/Source/WebCore/rendering/svg/SVGRootInlineBox.h
@@ -32,7 +32,7 @@ namespace WebCore {
class SVGInlineTextBox;
-class SVGRootInlineBox : public RootInlineBox {
+class SVGRootInlineBox FINAL : public RootInlineBox {
public:
SVGRootInlineBox(RenderBlock* block)
: RootInlineBox(block)
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
index ba2b7639d..e31104575 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
@@ -171,6 +171,8 @@ void SVGTextLayoutEngine::beginTextPathLayout(RenderObject* object, SVGTextLayou
RenderSVGTextPath* textPath = toRenderSVGTextPath(object);
m_textPath = textPath->layoutPath();
+ if (m_textPath.isEmpty())
+ return;
m_textPathStartOffset = textPath->startOffset();
m_textPathLength = m_textPath.length();
if (m_textPathStartOffset > 0 && m_textPathStartOffset <= 1)
@@ -423,7 +425,10 @@ void SVGTextLayoutEngine::advanceToNextVisualCharacter(const SVGTextMetrics& vis
void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, RenderSVGInlineText* text, const RenderStyle* style)
{
- SVGElement* lengthContext = static_cast<SVGElement*>(text->parent()->node());
+ if (m_inPathLayout && m_textPath.isEmpty())
+ return;
+
+ SVGElement* lengthContext = toSVGElement(text->parent()->node());
RenderObject* textParent = text->parent();
bool definesTextLength = textParent ? parentDefinesTextLength(textParent) : false;
@@ -578,20 +583,9 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, Rend
y += m_dy;
}
- // Determine wheter we have to start a new fragment.
- bool shouldStartNewFragment = false;
-
- if (m_dx || m_dy)
- shouldStartNewFragment = true;
-
- if (!shouldStartNewFragment && (m_isVerticalText || m_inPathLayout))
- shouldStartNewFragment = true;
-
- if (!shouldStartNewFragment && (angle || angle != lastAngle || orientationAngle))
- shouldStartNewFragment = true;
-
- if (!shouldStartNewFragment && (kerning || applySpacingToNextCharacter || definesTextLength))
- shouldStartNewFragment = true;
+ // Determine whether we have to start a new fragment.
+ bool shouldStartNewFragment = m_dx || m_dy || m_isVerticalText || m_inPathLayout || angle || angle != lastAngle
+ || orientationAngle || kerning || applySpacingToNextCharacter || definesTextLength;
// If we already started a fragment, close it now.
if (didStartTextFragment && shouldStartNewFragment) {
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
index 074a8ea66..f0107c4ab 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
@@ -30,8 +30,6 @@
#include "SVGFontData.h"
#include "SVGFontElement.h"
#include "SVGFontFaceElement.h"
-#else
-#include <wtf/UnusedParam.h>
#endif
namespace WebCore {
diff --git a/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp b/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp
index dfeebb2f8..901ec8179 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp
@@ -65,9 +65,6 @@ void SVGTextMetricsBuilder::advanceSimpleText()
return;
}
- if (currentCharacterStartsSurrogatePair())
- ASSERT(metricsLength == 2);
-
float currentWidth = m_simpleWidthIterator->runWidthSoFar() - m_totalWidth;
m_totalWidth = m_simpleWidthIterator->runWidthSoFar();
diff --git a/Source/WebCore/rendering/svg/SVGTextQuery.cpp b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
index a7ee787c4..bcc8d87ba 100644
--- a/Source/WebCore/rendering/svg/SVGTextQuery.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
@@ -101,7 +101,7 @@ void SVGTextQuery::collectTextBoxesInFlowBox(InlineFlowBox* flowBox)
}
if (child->isSVGInlineTextBox())
- m_textBoxes.append(static_cast<SVGInlineTextBox*>(child));
+ m_textBoxes.append(toSVGInlineTextBox(child));
}
}
@@ -352,10 +352,10 @@ bool SVGTextQuery::startPositionOfCharacterCallback(Data* queryData, const SVGTe
return true;
}
-FloatPoint SVGTextQuery::startPositionOfCharacter(unsigned position) const
+SVGPoint SVGTextQuery::startPositionOfCharacter(unsigned position) const
{
if (m_textBoxes.isEmpty())
- return FloatPoint();
+ return SVGPoint();
StartPositionOfCharacterData data(position);
executeQuery(&data, &SVGTextQuery::startPositionOfCharacterCallback);
@@ -399,10 +399,10 @@ bool SVGTextQuery::endPositionOfCharacterCallback(Data* queryData, const SVGText
return true;
}
-FloatPoint SVGTextQuery::endPositionOfCharacter(unsigned position) const
+SVGPoint SVGTextQuery::endPositionOfCharacter(unsigned position) const
{
if (m_textBoxes.isEmpty())
- return FloatPoint();
+ return SVGPoint();
EndPositionOfCharacterData data(position);
executeQuery(&data, &SVGTextQuery::endPositionOfCharacterCallback);
@@ -543,7 +543,7 @@ bool SVGTextQuery::characterNumberAtPositionCallback(Data* queryData, const SVGT
return false;
}
-int SVGTextQuery::characterNumberAtPosition(const FloatPoint& position) const
+int SVGTextQuery::characterNumberAtPosition(const SVGPoint& position) const
{
if (m_textBoxes.isEmpty())
return -1;
diff --git a/Source/WebCore/rendering/svg/SVGTextQuery.h b/Source/WebCore/rendering/svg/SVGTextQuery.h
index 331dd945c..bf60a6da6 100644
--- a/Source/WebCore/rendering/svg/SVGTextQuery.h
+++ b/Source/WebCore/rendering/svg/SVGTextQuery.h
@@ -22,6 +22,7 @@
#if ENABLE(SVG)
#include "FloatRect.h"
+#include "SVGPoint.h"
#include "SVGTextFragment.h"
#include <wtf/Vector.h>
@@ -38,11 +39,11 @@ public:
unsigned numberOfCharacters() const;
float textLength() const;
float subStringLength(unsigned startPosition, unsigned length) const;
- FloatPoint startPositionOfCharacter(unsigned position) const;
- FloatPoint endPositionOfCharacter(unsigned position) const;
+ SVGPoint startPositionOfCharacter(unsigned position) const;
+ SVGPoint endPositionOfCharacter(unsigned position) const;
float rotationOfCharacter(unsigned position) const;
FloatRect extentOfCharacter(unsigned position) const;
- int characterNumberAtPosition(const FloatPoint&) const;
+ int characterNumberAtPosition(const SVGPoint&) const;
// Public helper struct. Private classes in SVGTextQuery inherit from it.
struct Data;
diff --git a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
index 7dd60d49e..f94b283e6 100644
--- a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
@@ -126,7 +126,7 @@ void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const T
if (!glyph)
continue;
- float advance = glyphBuffer.advanceAt(from + i);
+ float advance = glyphBuffer.advanceAt(from + i).width();
SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
ASSERT(!svgGlyph.isPartOfLigature);
ASSERT(svgGlyph.tableEntry == glyph);
@@ -174,7 +174,7 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co
const SimpleFontData* primaryFont = font.primaryFont();
ASSERT(primaryFont);
- pair<GlyphData, GlyphPage*> pair = font.glyphDataAndPageForCharacter(character, mirror);
+ pair<GlyphData, GlyphPage*> pair = font.glyphDataAndPageForCharacter(character, mirror, AutoVariant);
GlyphData glyphData = pair.first;
// Check if we have the missing glyph data, in which case we can just return.
@@ -186,9 +186,9 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co
// Save data fromt he font fallback list because we may modify it later. Do this before the
// potential change to glyphData.fontData below.
- FontFallbackList* fontList = font.fontList();
- ASSERT(fontList);
- FontFallbackList::GlyphPagesStateSaver glyphPagesSaver(*fontList);
+ FontGlyphs* glyph = font.glyphs();
+ ASSERT(glyph);
+ FontGlyphs::GlyphPagesStateSaver glyphPagesSaver(*glyph);
// Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage.
const SimpleFontData* originalFontData = glyphData.fontData;
@@ -230,7 +230,7 @@ GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, co
// No suitable glyph found that is compatible with the requirments (same language, arabic-form, orientation etc.)
// Even though our GlyphPage contains an entry for eg. glyph "a", it's not compatible. So we have to temporarily
// remove the glyph data information from the GlyphPage, and retry the lookup, which handles font fallbacks correctly.
- page->setGlyphDataForCharacter(character, glyphData.glyph, 0);
+ page->setGlyphDataForCharacter(character, 0, 0);
// Assure that the font fallback glyph selection worked, aka. the fallbackGlyphData font data is not the same as before.
GlyphData fallbackGlyphData = font.glyphDataForCharacter(character, mirror);