summaryrefslogtreecommitdiffstats
path: root/WebCore/rendering
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/rendering')
-rw-r--r--WebCore/rendering/EllipsisBox.cpp8
-rw-r--r--WebCore/rendering/HitTestResult.cpp61
-rw-r--r--WebCore/rendering/HitTestResult.h56
-rw-r--r--WebCore/rendering/InlineFlowBox.cpp11
-rw-r--r--WebCore/rendering/InlineTextBox.cpp7
-rw-r--r--WebCore/rendering/RenderBlock.cpp33
-rw-r--r--WebCore/rendering/RenderBox.cpp11
-rw-r--r--WebCore/rendering/RenderForeignObject.cpp10
-rw-r--r--WebCore/rendering/RenderHTMLCanvas.cpp7
-rw-r--r--WebCore/rendering/RenderImage.cpp12
-rw-r--r--WebCore/rendering/RenderLayer.cpp65
-rw-r--r--WebCore/rendering/RenderLayerBacking.cpp16
-rw-r--r--WebCore/rendering/RenderLayerBacking.h2
-rw-r--r--WebCore/rendering/RenderLayerCompositor.cpp7
-rw-r--r--WebCore/rendering/RenderLineBoxList.cpp11
-rw-r--r--WebCore/rendering/RenderMenuList.cpp7
-rw-r--r--WebCore/rendering/RenderMenuList.h2
-rw-r--r--WebCore/rendering/RenderObject.h2
-rw-r--r--WebCore/rendering/RenderPath.cpp48
-rw-r--r--WebCore/rendering/RenderPath.h4
-rw-r--r--WebCore/rendering/RenderSVGBlock.cpp20
-rw-r--r--WebCore/rendering/RenderSVGBlock.h4
-rw-r--r--WebCore/rendering/RenderSVGContainer.cpp16
-rw-r--r--WebCore/rendering/RenderSVGContainer.h2
-rw-r--r--WebCore/rendering/RenderSVGGradientStop.cpp15
-rw-r--r--WebCore/rendering/RenderSVGHiddenContainer.h5
-rw-r--r--WebCore/rendering/RenderSVGImage.cpp29
-rw-r--r--WebCore/rendering/RenderSVGImage.h2
-rw-r--r--WebCore/rendering/RenderSVGInline.cpp19
-rw-r--r--WebCore/rendering/RenderSVGInline.h4
-rw-r--r--WebCore/rendering/RenderSVGModelObject.cpp10
-rw-r--r--WebCore/rendering/RenderSVGModelObject.h1
-rw-r--r--WebCore/rendering/RenderSVGResource.cpp111
-rw-r--r--WebCore/rendering/RenderSVGResource.h9
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.cpp61
-rw-r--r--WebCore/rendering/RenderSVGResourceClipper.h2
-rw-r--r--WebCore/rendering/RenderSVGResourceContainer.cpp169
-rw-r--r--WebCore/rendering/RenderSVGResourceContainer.h32
-rw-r--r--WebCore/rendering/RenderSVGResourceFilter.cpp26
-rw-r--r--WebCore/rendering/RenderSVGResourceGradient.cpp26
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.cpp37
-rw-r--r--WebCore/rendering/RenderSVGResourceMarker.h4
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.cpp40
-rw-r--r--WebCore/rendering/RenderSVGResourceMasker.h2
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.cpp43
-rw-r--r--WebCore/rendering/RenderSVGResourcePattern.h2
-rw-r--r--WebCore/rendering/RenderSVGRoot.cpp35
-rw-r--r--WebCore/rendering/RenderSVGRoot.h4
-rw-r--r--WebCore/rendering/RenderSVGText.cpp10
-rw-r--r--WebCore/rendering/RenderSVGText.h2
-rw-r--r--WebCore/rendering/RenderScrollbar.cpp3
-rw-r--r--WebCore/rendering/RenderScrollbar.h1
-rw-r--r--WebCore/rendering/RenderTable.cpp16
-rw-r--r--WebCore/rendering/RenderTableSection.cpp8
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.cpp17
-rw-r--r--WebCore/rendering/RenderTextControlSingleLine.h3
-rw-r--r--WebCore/rendering/RenderWidget.cpp2
-rw-r--r--WebCore/rendering/SVGInlineTextBox.cpp32
-rw-r--r--WebCore/rendering/SVGInlineTextBox.h4
-rw-r--r--WebCore/rendering/SVGRenderSupport.cpp102
-rw-r--r--WebCore/rendering/SVGRenderSupport.h2
-rw-r--r--WebCore/rendering/SVGRenderTreeAsText.cpp6
-rw-r--r--WebCore/rendering/SVGResources.cpp623
-rw-r--r--WebCore/rendering/SVGResources.h112
-rw-r--r--WebCore/rendering/SVGResourcesCache.cpp12
-rw-r--r--WebCore/rendering/SVGResourcesCycleSolver.cpp28
-rw-r--r--WebCore/rendering/SVGResourcesCycleSolver.h1
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.cpp5
-rw-r--r--WebCore/rendering/style/SVGRenderStyle.h270
-rw-r--r--WebCore/rendering/style/SVGRenderStyleDefs.h40
70 files changed, 1588 insertions, 821 deletions
diff --git a/WebCore/rendering/EllipsisBox.cpp b/WebCore/rendering/EllipsisBox.cpp
index 96efbe2..951df9f 100644
--- a/WebCore/rendering/EllipsisBox.cpp
+++ b/WebCore/rendering/EllipsisBox.cpp
@@ -113,6 +113,7 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
}
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
IntRect boundsRect = IntRect(tx, ty, m_width, m_height);
if (visibleToHitTesting() && result.intersects(x, y, boundsRect)) {
@@ -129,6 +130,13 @@ bool EllipsisBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
#endif
return true;
+=======
+ IntRect boundsRect = IntRect(tx, ty, m_width, m_height);
+ if (visibleToHitTesting() && boundsRect.intersects(result.rectFromPoint(x, y))) {
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+ if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, boundsRect))
+ return true;
+>>>>>>> webkit.org at r64523
}
return false;
diff --git a/WebCore/rendering/HitTestResult.cpp b/WebCore/rendering/HitTestResult.cpp
index 8a4ef3c..e1dfecb 100644
--- a/WebCore/rendering/HitTestResult.cpp
+++ b/WebCore/rendering/HitTestResult.cpp
@@ -49,9 +49,11 @@ using namespace HTMLNames;
HitTestResult::HitTestResult(const IntPoint& point)
: m_point(point)
, m_isOverWidget(false)
+ , m_isRectBased(false)
{
}
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
HitTestResult::HitTestResult(const IntPoint& point, const IntSize& padding)
: m_point(point)
@@ -60,6 +62,17 @@ HitTestResult::HitTestResult(const IntPoint& point, const IntSize& padding)
{
}
#endif
+=======
+HitTestResult::HitTestResult(const IntPoint& centerPoint, const IntSize& padding)
+ : m_point(centerPoint)
+ , m_isOverWidget(false)
+{
+ // If a zero padding is passed in or either width or height is negative, then it
+ // is not a valid padding and hence not a rect based hit test.
+ m_isRectBased = !(padding.isZero() || (padding.width() < 0 || padding.height() < 0));
+ m_padding = m_isRectBased ? padding : IntSize();
+}
+>>>>>>> webkit.org at r64523
HitTestResult::HitTestResult(const HitTestResult& other)
: m_innerNode(other.innerNode())
@@ -74,6 +87,12 @@ HitTestResult::HitTestResult(const HitTestResult& other)
, m_rawNodeList(other.rawNodeList())
#endif
{
+ // Only copy the padding and ListHashSet in case of rect hit test.
+ // Copying the later is rather expensive.
+ if ((m_isRectBased = other.isRectBasedTest())) {
+ m_padding = other.padding();
+ m_rectBasedTestResult = other.rectBasedTestResult();
+ }
}
HitTestResult::~HitTestResult()
@@ -89,10 +108,19 @@ HitTestResult& HitTestResult::operator=(const HitTestResult& other)
m_innerURLElement = other.URLElement();
m_scrollbar = other.scrollbar();
m_isOverWidget = other.isOverWidget();
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
m_pointPadding = other.pointPadding();
m_rawNodeList = other.rawNodeList();
#endif
+=======
+ // Only copy the padding and ListHashSet in case of rect hit test.
+ // Copying the later is rather expensive.
+ if ((m_isRectBased = other.isRectBasedTest())) {
+ m_padding = other.padding();
+ m_rectBasedTestResult = other.rectBasedTestResult();
+ }
+>>>>>>> webkit.org at r64523
return *this;
}
@@ -379,6 +407,7 @@ bool HitTestResult::isContentEditable() const
return m_innerNonSharedNode->isContentEditable();
}
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
bool HitTestResult::intersects(int x, int y, const IntRect& other) const
@@ -395,6 +424,29 @@ bool HitTestResult::containedBy(int x, int y, const IntRect& other) const
void HitTestResult::merge(const HitTestResult& other)
{
+=======
+bool HitTestResult::addNodeToRectBasedTestResult(Node* node, int x, int y, const IntRect& rect)
+{
+ // If it is not a rect-based hit test, this method has to be no-op.
+ // Return false, so the hit test stops.
+ if (!isRectBasedTest())
+ return false;
+
+ // If node is null, return true so the hit test can continue.
+ if (!node)
+ return true;
+
+ node = node->shadowAncestorNode();
+ m_rectBasedTestResult.add(node);
+
+ return !rect.contains(rectFromPoint(x, y));
+}
+
+void HitTestResult::append(const HitTestResult& other)
+{
+ ASSERT(isRectBasedTest() && other.isRectBasedTest());
+
+>>>>>>> webkit.org at r64523
if (!m_innerNode && other.innerNode()) {
m_innerNode = other.innerNode();
m_innerNonSharedNode = other.innerNonSharedNode();
@@ -404,6 +456,7 @@ void HitTestResult::merge(const HitTestResult& other)
m_isOverWidget = other.isOverWidget();
}
+<<<<<<< HEAD
const Vector<RefPtr<Node> >& list = other.rawNodeList();
Vector<RefPtr<Node> >::const_iterator last = list.end();
for (Vector<RefPtr<Node> >::const_iterator it = list.begin(); it != last; ++it)
@@ -425,4 +478,12 @@ void HitTestResult::addRawNode(Node* node)
#endif // ANDROID_HITTEST_WITHSIZE
+=======
+ const ListHashSet<RefPtr<Node> >& list = other.rectBasedTestResult();
+ ListHashSet<RefPtr<Node> >::const_iterator last = list.end();
+ for (ListHashSet<RefPtr<Node> >::const_iterator it = list.begin(); it != last; ++it)
+ m_rectBasedTestResult.add(it->get());
+}
+
+>>>>>>> webkit.org at r64523
} // namespace WebCore
diff --git a/WebCore/rendering/HitTestResult.h b/WebCore/rendering/HitTestResult.h
index 0f45900..6d39e8d 100644
--- a/WebCore/rendering/HitTestResult.h
+++ b/WebCore/rendering/HitTestResult.h
@@ -21,11 +21,17 @@
#define HitTestResult_h
#include "IntPoint.h"
+#include "IntRect.h"
+#include "IntSize.h"
#include "TextDirection.h"
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
#include <IntSize.h>
#include <wtf/Vector.h>
#endif
+=======
+#include <wtf/ListHashSet.h>
+>>>>>>> webkit.org at r64523
#include <wtf/RefPtr.h>
namespace WebCore {
@@ -42,6 +48,8 @@ class String;
class HitTestResult {
public:
HitTestResult(const IntPoint&);
+ // Pass a non-negative IntSize value as padding to perform a rect-based hit test.
+ HitTestResult(const IntPoint& centerPoint, const IntSize& padding);
HitTestResult(const HitTestResult&);
~HitTestResult();
HitTestResult& operator=(const HitTestResult&);
@@ -80,6 +88,7 @@ public:
bool isLiveLink() const;
bool isContentEditable() const;
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
HitTestResult(const IntPoint&, const IntSize&);
@@ -92,8 +101,23 @@ public:
void addRawNode(Node*);
const Vector<RefPtr<Node> >& rawNodeList() const { return m_rawNodeList; }
#endif
+=======
+ // Rect-based hit test related methods.
+ bool isRectBasedTest() const { return m_isRectBased; }
+ IntRect rectFromPoint(int x, int y) const;
+ IntRect rectFromPoint(const IntPoint&) const;
+ IntSize padding() const { return m_padding; }
+ int paddingWidth() const { return m_padding.width() >= 0 ? m_padding.width() : 0; }
+ int paddingHeight() const { return m_padding.height() >= 0 ? m_padding.height() : 0; }
+ // Returns true if it is rect-based hit test and needs to continue until the rect is fully
+ // enclosed by the boundaries of a node.
+ bool addNodeToRectBasedTestResult(Node*, int x, int y, const IntRect& rect = IntRect());
+ const ListHashSet<RefPtr<Node> >& rectBasedTestResult() const { return m_rectBasedTestResult; }
+ void append(const HitTestResult&);
+>>>>>>> webkit.org at r64523
private:
+
RefPtr<Node> m_innerNode;
RefPtr<Node> m_innerNonSharedNode;
IntPoint m_point;
@@ -102,13 +126,45 @@ private:
RefPtr<Element> m_innerURLElement;
RefPtr<Scrollbar> m_scrollbar;
bool m_isOverWidget; // Returns true if we are over a widget (and not in the border/padding area of a RenderWidget for example).
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
IntSize m_pointPadding;
Vector<RefPtr<Node> > m_rawNodeList;
#endif
+=======
+ bool m_isRectBased;
+ IntSize m_padding;
+ ListHashSet<RefPtr<Node> > m_rectBasedTestResult;
+>>>>>>> webkit.org at r64523
};
+inline IntRect HitTestResult::rectFromPoint(int x, int y) const
+{
+ return rectFromPoint(IntPoint(x, y));
+}
+
+// Formula:
+// x = p.x() - padding.width()
+// y = p.y() - padding.height()
+// width = 2 * padding.width() + 1
+// height = 2 * m_padding.height() + 1
+inline IntRect HitTestResult::rectFromPoint(const IntPoint& point) const
+{
+ IntPoint realPoint(point);
+ IntSize realPadding(m_padding);
+
+ // Real IntPoint for the rect.
+ realPadding.clampNegativeToZero();
+ realPoint -= realPadding;
+
+ // Real IntSize for the rect.
+ realPadding.scale(2);
+ realPadding += IntSize(1, 1);
+
+ return IntRect(realPoint, realPadding);
+}
+
String displayString(const String&, const Node*);
} // namespace WebCore
diff --git a/WebCore/rendering/InlineFlowBox.cpp b/WebCore/rendering/InlineFlowBox.cpp
index 8ac8c40..daa48f2 100644
--- a/WebCore/rendering/InlineFlowBox.cpp
+++ b/WebCore/rendering/InlineFlowBox.cpp
@@ -611,11 +611,15 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
{
IntRect overflowRect(visibleOverflowRect());
overflowRect.move(tx, ty);
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (!result.intersects(x, y, overflowRect))
#else
if (!overflowRect.contains(x, y))
#endif
+=======
+ if (!overflowRect.intersects(result.rectFromPoint(x, y)))
+>>>>>>> webkit.org at r64523
return false;
// Check children first.
@@ -628,6 +632,7 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
// Now check ourselves.
IntRect rect(tx + m_x, ty + m_y, m_width, height());
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (visibleToHitTesting() && result.intersects(x, y, rect)) {
#else
@@ -643,6 +648,12 @@ bool InlineFlowBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
}
#endif
return true;
+=======
+ if (visibleToHitTesting() && rect.intersects(result.rectFromPoint(x, y))) {
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty)); // Don't add in m_x or m_y here, we want coords in the containing block's space.
+ if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, rect))
+ return true;
+>>>>>>> webkit.org at r64523
}
return false;
diff --git a/WebCore/rendering/InlineTextBox.cpp b/WebCore/rendering/InlineTextBox.cpp
index d6bd70c..b0e2887 100644
--- a/WebCore/rendering/InlineTextBox.cpp
+++ b/WebCore/rendering/InlineTextBox.cpp
@@ -287,6 +287,7 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
return false;
IntRect rect(tx + m_x, ty + m_y, m_width, height());
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (m_truncation != cFullTruncation && visibleToHitTesting() && result.intersects(x, y, rect)) {
#else
@@ -302,6 +303,12 @@ bool InlineTextBox::nodeAtPoint(const HitTestRequest&, HitTestResult& result, in
}
#endif
return true;
+=======
+ if (m_truncation != cFullTruncation && visibleToHitTesting() && rect.intersects(result.rectFromPoint(x, y))) {
+ renderer()->updateHitTestResult(result, IntPoint(x - tx, y - ty));
+ if (!result.addNodeToRectBasedTestResult(renderer()->node(), x, y, rect))
+ return true;
+>>>>>>> webkit.org at r64523
}
return false;
}
diff --git a/WebCore/rendering/RenderBlock.cpp b/WebCore/rendering/RenderBlock.cpp
index 1b855d4..3f369c3 100644
--- a/WebCore/rendering/RenderBlock.cpp
+++ b/WebCore/rendering/RenderBlock.cpp
@@ -3767,16 +3767,21 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Check if we need to do anything at all.
IntRect overflowBox = visibleOverflowRect();
overflowBox.move(tx, ty);
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (!result.intersects(_x, _y, overflowBox))
#else
if (!overflowBox.contains(_x, _y))
#endif
+=======
+ if (!overflowBox.intersects(result.rectFromPoint(_x, _y)))
+>>>>>>> webkit.org at r64523
return false;
}
if ((hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) && isPointInOverflowControl(result, _x, _y, tx, ty)) {
updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
// TODO: isPointInOverflowControl() doesn't handle region test yet.
if (result.isRegionTest()) {
@@ -3785,16 +3790,26 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
} else
#endif
return true;
+=======
+ // FIXME: isPointInOverflowControl() doesn't handle rect-based tests yet.
+ if (!result.addNodeToRectBasedTestResult(node(), _x, _y))
+ return true;
+>>>>>>> webkit.org at r64523
}
// If we have clipping, then we can't have any spillout.
bool useOverflowClip = hasOverflowClip() && !hasSelfPaintingLayer();
bool useClip = (hasControlClip() || useOverflowClip);
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
bool checkChildren = !useClip || (hasControlClip() ? result.intersects(_x, _y, controlClipRect(tx, ty)) : result.intersects(_x, _y, overflowClipRect(tx, ty)));
#else
bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).contains(_x, _y) : overflowClipRect(tx, ty).contains(_x, _y));
#endif
+=======
+ IntRect hitTestArea(result.rectFromPoint(_x, _y));
+ bool checkChildren = !useClip || (hasControlClip() ? controlClipRect(tx, ty).intersects(hitTestArea) : overflowClipRect(tx, ty).intersects(hitTestArea));
+>>>>>>> webkit.org at r64523
if (checkChildren) {
// Hit test descendants first.
int scrolledX = tx;
@@ -3842,6 +3857,7 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
// Now hit test our background
if (hitTestAction == HitTestBlockBackground || hitTestAction == HitTestChildBlockBackground) {
IntRect boundsRect(tx, ty, width(), height());
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (visibleToHitTesting() && result.intersects(_x, _y, boundsRect)) {
#else
@@ -3857,6 +3873,12 @@ bool RenderBlock::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
#endif
return true;
+=======
+ if (visibleToHitTesting() && boundsRect.intersects(result.rectFromPoint(_x, _y))) {
+ updateHitTestResult(result, IntPoint(_x - tx, _y - ty));
+ if (!result.addNodeToRectBasedTestResult(node(), _x, _y, boundsRect))
+ return true;
+>>>>>>> webkit.org at r64523
}
}
@@ -3881,22 +3903,33 @@ bool RenderBlock::hitTestColumns(const HitTestRequest& request, HitTestResult& r
currYOffset += colRect.height();
colRect.move(tx, ty);
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (result.intersects(x, y, colRect)) {
#else
if (colRect.contains(x, y)) {
#endif
+=======
+ if (colRect.intersects(result.rectFromPoint(x, y))) {
+>>>>>>> webkit.org at r64523
// The point is inside this column.
// Adjust tx and ty to change where we hit test.
int finalX = tx + currXOffset;
int finalY = ty + currYOffset;
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (result.isRegionTest() && !result.containedBy(x, y, colRect))
hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
else
#endif
return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
+=======
+ if (result.isRectBasedTest() && !colRect.contains(result.rectFromPoint(x, y)))
+ hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
+ else
+ return hitTestContents(request, result, x, y, finalX, finalY, hitTestAction);
+>>>>>>> webkit.org at r64523
}
}
diff --git a/WebCore/rendering/RenderBox.cpp b/WebCore/rendering/RenderBox.cpp
index 2deeffc..b546893 100644
--- a/WebCore/rendering/RenderBox.cpp
+++ b/WebCore/rendering/RenderBox.cpp
@@ -31,6 +31,7 @@
#include "Document.h"
#include "FrameView.h"
#include "GraphicsContext.h"
+#include "HitTestResult.h"
#include "htmlediting.h"
#include "HTMLElement.h"
#include "HTMLNames.h"
@@ -568,6 +569,7 @@ bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
#else
// Check our bounds next. For this purpose always assume that we can only be hit in the
// foreground phase (which is true for replaced elements like images).
+<<<<<<< HEAD
if (visibleToHitTesting() && action == HitTestForeground && IntRect(tx, ty, width(), height()).contains(xPos, yPos)) {
#endif
updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
@@ -580,6 +582,13 @@ bool RenderBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result
}
#endif
return true;
+=======
+ IntRect boundsRect = IntRect(tx, ty, width(), height());
+ if (visibleToHitTesting() && action == HitTestForeground && boundsRect.intersects(result.rectFromPoint(xPos, yPos))) {
+ updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ if (!result.addNodeToRectBasedTestResult(node(), xPos, yPos, boundsRect))
+ return true;
+>>>>>>> webkit.org at r64523
}
return false;
@@ -1595,7 +1604,7 @@ void RenderBox::calcHeight()
&& (isRoot() || (isBody() && document()->documentElement()->renderer()->style()->height().isPercent()));
if (stretchesToViewHeight() || printingNeedsBaseHeight) {
int margins = collapsedMarginTop() + collapsedMarginBottom();
- int visHeight = document()->printing() ? view()->frameView()->visibleHeight() : view()->viewHeight();
+ int visHeight = document()->printing() ? view()->frameView()->pageHeight() : view()->viewHeight();
if (isRoot())
setHeight(max(height(), visHeight - margins));
else {
diff --git a/WebCore/rendering/RenderForeignObject.cpp b/WebCore/rendering/RenderForeignObject.cpp
index 8b84f97..50c1a42 100644
--- a/WebCore/rendering/RenderForeignObject.cpp
+++ b/WebCore/rendering/RenderForeignObject.cpp
@@ -117,14 +117,16 @@ void RenderForeignObject::layout()
// FIXME: Investigate in location rounding issues - only affects RenderForeignObject & RenderSVGText
setLocation(roundedIntPoint(viewportLocation));
+
+ bool layoutChanged = m_everHadLayout && selfNeedsLayout();
RenderBlock::layout();
+ ASSERT(!needsLayout());
- // Invalidate all resources of this client, if we changed something.
- if (m_everHadLayout && selfNeedsLayout())
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+ // Invalidate all resources of this client if our layout changed.
+ if (layoutChanged)
+ SVGResourcesCache::clientLayoutChanged(this);
repainter.repaintAfterLayout();
- setNeedsLayout(false);
}
bool RenderForeignObject::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
diff --git a/WebCore/rendering/RenderHTMLCanvas.cpp b/WebCore/rendering/RenderHTMLCanvas.cpp
index 8c17a0e..c89495b 100644
--- a/WebCore/rendering/RenderHTMLCanvas.cpp
+++ b/WebCore/rendering/RenderHTMLCanvas.cpp
@@ -26,6 +26,7 @@
#include "config.h"
#include "RenderHTMLCanvas.h"
+#include "CanvasRenderingContext.h"
#include "Document.h"
#include "GraphicsContext.h"
#include "HTMLCanvasElement.h"
@@ -48,12 +49,8 @@ bool RenderHTMLCanvas::requiresLayer() const
if (RenderReplaced::requiresLayer())
return true;
-#if ENABLE(3D_CANVAS)
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(node());
- return canvas && canvas->is3D();
-#else
- return false;
-#endif
+ return canvas && canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
}
void RenderHTMLCanvas::paintReplaced(PaintInfo& paintInfo, int tx, int ty)
diff --git a/WebCore/rendering/RenderImage.cpp b/WebCore/rendering/RenderImage.cpp
index 643fac9..3612ed5 100644
--- a/WebCore/rendering/RenderImage.cpp
+++ b/WebCore/rendering/RenderImage.cpp
@@ -387,6 +387,7 @@ HTMLMapElement* RenderImage::imageMap() const
bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, int x, int y, int tx, int ty, HitTestAction hitTestAction)
{
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
HitTestResult tempResult(result.point(), result.pointPadding());
#else
@@ -399,6 +400,12 @@ bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
#else
if (inside && node()) {
#endif
+=======
+ HitTestResult tempResult(result.point(), result.padding());
+ bool inside = RenderReplaced::nodeAtPoint(request, tempResult, x, y, tx, ty, hitTestAction);
+
+ if (tempResult.innerNode() && node()) {
+>>>>>>> webkit.org at r64523
if (HTMLMapElement* map = imageMap()) {
IntRect contentBox = contentBoxRect();
float zoom = style()->effectiveZoom();
@@ -409,10 +416,15 @@ bool RenderImage::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
}
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (!inside && result.isRegionTest())
result.merge(tempResult);
#endif
+=======
+ if (!inside && result.isRectBasedTest())
+ result.append(tempResult);
+>>>>>>> webkit.org at r64523
if (inside)
result = tempResult;
return inside;
diff --git a/WebCore/rendering/RenderLayer.cpp b/WebCore/rendering/RenderLayer.cpp
index 756a9b3..998ffa7 100644
--- a/WebCore/rendering/RenderLayer.cpp
+++ b/WebCore/rendering/RenderLayer.cpp
@@ -1800,6 +1800,9 @@ void RenderLayer::destroyScrollbar(ScrollbarOrientation orientation)
{
RefPtr<Scrollbar>& scrollbar = orientation == HorizontalScrollbar ? m_hBar : m_vBar;
if (scrollbar) {
+ if (scrollbar->isCustomScrollbar())
+ static_cast<RenderScrollbar*>(scrollbar.get())->clearOwningRenderer();
+
scrollbar->removeFromParent();
scrollbar->setClient(0);
scrollbar = 0;
@@ -2749,18 +2752,24 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
#if USE(ACCELERATED_COMPOSITING)
useTemporaryClipRects = compositor()->inCompositingMode();
#endif
-
+
+ IntRect hitTestArea = result.rectFromPoint(hitTestPoint);
+
// Apply a transform if we have one.
if (transform() && !appliedTransform) {
// Make sure the parent's clip rects have been calculated.
if (parent()) {
IntRect clipRect = backgroundClipRect(rootLayer, useTemporaryClipRects);
// Go ahead and test the enclosing clip now.
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (!result.intersects(hitTestPoint.x(), hitTestPoint.y(), clipRect))
#else
if (!clipRect.contains(hitTestPoint))
#endif
+=======
+ if (!clipRect.intersects(hitTestArea))
+>>>>>>> webkit.org at r64523
return 0;
}
@@ -2873,6 +2882,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
}
// Next we want to see if the mouse pos is inside the child RenderObjects of the layer.
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (result.intersects(hitTestPoint.x(), hitTestPoint.y(), fgRect) && isSelfPaintingLayer()) {
#else
@@ -2892,15 +2902,31 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
else
#endif
result = tempResult;
+=======
+ if (fgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
+ // Hit test with a temporary HitTestResult, because we only want to commit to 'result' if we know we're frontmost.
+ HitTestResult tempResult(result.point(), result.padding());
+ if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestDescendants) &&
+ isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
+ if (result.isRectBasedTest())
+ result.append(tempResult);
+ else
+ result = tempResult;
+>>>>>>> webkit.org at r64523
if (!depthSortDescendants)
return this;
// Foreground can depth-sort with descendant layers, so keep this as a candidate.
candidateLayer = this;
+<<<<<<< HEAD
}
#ifdef ANDROID_HITTEST_WITHSIZE
else if (result.isRegionTest())
result.merge(tempResult);
#endif
+=======
+ } else if (result.isRectBasedTest())
+ result.append(tempResult);
+>>>>>>> webkit.org at r64523
}
// Now check our negative z-index children.
@@ -2916,6 +2942,7 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
if (candidateLayer)
return candidateLayer;
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (result.intersects(hitTestPoint.x(), hitTestPoint.y(), bgRect) && isSelfPaintingLayer()) {
HitTestResult tempResult(result.point(), result.pointPadding());
@@ -2937,6 +2964,19 @@ RenderLayer* RenderLayer::hitTestLayer(RenderLayer* rootLayer, RenderLayer* cont
else if (result.isRegionTest())
result.merge(tempResult);
#endif
+=======
+ if (bgRect.intersects(hitTestArea) && isSelfPaintingLayer()) {
+ HitTestResult tempResult(result.point(), result.padding());
+ if (hitTestContents(request, tempResult, layerBounds, hitTestPoint, HitTestSelf) &&
+ isHitCandidate(this, false, zOffsetForContentsPtr, unflattenedTransformState.get())) {
+ if (result.isRectBasedTest())
+ result.append(tempResult);
+ else
+ result = tempResult;
+ return this;
+ } else if (result.isRectBasedTest())
+ result.append(tempResult);
+>>>>>>> webkit.org at r64523
}
return 0;
@@ -2948,8 +2988,9 @@ bool RenderLayer::hitTestContents(const HitTestRequest& request, HitTestResult&
layerBounds.x() - renderBoxX(),
layerBounds.y() - renderBoxY(),
hitTestFilter)) {
- // It's wrong to set innerNode, but then claim that you didn't hit anything.
- ASSERT(!result.innerNode());
+ // It's wrong to set innerNode, but then claim that you didn't hit anything, unless it is
+ // a rect-based test.
+ ASSERT(!result.innerNode() || (result.isRectBasedTest() && result.rectBasedTestResult().size()));
return false;
}
@@ -2983,25 +3024,39 @@ RenderLayer* RenderLayer::hitTestList(Vector<RenderLayer*>* list, RenderLayer* r
for (int i = list->size() - 1; i >= 0; --i) {
RenderLayer* childLayer = list->at(i);
RenderLayer* hitLayer = 0;
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
HitTestResult tempResult(result.point(), result.pointPadding());
#else
HitTestResult tempResult(result.point());
#endif
+=======
+ HitTestResult tempResult(result.point(), result.padding());
+>>>>>>> webkit.org at r64523
if (childLayer->isPaginated())
hitLayer = hitTestPaginatedChildLayer(childLayer, rootLayer, request, tempResult, hitTestRect, hitTestPoint, transformState, zOffsetForDescendants);
else
hitLayer = childLayer->hitTestLayer(rootLayer, this, request, tempResult, hitTestRect, hitTestPoint, false, transformState, zOffsetForDescendants);
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (result.isRegionTest())
result.merge(tempResult);
#endif
+=======
+
+ // If it a rect-based test, we can safely append the temporary result since it might had hit
+ // nodes but not necesserily had hitLayer set.
+ if (result.isRectBasedTest())
+ result.append(tempResult);
+
+>>>>>>> webkit.org at r64523
if (isHitCandidate(hitLayer, depthSortDescendants, zOffset, unflattenedTransformState)) {
#ifdef ANDROID_HITTEST_WITHSIZE
if (!result.isRegionTest())
#endif
resultLayer = hitLayer;
- result = tempResult;
+ if (!result.isRectBasedTest())
+ result = tempResult;
if (!depthSortDescendants)
break;
}
@@ -3061,7 +3116,7 @@ RenderLayer* RenderLayer::hitTestChildLayerColumns(RenderLayer* childLayer, Rend
IntRect localClipRect(hitTestRect);
localClipRect.intersect(colRect);
- if (!localClipRect.isEmpty() && localClipRect.contains(hitTestPoint)) {
+ if (!localClipRect.isEmpty() && localClipRect.intersects(result.rectFromPoint(hitTestPoint))) {
RenderLayer* hitLayer = 0;
if (!columnIndex) {
// Apply a translation transform to change where the layer paints.
diff --git a/WebCore/rendering/RenderLayerBacking.cpp b/WebCore/rendering/RenderLayerBacking.cpp
index d66dfc2..e1cf2a2 100644
--- a/WebCore/rendering/RenderLayerBacking.cpp
+++ b/WebCore/rendering/RenderLayerBacking.cpp
@@ -666,6 +666,9 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
if (hasBoxDecorationsOrBackground(renderObject))
return false;
+ if (m_owningLayer->hasOverflowControls())
+ return false;
+
// If we have got this far and the renderer has no children, then we're ok.
if (!renderObject->firstChild())
return true;
@@ -694,26 +697,23 @@ bool RenderLayerBacking::isSimpleContainerCompositingLayer() const
if (hasBoxDecorationsOrBackgroundImage(style))
return false;
- // Ceck to see if all the body's children are compositing layers.
- if (hasNonCompositingContent())
+ // Check to see if all the body's children are compositing layers.
+ if (hasNonCompositingDescendants())
return false;
return true;
}
// Check to see if all the renderer's children are compositing layers.
- if (hasNonCompositingContent())
+ if (hasNonCompositingDescendants())
return false;
return true;
}
// Conservative test for having no rendered children.
-bool RenderLayerBacking::hasNonCompositingContent() const
+bool RenderLayerBacking::hasNonCompositingDescendants() const
{
- if (m_owningLayer->hasOverflowControls())
- return true;
-
// Some HTML can cause whitespace text nodes to have renderers, like:
// <div>
// <img src=...>
@@ -911,7 +911,7 @@ FloatPoint RenderLayerBacking::contentsToGraphicsLayerCoordinates(const Graphics
bool RenderLayerBacking::paintingGoesToWindow() const
{
if (m_owningLayer->isRootLayer())
- return compositor()->rootLayerAttachment() == RenderLayerCompositor::RootLayerAttachedViaChromeClient;
+ return compositor()->rootLayerAttachment() != RenderLayerCompositor::RootLayerAttachedViaEnclosingIframe;
return false;
}
diff --git a/WebCore/rendering/RenderLayerBacking.h b/WebCore/rendering/RenderLayerBacking.h
index 852fc04..808000b 100644
--- a/WebCore/rendering/RenderLayerBacking.h
+++ b/WebCore/rendering/RenderLayerBacking.h
@@ -173,7 +173,7 @@ private:
bool rendererHasBackground() const;
const Color rendererBackgroundColor() const;
- bool hasNonCompositingContent() const;
+ bool hasNonCompositingDescendants() const;
void paintIntoLayer(RenderLayer* rootLayer, GraphicsContext*, const IntRect& paintDirtyRect,
PaintBehavior paintBehavior, GraphicsLayerPaintingPhase, RenderObject* paintingRoot);
diff --git a/WebCore/rendering/RenderLayerCompositor.cpp b/WebCore/rendering/RenderLayerCompositor.cpp
index 3d16864..b60dec9 100644
--- a/WebCore/rendering/RenderLayerCompositor.cpp
+++ b/WebCore/rendering/RenderLayerCompositor.cpp
@@ -29,6 +29,7 @@
#include "RenderLayerCompositor.h"
#include "AnimationController.h"
+#include "CanvasRenderingContext.h"
#include "CSSPropertyNames.h"
#include "Chrome.h"
#include "ChromeClient.h"
@@ -1271,14 +1272,10 @@ bool RenderLayerCompositor::requiresCompositingForVideo(RenderObject* renderer)
bool RenderLayerCompositor::requiresCompositingForCanvas(RenderObject* renderer) const
{
-#if ENABLE(3D_CANVAS)
if (renderer->isCanvas()) {
HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(renderer->node());
- return canvas->is3D();
+ return canvas->renderingContext() && canvas->renderingContext()->isAccelerated();
}
-#else
- UNUSED_PARAM(renderer);
-#endif
return false;
}
diff --git a/WebCore/rendering/RenderLineBoxList.cpp b/WebCore/rendering/RenderLineBoxList.cpp
index 3e4c882..06aab89 100644
--- a/WebCore/rendering/RenderLineBoxList.cpp
+++ b/WebCore/rendering/RenderLineBoxList.cpp
@@ -29,6 +29,7 @@
#include "config.h"
#include "RenderLineBoxList.h"
+#include "HitTestResult.h"
#include "InlineTextBox.h"
#ifdef ANDROID_HITTEST_WITHSIZE
#include "HitTestResult.h"
@@ -248,22 +249,32 @@ bool RenderLineBoxList::hitTest(RenderBoxModelObject* renderer, const HitTestReq
// contain the point. This is a quick short-circuit that we can take to avoid walking any lines.
// FIXME: This check is flawed in the following extremely obscure way:
// if some line in the middle has a huge overflow, it might actually extend below the last line.
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if ((y - result.pointPadding().height() >= ty + lastLineBox()->root()->bottomVisibleOverflow()) || (y + result.pointPadding().height() < ty + firstLineBox()->root()->topVisibleOverflow()))
#else
if ((y >= ty + lastLineBox()->root()->bottomVisibleOverflow()) || (y < ty + firstLineBox()->root()->topVisibleOverflow()))
#endif
+=======
+ if (y - result.paddingHeight() >= ty + lastLineBox()->root()->bottomVisibleOverflow()
+ || y + result.paddingHeight() < ty + firstLineBox()->root()->topVisibleOverflow())
+>>>>>>> webkit.org at r64523
return false;
// See if our root lines contain the point. If so, then we hit test
// them further. Note that boxes can easily overlap, so we can't make any assumptions
// based off positions of our first line box or our last line box.
for (InlineFlowBox* curr = lastLineBox(); curr; curr = curr->prevLineBox()) {
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (y + result.pointPadding().height() >= ty + curr->root()->topVisibleOverflow() && y - result.pointPadding().height() < ty + curr->root()->bottomVisibleOverflow()) {
#else
if (y >= ty + curr->root()->topVisibleOverflow() && y < ty + curr->root()->bottomVisibleOverflow()) {
#endif
+=======
+ if (y + result.paddingHeight() >= ty + curr->root()->topVisibleOverflow()
+ && y - result.paddingHeight() < ty + curr->root()->bottomVisibleOverflow()) {
+>>>>>>> webkit.org at r64523
bool inside = curr->nodeAtPoint(request, result, x, y, tx, ty);
if (inside) {
renderer->updateHitTestResult(result, IntPoint(x - tx, y - ty));
diff --git a/WebCore/rendering/RenderMenuList.cpp b/WebCore/rendering/RenderMenuList.cpp
index ff16e7e..b6a97a9 100644
--- a/WebCore/rendering/RenderMenuList.cpp
+++ b/WebCore/rendering/RenderMenuList.cpp
@@ -26,6 +26,7 @@
#include "RenderMenuList.h"
#include "AXObjectCache.h"
+#include "Chrome.h"
#include "CSSStyleSelector.h"
#include "Frame.h"
#include "FrameView.h"
@@ -88,8 +89,8 @@ void RenderMenuList::adjustInnerStyle()
m_innerBlock->style()->setPaddingRight(Length(theme()->popupInternalPaddingRight(style()), Fixed));
m_innerBlock->style()->setPaddingTop(Length(theme()->popupInternalPaddingTop(style()), Fixed));
m_innerBlock->style()->setPaddingBottom(Length(theme()->popupInternalPaddingBottom(style()), Fixed));
-
- if (PopupMenu::itemWritingDirectionIsNatural()) {
+
+ if (document()->page()->chrome()->selectItemWritingDirectionIsNatural()) {
// Items in the popup will not respect the CSS text-align and direction properties,
// so we must adjust our own style to match.
m_innerBlock->style()->setTextAlign(LEFT);
@@ -278,7 +279,7 @@ void RenderMenuList::showPopup()
// inside the showPopup call and it would fail.
createInnerBlock();
if (!m_popup)
- m_popup = PopupMenu::create(this);
+ m_popup = document()->page()->chrome()->createPopupMenu(this);
SelectElement* select = toSelectElement(static_cast<Element*>(node()));
m_popupIsVisible = true;
diff --git a/WebCore/rendering/RenderMenuList.h b/WebCore/rendering/RenderMenuList.h
index aef8d4f..512fa9b 100644
--- a/WebCore/rendering/RenderMenuList.h
+++ b/WebCore/rendering/RenderMenuList.h
@@ -24,6 +24,7 @@
#ifndef RenderMenuList_h
#define RenderMenuList_h
+#include "PopupMenu.h"
#include "PopupMenuClient.h"
#include "RenderFlexibleBox.h"
@@ -35,7 +36,6 @@
namespace WebCore {
-class PopupMenu;
class RenderText;
#if ENABLE(NO_LISTBOX_RENDERING)
diff --git a/WebCore/rendering/RenderObject.h b/WebCore/rendering/RenderObject.h
index 3f78e45..46169d0 100644
--- a/WebCore/rendering/RenderObject.h
+++ b/WebCore/rendering/RenderObject.h
@@ -38,7 +38,7 @@
#include "TransformationMatrix.h"
#include <wtf/UnusedParam.h>
-#if PLATFORM(CG)
+#if PLATFORM(CG) || PLATFORM(CAIRO)
#define HAVE_PATH_BASED_BORDER_RADIUS_DRAWING 1
#endif
diff --git a/WebCore/rendering/RenderPath.cpp b/WebCore/rendering/RenderPath.cpp
index dd79397..915be5d 100644
--- a/WebCore/rendering/RenderPath.cpp
+++ b/WebCore/rendering/RenderPath.cpp
@@ -35,11 +35,12 @@
#include "PointerEventsHitRules.h"
#include "RenderSVGContainer.h"
#include "RenderSVGResourceMarker.h"
-#include "StrokeStyleApplier.h"
#include "SVGRenderSupport.h"
+#include "SVGResources.h"
#include "SVGStyledTransformableElement.h"
#include "SVGTransformList.h"
#include "SVGURIReference.h"
+#include "StrokeStyleApplier.h"
#include <wtf/MathExtras.h>
namespace WebCore {
@@ -72,7 +73,7 @@ RenderPath::RenderPath(SVGStyledTransformableElement* node)
{
}
-bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill, WindRule fillRule) const
+bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill, WindRule fillRule)
{
if (!m_fillBoundingBox.contains(point))
return false;
@@ -83,7 +84,7 @@ bool RenderPath::fillContains(const FloatPoint& point, bool requiresFill, WindRu
return m_path.contains(point, fillRule);
}
-bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke) const
+bool RenderPath::strokeContains(const FloatPoint& point, bool requiresStroke)
{
if (!m_strokeAndMarkerBoundingBox.contains(point))
return false;
@@ -111,9 +112,9 @@ void RenderPath::layout()
m_needsTransformUpdate = false;
}
- // Invalidate all resources of this client, if we changed something.
+ // Invalidate all resources of this client if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+ SVGResourcesCache::clientLayoutChanged(this);
// At this point LayoutRepainter already grabbed the old bounds,
// recalculate them now so repaintAfterLayout() uses the new bounds
@@ -234,8 +235,6 @@ bool RenderPath::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult&
FloatRect RenderPath::calculateMarkerBoundsIfNeeded()
{
- Document* doc = document();
-
SVGElement* svgElement = static_cast<SVGElement*>(node());
ASSERT(svgElement && svgElement->document());
if (!svgElement->isStyled())
@@ -248,39 +247,24 @@ FloatRect RenderPath::calculateMarkerBoundsIfNeeded()
const SVGRenderStyle* svgStyle = style()->svgStyle();
ASSERT(svgStyle->hasMarkers());
- AtomicString startMarkerId(svgStyle->markerStartResource());
- AtomicString midMarkerId(svgStyle->markerMidResource());
- AtomicString endMarkerId(svgStyle->markerEndResource());
-
- RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, startMarkerId);
- RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, midMarkerId);
- RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(doc, endMarkerId);
-
- if (!startMarker && !startMarkerId.isEmpty())
- svgElement->document()->accessSVGExtensions()->addPendingResource(startMarkerId, styledElement);
- else if (startMarker)
- startMarker->addClient(this);
-
- if (!midMarker && !midMarkerId.isEmpty())
- svgElement->document()->accessSVGExtensions()->addPendingResource(midMarkerId, styledElement);
- else if (midMarker)
- midMarker->addClient(this);
-
- if (!endMarker && !endMarkerId.isEmpty())
- svgElement->document()->accessSVGExtensions()->addPendingResource(endMarkerId, styledElement);
- else if (endMarker)
- endMarker->addClient(this);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
+ if (!resources)
+ return FloatRect();
- if (!startMarker && !midMarker && !endMarker)
+ RenderSVGResourceMarker* markerStart = resources->markerStart();
+ RenderSVGResourceMarker* markerMid = resources->markerMid();
+ RenderSVGResourceMarker* markerEnd = resources->markerEnd();
+ if (!markerStart && !markerMid && !markerEnd)
return FloatRect();
float strokeWidth = SVGRenderStyle::cssPrimitiveToLength(this, svgStyle->strokeWidth(), 1.0f);
- return m_markerLayoutInfo.calculateBoundaries(startMarker, midMarker, endMarker, strokeWidth, m_path);
+ return m_markerLayoutInfo.calculateBoundaries(markerStart, markerMid, markerEnd, strokeWidth, m_path);
}
void RenderPath::styleWillChange(StyleDifference diff, const RenderStyle* newStyle)
{
- setNeedsBoundariesUpdate();
+ if (diff == StyleDifferenceLayout)
+ setNeedsBoundariesUpdate();
RenderSVGModelObject::styleWillChange(diff, newStyle);
}
diff --git a/WebCore/rendering/RenderPath.h b/WebCore/rendering/RenderPath.h
index 3748f39..57900ad 100644
--- a/WebCore/rendering/RenderPath.h
+++ b/WebCore/rendering/RenderPath.h
@@ -47,8 +47,8 @@ public:
private:
// Hit-detection seperated for the fill and the stroke
- bool fillContains(const FloatPoint&, bool requiresFill = true, WindRule fillRule = RULE_NONZERO) const;
- bool strokeContains(const FloatPoint&, bool requiresStroke = true) const;
+ bool fillContains(const FloatPoint&, bool requiresFill = true, WindRule fillRule = RULE_NONZERO);
+ bool strokeContains(const FloatPoint&, bool requiresStroke = true);
virtual FloatRect objectBoundingBox() const { return m_fillBoundingBox; }
virtual FloatRect strokeBoundingBox() const { return m_strokeAndMarkerBoundingBox; }
diff --git a/WebCore/rendering/RenderSVGBlock.cpp b/WebCore/rendering/RenderSVGBlock.cpp
index 2bae158..d6022b5 100644
--- a/WebCore/rendering/RenderSVGBlock.cpp
+++ b/WebCore/rendering/RenderSVGBlock.cpp
@@ -25,6 +25,7 @@
#if ENABLE(SVG)
#include "RenderSVGBlock.h"
+#include "RenderSVGResource.h"
#include "SVGElement.h"
namespace WebCore {
@@ -73,6 +74,25 @@ void RenderSVGBlock::absoluteRects(Vector<IntRect>&, int, int)
// This code path should never be taken for SVG, as we're assuming useTransforms=true everywhere, absoluteQuads should be used.
ASSERT_NOT_REACHED();
}
+
+void RenderSVGBlock::destroy()
+{
+ SVGResourcesCache::clientDestroyed(this);
+ RenderBlock::destroy();
+}
+
+void RenderSVGBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderBlock::styleDidChange(diff, oldStyle);
+ SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
+
+void RenderSVGBlock::updateFromElement()
+{
+ RenderBlock::updateFromElement();
+ SVGResourcesCache::clientUpdatedFromElement(this, style());
+}
+
}
#endif
diff --git a/WebCore/rendering/RenderSVGBlock.h b/WebCore/rendering/RenderSVGBlock.h
index 8dd140b..c4337cc 100644
--- a/WebCore/rendering/RenderSVGBlock.h
+++ b/WebCore/rendering/RenderSVGBlock.h
@@ -38,6 +38,10 @@ private:
virtual void updateBoxModelInfoFromStyle();
virtual void absoluteRects(Vector<IntRect>&, int tx, int ty);
+
+ virtual void destroy();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void updateFromElement();
};
}
diff --git a/WebCore/rendering/RenderSVGContainer.cpp b/WebCore/rendering/RenderSVGContainer.cpp
index ad63771..bab07a4 100644
--- a/WebCore/rendering/RenderSVGContainer.cpp
+++ b/WebCore/rendering/RenderSVGContainer.cpp
@@ -31,6 +31,7 @@
#include "RenderSVGResourceFilter.h"
#include "RenderView.h"
#include "SVGRenderSupport.h"
+#include "SVGResources.h"
#include "SVGStyledElement.h"
namespace WebCore {
@@ -58,23 +59,22 @@ void RenderSVGContainer::layout()
SVGRenderSupport::layoutChildren(this, selfNeedsLayout());
- // Invalidate all resources of this client, if we changed something.
+ // Invalidate all resources of this client if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+ SVGResourcesCache::clientLayoutChanged(this);
repainter.repaintAfterLayout();
setNeedsLayout(false);
}
-bool RenderSVGContainer::selfWillPaint() const
+bool RenderSVGContainer::selfWillPaint()
{
#if ENABLE(FILTERS)
- const SVGRenderStyle* svgStyle = style()->svgStyle();
- RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document(), svgStyle->filterResource());
- if (filter)
- return true;
-#endif
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
+ return resources && resources->filter();
+#else
return false;
+#endif
}
void RenderSVGContainer::paint(PaintInfo& paintInfo, int, int)
diff --git a/WebCore/rendering/RenderSVGContainer.h b/WebCore/rendering/RenderSVGContainer.h
index 53f1a97..0a122cd 100644
--- a/WebCore/rendering/RenderSVGContainer.h
+++ b/WebCore/rendering/RenderSVGContainer.h
@@ -69,7 +69,7 @@ protected:
virtual void applyViewportClip(PaintInfo&) { }
virtual bool pointIsInsideViewportClip(const FloatPoint& /*pointInParent*/) { return true; }
- bool selfWillPaint() const;
+ bool selfWillPaint();
private:
RenderObjectChildList m_children;
diff --git a/WebCore/rendering/RenderSVGGradientStop.cpp b/WebCore/rendering/RenderSVGGradientStop.cpp
index 754f31f..3494aa7 100644
--- a/WebCore/rendering/RenderSVGGradientStop.cpp
+++ b/WebCore/rendering/RenderSVGGradientStop.cpp
@@ -25,8 +25,10 @@
#if ENABLE(SVG)
#include "RenderSVGGradientStop.h"
+#include "RenderSVGResourceContainer.h"
#include "SVGGradientElement.h"
#include "SVGNames.h"
+#include "SVGResourcesCache.h"
#include "SVGStopElement.h"
namespace WebCore {
@@ -48,8 +50,17 @@ void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderSty
// <stop> elements should only be allowed to make renderers under gradient elements
// but I can imagine a few cases we might not be catching, so let's not crash if our parent isn't a gradient.
- if (SVGGradientElement* gradient = gradientElement())
- gradient->invalidateResourceClients();
+ SVGGradientElement* gradient = gradientElement();
+ if (!gradient)
+ return;
+
+ RenderObject* renderer = gradient->renderer();
+ if (!renderer)
+ return;
+
+ ASSERT(renderer->isSVGResourceContainer());
+ RenderSVGResourceContainer* container = renderer->toRenderSVGResourceContainer();
+ container->invalidateClients();
}
void RenderSVGGradientStop::layout()
diff --git a/WebCore/rendering/RenderSVGHiddenContainer.h b/WebCore/rendering/RenderSVGHiddenContainer.h
index 297a738..e0daac1 100644
--- a/WebCore/rendering/RenderSVGHiddenContainer.h
+++ b/WebCore/rendering/RenderSVGHiddenContainer.h
@@ -24,7 +24,6 @@
#define RenderSVGHiddenContainer_h
#if ENABLE(SVG)
-
#include "RenderSVGContainer.h"
namespace WebCore {
@@ -39,11 +38,13 @@ namespace WebCore {
virtual const char* renderName() const { return "RenderSVGHiddenContainer"; }
+ protected:
+ virtual void layout();
+
private:
virtual bool isSVGHiddenContainer() const { return true; }
virtual bool requiresLayer() const { return false; }
- virtual void layout();
virtual void paint(PaintInfo&, int parentX, int parentY);
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
diff --git a/WebCore/rendering/RenderSVGImage.cpp b/WebCore/rendering/RenderSVGImage.cpp
index 44b68b1..5a92e33 100644
--- a/WebCore/rendering/RenderSVGImage.cpp
+++ b/WebCore/rendering/RenderSVGImage.cpp
@@ -39,6 +39,7 @@
#include "SVGLength.h"
#include "SVGPreserveAspectRatio.h"
#include "SVGRenderSupport.h"
+#include "SVGResources.h"
namespace WebCore {
@@ -70,9 +71,9 @@ void RenderSVGImage::layout()
m_localBounds = FloatRect(image->x().value(image), image->y().value(image), image->width().value(image), image->height().value(image));
m_cachedLocalRepaintRect = FloatRect();
- // Invalidate all resources of this client, if we changed something.
+ // Invalidate all resources of this client if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+ SVGResourcesCache::clientLayoutChanged(this);
repainter.repaintAfterLayout();
setNeedsLayout(false);
@@ -110,10 +111,22 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, int, int)
void RenderSVGImage::destroy()
{
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+ SVGResourcesCache::clientDestroyed(this);
RenderImage::destroy();
}
+void RenderSVGImage::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderImage::styleDidChange(diff, oldStyle);
+ SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
+
+void RenderSVGImage::updateFromElement()
+{
+ RenderImage::updateFromElement();
+ SVGResourcesCache::clientUpdatedFromElement(this, style());
+}
+
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.
@@ -160,12 +173,12 @@ FloatRect RenderSVGImage::repaintRectInLocalCoordinates() const
void RenderSVGImage::imageChanged(WrappedImagePtr image, const IntRect* rect)
{
RenderImage::imageChanged(image, rect);
-#if ENABLE(FILTERS)
+
// The image resource defaults to nullImage until the resource arrives.
- // This empty image may be cached by SVG filter effects which must be invalidated.
- if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document(), style()->svgStyle()->filterResource()))
- filter->invalidateClient(this);
-#endif
+ // This empty image may be cached by SVG resources which must be invalidated.
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this))
+ resources->invalidateClient(this);
+
repaint();
}
diff --git a/WebCore/rendering/RenderSVGImage.h b/WebCore/rendering/RenderSVGImage.h
index 3baac23..6ee0179 100644
--- a/WebCore/rendering/RenderSVGImage.h
+++ b/WebCore/rendering/RenderSVGImage.h
@@ -65,6 +65,8 @@ private:
virtual void paint(PaintInfo&, int parentX, int parentY);
virtual void destroy();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void updateFromElement();
virtual bool requiresLayer() const { return false; }
diff --git a/WebCore/rendering/RenderSVGInline.cpp b/WebCore/rendering/RenderSVGInline.cpp
index ffc6b62..93e6a06 100644
--- a/WebCore/rendering/RenderSVGInline.cpp
+++ b/WebCore/rendering/RenderSVGInline.cpp
@@ -26,6 +26,7 @@
#if ENABLE(SVG)
#include "RenderSVGInline.h"
+#include "RenderSVGResource.h"
#include "SVGInlineFlowBox.h"
namespace WebCore {
@@ -92,6 +93,24 @@ void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads)
quads.append(localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x(), textBoundingBox.y() + box->y(), box->width(), box->height())));
}
+void RenderSVGInline::destroy()
+{
+ SVGResourcesCache::clientDestroyed(this);
+ RenderInline::destroy();
+}
+
+void RenderSVGInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderInline::styleDidChange(diff, oldStyle);
+ SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
+
+void RenderSVGInline::updateFromElement()
+{
+ RenderInline::updateFromElement();
+ SVGResourcesCache::clientUpdatedFromElement(this, style());
+}
+
}
diff --git a/WebCore/rendering/RenderSVGInline.h b/WebCore/rendering/RenderSVGInline.h
index 6f44162..56d911f 100644
--- a/WebCore/rendering/RenderSVGInline.h
+++ b/WebCore/rendering/RenderSVGInline.h
@@ -54,6 +54,10 @@ public:
private:
virtual InlineFlowBox* createInlineFlowBox();
+
+ virtual void destroy();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void updateFromElement();
};
}
diff --git a/WebCore/rendering/RenderSVGModelObject.cpp b/WebCore/rendering/RenderSVGModelObject.cpp
index 49404cb..5a19749 100644
--- a/WebCore/rendering/RenderSVGModelObject.cpp
+++ b/WebCore/rendering/RenderSVGModelObject.cpp
@@ -83,16 +83,20 @@ void RenderSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads)
void RenderSVGModelObject::destroy()
{
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+ SVGResourcesCache::clientDestroyed(this);
RenderObject::destroy();
}
void RenderSVGModelObject::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
RenderObject::styleDidChange(diff, oldStyle);
+ SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
- if (style() && (diff == StyleDifferenceLayout || diff == StyleDifferenceRepaint))
- RenderSVGResource::markForLayoutAndParentResourceInvalidation(this, false);
+void RenderSVGModelObject::updateFromElement()
+{
+ RenderObject::updateFromElement();
+ SVGResourcesCache::clientUpdatedFromElement(this, style());
}
bool RenderSVGModelObject::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
diff --git a/WebCore/rendering/RenderSVGModelObject.h b/WebCore/rendering/RenderSVGModelObject.h
index 741cd61..35c4dc3 100644
--- a/WebCore/rendering/RenderSVGModelObject.h
+++ b/WebCore/rendering/RenderSVGModelObject.h
@@ -62,6 +62,7 @@ public:
virtual void mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool useTransforms, bool fixed, TransformState&) const;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void updateFromElement();
private:
// This method should never be called, SVG uses a different nodeAtPoint method
diff --git a/WebCore/rendering/RenderSVGResource.cpp b/WebCore/rendering/RenderSVGResource.cpp
index b4f499e..9c89d3c 100644
--- a/WebCore/rendering/RenderSVGResource.cpp
+++ b/WebCore/rendering/RenderSVGResource.cpp
@@ -26,28 +26,13 @@
#if ENABLE(SVG)
#include "RenderSVGResource.h"
-#include "RenderSVGResourceClipper.h"
#include "RenderSVGResourceContainer.h"
-#include "RenderSVGResourceFilter.h"
-#include "RenderSVGResourceMarker.h"
-#include "RenderSVGResourceMasker.h"
#include "RenderSVGResourceSolidColor.h"
+#include "SVGResources.h"
#include "SVGURIReference.h"
namespace WebCore {
-static inline void registerPendingResource(const AtomicString& id, const SVGPaint::SVGPaintType& paintType, const RenderObject* object)
-{
- if (paintType != SVGPaint::SVG_PAINTTYPE_URI)
- return;
-
- SVGElement* svgElement = static_cast<SVGElement*>(object->node());
- ASSERT(svgElement);
- ASSERT(svgElement->isStyled());
-
- object->document()->accessSVGExtensions()->addPendingResource(id, static_cast<SVGStyledElement*>(svgElement));
-}
-
inline void RenderSVGResource::adjustColorForPseudoRules(const RenderStyle* style, bool useFillPaint, Color& color)
{
if (style->insideLink() != InsideVisitedLink)
@@ -69,7 +54,7 @@ inline void RenderSVGResource::adjustColorForPseudoRules(const RenderStyle* styl
}
// FIXME: This method and strokePaintingResource() should be refactored, to share even more code
-RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* object, const RenderStyle* style)
+RenderSVGResource* RenderSVGResource::fillPaintingResource(RenderObject* object, const RenderStyle* style)
{
ASSERT(object);
ASSERT(style);
@@ -84,13 +69,9 @@ RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* o
RenderSVGResource* fillPaintingResource = 0;
SVGPaint::SVGPaintType paintType = fillPaint->paintType();
- if (paintType == SVGPaint::SVG_PAINTTYPE_URI
- || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) {
- AtomicString id(SVGURIReference::getTarget(fillPaint->uri()));
- fillPaintingResource = getRenderSVGResourceContainerById(object->document(), id);
-
- if (!fillPaintingResource)
- registerPendingResource(id, paintType, object);
+ if (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR) {
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object))
+ fillPaintingResource = resources->fill();
}
if (paintType != SVGPaint::SVG_PAINTTYPE_URI && !fillPaintingResource) {
@@ -122,7 +103,7 @@ RenderSVGResource* RenderSVGResource::fillPaintingResource(const RenderObject* o
return fillPaintingResource;
}
-RenderSVGResource* RenderSVGResource::strokePaintingResource(const RenderObject* object, const RenderStyle* style)
+RenderSVGResource* RenderSVGResource::strokePaintingResource(RenderObject* object, const RenderStyle* style)
{
ASSERT(object);
ASSERT(style);
@@ -138,13 +119,9 @@ RenderSVGResource* RenderSVGResource::strokePaintingResource(const RenderObject*
FloatRect objectBoundingBox = object->objectBoundingBox();
SVGPaint::SVGPaintType paintType = strokePaint->paintType();
- if (!objectBoundingBox.isEmpty()
- && (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)) {
- AtomicString id(SVGURIReference::getTarget(strokePaint->uri()));
- strokePaintingResource = getRenderSVGResourceContainerById(object->document(), id);
-
- if (!strokePaintingResource)
- registerPendingResource(id, paintType, object);
+ if (!objectBoundingBox.isEmpty() && (paintType == SVGPaint::SVG_PAINTTYPE_URI || paintType == SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)) {
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object))
+ strokePaintingResource = resources->stroke();
}
if (paintType != SVGPaint::SVG_PAINTTYPE_URI && !strokePaintingResource) {
@@ -184,72 +161,6 @@ RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
return s_sharedSolidPaintingResource;
}
-void RenderSVGResource::markForLayoutAndResourceInvalidation(RenderObject* object, bool needsBoundariesUpdate)
-{
- ASSERT(object);
- ASSERT(object->node());
- ASSERT(object->node()->isSVGElement());
-
- // Eventually mark the renderer needing a boundaries update
- if (needsBoundariesUpdate)
- object->setNeedsBoundariesUpdate();
-
- markForLayoutAndParentResourceInvalidation(object);
-}
-
-static inline void invalidatePaintingResource(SVGPaint* paint, RenderObject* object)
-{
- ASSERT(paint);
-
- SVGPaint::SVGPaintType paintType = paint->paintType();
- if (paintType != SVGPaint::SVG_PAINTTYPE_URI && paintType != SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR)
- return;
-
- AtomicString id(SVGURIReference::getTarget(paint->uri()));
- if (RenderSVGResourceContainer* paintingResource = getRenderSVGResourceContainerById(object->document(), id))
- paintingResource->invalidateClient(object);
-}
-
-void RenderSVGResource::invalidateAllResourcesOfRenderer(RenderObject* object)
-{
- ASSERT(object);
- ASSERT(object->style());
-
- Document* document = object->document();
- ASSERT(document);
-
- const SVGRenderStyle* svgStyle = object->style()->svgStyle();
- ASSERT(svgStyle);
-
- // Masker
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, svgStyle->maskerResource()))
- masker->invalidateClient(object);
-
- // Clipper
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, svgStyle->clipperResource()))
- clipper->invalidateClient(object);
-
- // Filter
-#if ENABLE(FILTERS)
- if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, svgStyle->filterResource()))
- filter->invalidateClient(object);
-#endif
-
- // Markers
- if (RenderSVGResourceMarker* startMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerStartResource()))
- startMarker->invalidateClient(object);
- if (RenderSVGResourceMarker* midMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerMidResource()))
- midMarker->invalidateClient(object);
- if (RenderSVGResourceMarker* endMarker = getRenderSVGResourceById<RenderSVGResourceMarker>(document, svgStyle->markerEndResource()))
- endMarker->invalidateClient(object);
-
- // Gradients/Patterns
- if (svgStyle->hasFill())
- invalidatePaintingResource(svgStyle->fillPaint(), object);
- if (svgStyle->hasStroke())
- invalidatePaintingResource(svgStyle->strokePaint(), object);
-}
-
void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject* object, bool needsLayout)
{
ASSERT(object);
@@ -259,8 +170,10 @@ void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject*
// Invalidate resources in ancestor chain, if needed.
RenderObject* current = object->parent();
while (current) {
- if (current->isSVGResourceContainer())
+ if (current->isSVGResourceContainer()) {
current->toRenderSVGResourceContainer()->invalidateClients();
+ break;
+ }
current = current->parent();
}
diff --git a/WebCore/rendering/RenderSVGResource.h b/WebCore/rendering/RenderSVGResource.h
index b3ea6fb..e2d8216 100644
--- a/WebCore/rendering/RenderSVGResource.h
+++ b/WebCore/rendering/RenderSVGResource.h
@@ -22,6 +22,7 @@
#define RenderSVGResource_h
#if ENABLE(SVG)
+#include "RenderStyleConstants.h"
#include "SVGDocumentExtensions.h"
namespace WebCore {
@@ -75,18 +76,14 @@ public:
}
// Helper utilities used in the render tree to access resources used for painting shapes/text (gradients & patterns only)
- static RenderSVGResource* fillPaintingResource(const RenderObject*, const RenderStyle*);
- static RenderSVGResource* strokePaintingResource(const RenderObject*, const RenderStyle*);
+ static RenderSVGResource* fillPaintingResource(RenderObject*, const RenderStyle*);
+ static RenderSVGResource* strokePaintingResource(RenderObject*, const RenderStyle*);
static RenderSVGResourceSolidColor* sharedSolidPaintingResource();
- static void invalidateAllResourcesOfRenderer(RenderObject*);
static void markForLayoutAndParentResourceInvalidation(RenderObject*, bool needsLayout = true);
private:
static void adjustColorForPseudoRules(const RenderStyle*, bool useFillPaint, Color&);
-
-protected:
- void markForLayoutAndResourceInvalidation(RenderObject*, bool needsBoundariesUpdate = true);
};
}
diff --git a/WebCore/rendering/RenderSVGResourceClipper.cpp b/WebCore/rendering/RenderSVGResourceClipper.cpp
index e923f7e..a201d1f 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.cpp
+++ b/WebCore/rendering/RenderSVGResourceClipper.cpp
@@ -21,6 +21,7 @@
*/
#include "config.h"
+
#if ENABLE(SVG)
#include "RenderSVGResourceClipper.h"
@@ -32,11 +33,12 @@
#include "ImageBuffer.h"
#include "IntRect.h"
#include "RenderObject.h"
-#include "RenderStyle.h"
#include "RenderSVGResource.h"
+#include "RenderStyle.h"
#include "SVGClipPathElement.h"
#include "SVGElement.h"
#include "SVGRenderSupport.h"
+#include "SVGResources.h"
#include "SVGStyledElement.h"
#include "SVGStyledTransformableElement.h"
#include "SVGUnitTypes.h"
@@ -55,6 +57,9 @@ RenderSVGResourceClipper::RenderSVGResourceClipper(SVGClipPathElement* node)
RenderSVGResourceClipper::~RenderSVGResourceClipper()
{
+ if (m_clipper.isEmpty())
+ return;
+
deleteAllValues(m_clipper);
m_clipper.clear();
}
@@ -64,26 +69,26 @@ void RenderSVGResourceClipper::invalidateClients()
if (m_invalidationBlocked)
return;
- HashMap<RenderObject*, ClipperData*>::const_iterator end = m_clipper.end();
- for (HashMap<RenderObject*, ClipperData*>::const_iterator it = m_clipper.begin(); it != end; ++it)
- markForLayoutAndResourceInvalidation(it->first);
-
- deleteAllValues(m_clipper);
- m_clipper.clear();
m_clipBoundaries = FloatRect();
+ if (!m_clipper.isEmpty()) {
+ deleteAllValues(m_clipper);
+ m_clipper.clear();
+ }
+
+ markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
}
-void RenderSVGResourceClipper::invalidateClient(RenderObject* object)
+void RenderSVGResourceClipper::invalidateClient(RenderObject* client)
{
+ ASSERT(client);
if (m_invalidationBlocked)
return;
- ASSERT(object);
- if (!m_clipper.contains(object))
- return;
+ ASSERT(client->selfNeedsLayout());
+ if (m_clipper.contains(client))
+ delete m_clipper.take(client);
- delete m_clipper.take(object);
- markForLayoutAndResourceInvalidation(object);
+ markClientForInvalidation(client, BoundariesInvalidation);
}
bool RenderSVGResourceClipper::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
@@ -96,10 +101,6 @@ bool RenderSVGResourceClipper::applyResource(RenderObject* object, RenderStyle*,
UNUSED_PARAM(resourceMode);
#endif
- // Early exit, if this resource contains a child which references ourselves.
- if (containsCyclicReference(node()))
- return false;
-
applyClippingToContext(object, object->objectBoundingBox(), object->repaintRectInLocalCoordinates(), context);
return true;
}
@@ -191,11 +192,13 @@ bool RenderSVGResourceClipper::createClipData(ClipperData* clipperData, const Fl
maskContext->translate(-repaintRect.x(), -repaintRect.y());
// clipPath can also be clipped by another clipPath.
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(this->document(), style()->svgStyle()->clipperResource())) {
- if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
- maskContext->restore();
- return false;
- }
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this)) {
+ if (RenderSVGResourceClipper* clipper = resources->clipper()) {
+ if (!clipper->applyClippingToContext(this, objectBoundingBox, repaintRect, maskContext)) {
+ maskContext->restore();
+ return false;
+ }
+ }
}
SVGClipPathElement* clipPath = static_cast<SVGClipPathElement*>(node());
@@ -280,12 +283,6 @@ void RenderSVGResourceClipper::calculateClipContentRepaintRect()
bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
{
- // FIXME: We should be able to check whether m_clipper.contains(object) - this doesn't work at the moment
- // as resourceBoundingBox() has already created ClipperData, even if applyResource() returned false.
- // Early exit, if this resource contains a child which references ourselves.
- if (containsCyclicReference(node()))
- return false;
-
FloatPoint point = nodeAtPoint;
if (!SVGRenderSupport::pointInClippingArea(this, point))
return false;
@@ -312,14 +309,6 @@ bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundin
return false;
}
-bool RenderSVGResourceClipper::childElementReferencesResource(const SVGRenderStyle* style, const String& referenceId) const
-{
- if (!style->hasClipper())
- return false;
-
- return style->clipperResource() == referenceId;
-}
-
FloatRect RenderSVGResourceClipper::resourceBoundingBox(RenderObject* object)
{
// Resource was not layouted yet. Give back the boundingBox of the object.
diff --git a/WebCore/rendering/RenderSVGResourceClipper.h b/WebCore/rendering/RenderSVGResourceClipper.h
index 7128aa1..3c76bc8 100644
--- a/WebCore/rendering/RenderSVGResourceClipper.h
+++ b/WebCore/rendering/RenderSVGResourceClipper.h
@@ -68,8 +68,6 @@ private:
bool createClipData(ClipperData*, const FloatRect&, const FloatRect&);
void calculateClipContentRepaintRect();
- virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const;
-
bool m_invalidationBlocked;
FloatRect m_clipBoundaries;
HashMap<RenderObject*, ClipperData*> m_clipper;
diff --git a/WebCore/rendering/RenderSVGResourceContainer.cpp b/WebCore/rendering/RenderSVGResourceContainer.cpp
index 3707797..7e43300 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.cpp
+++ b/WebCore/rendering/RenderSVGResourceContainer.cpp
@@ -28,102 +28,147 @@
namespace WebCore {
+static inline SVGDocumentExtensions* svgExtensionsFromNode(Node* node)
+{
+ ASSERT(node);
+ ASSERT(node->document());
+ return node->document()->accessSVGExtensions();
+}
+
RenderSVGResourceContainer::RenderSVGResourceContainer(SVGStyledElement* node)
: RenderSVGHiddenContainer(node)
- , RenderSVGResource()
, m_id(node->hasID() ? node->getIdAttribute() : nullAtom)
+ , m_registered(false)
{
- ASSERT(node->document());
- node->document()->accessSVGExtensions()->addResource(m_id, this);
}
RenderSVGResourceContainer::~RenderSVGResourceContainer()
{
- ASSERT(node());
- ASSERT(node()->document());
- node()->document()->accessSVGExtensions()->removeResource(m_id);
+ if (m_registered)
+ svgExtensionsFromNode(node())->removeResource(m_id);
}
-void RenderSVGResourceContainer::idChanged()
+void RenderSVGResourceContainer::layout()
{
- ASSERT(node());
- ASSERT(node()->document());
- SVGDocumentExtensions* extensions = node()->document()->accessSVGExtensions();
+ // Invalidate all resources if our layout changed.
+ if (m_everHadLayout && selfNeedsLayout())
+ invalidateClients();
- // Remove old id, that is guaranteed to be present in cache
- extensions->removeResource(m_id);
- m_id = static_cast<Element*>(node())->getIdAttribute();
+ RenderSVGHiddenContainer::layout();
+}
- // It's possible that an element is referencing us with the new id, and has to be notified that we're existing now
- if (extensions->isPendingResource(m_id)) {
- OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(m_id));
- if (clients->isEmpty())
- return;
+void RenderSVGResourceContainer::destroy()
+{
+ SVGResourcesCache::resourceDestroyed(this);
+ RenderSVGHiddenContainer::destroy();
+}
- HashSet<SVGStyledElement*>::const_iterator it = clients->begin();
- const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+void RenderSVGResourceContainer::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderSVGHiddenContainer::styleDidChange(diff, oldStyle);
- for (; it != end; ++it) {
- if (RenderObject* renderer = (*it)->renderer())
- renderer->setNeedsLayout(true);
- }
+ if (!m_registered) {
+ m_registered = true;
+ registerResource();
}
-
- // Recache us with the new id
- extensions->addResource(m_id, this);
}
-AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
+void RenderSVGResourceContainer::idChanged()
{
- if (!object->isRenderPath())
- return resourceTransform;
+ // Invalidate all our current clients.
+ invalidateClients();
- SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
- AffineTransform transform = resourceTransform;
- transform.multiply(element->getScreenCTM());
- return transform;
+ // 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();
+
+ registerResource();
}
-bool RenderSVGResourceContainer::containsCyclicReference(const Node* startNode) const
+void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode mode)
{
- ASSERT(startNode->document());
+ if (m_clients.isEmpty())
+ return;
- for (Node* node = startNode->firstChild(); node; node = node->nextSibling()) {
- if (!node->isSVGElement())
- continue;
+ bool needsLayout = mode == LayoutAndBoundariesInvalidation;
- RenderObject* renderer = node->renderer();
- if (!renderer)
+ HashSet<RenderObject*>::iterator end = m_clients.end();
+ for (HashSet<RenderObject*>::iterator it = m_clients.begin(); it != end; ++it) {
+ RenderObject* client = *it;
+ if (client->isSVGResourceContainer()) {
+ client->toRenderSVGResourceContainer()->invalidateClients();
continue;
+ }
- RenderStyle* style = renderer->style();
- if (!style)
- continue;
+ markClientForInvalidation(client, mode);
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(client, needsLayout);
+ }
+}
- const SVGRenderStyle* svgStyle = style->svgStyle();
- ASSERT(svgStyle);
+void RenderSVGResourceContainer::markClientForInvalidation(RenderObject* client, InvalidationMode mode)
+{
+ ASSERT(client);
+ ASSERT(!m_clients.isEmpty());
+
+ switch (mode) {
+ case LayoutAndBoundariesInvalidation:
+ case BoundariesInvalidation:
+ client->setNeedsBoundariesUpdate();
+ break;
+ case RepaintInvalidation:
+ if (client->view())
+ client->repaint();
+ break;
+ }
+}
- // Let the class inheriting from us decide whether the child element references ourselves.
- if (childElementReferencesResource(svgStyle, m_id))
- return true;
+void RenderSVGResourceContainer::addClient(RenderObject* client)
+{
+ ASSERT(client);
+ m_clients.add(client);
+}
- // Dive into shadow tree to check for cycles there.
- if (node->hasTagName(SVGNames::useTag)) {
- ASSERT(renderer->isSVGShadowTreeRootContainer());
- if (Node* shadowRoot = static_cast<RenderSVGShadowTreeRootContainer*>(renderer)->rootElement()) {
- if (containsCyclicReference(shadowRoot))
- return true;
- }
+void RenderSVGResourceContainer::removeClient(RenderObject* client)
+{
+ ASSERT(client);
+ m_clients.remove(client);
+}
- }
+void RenderSVGResourceContainer::registerResource()
+{
+ SVGDocumentExtensions* extensions = svgExtensionsFromNode(node());
+ if (!extensions->isPendingResource(m_id)) {
+ extensions->addResource(m_id, this);
+ return;
+ }
- if (node->hasChildNodes()) {
- if (containsCyclicReference(node))
- return true;
- }
+ OwnPtr<HashSet<SVGStyledElement*> > clients(extensions->removePendingResource(m_id));
+
+ // Cache us with the new id.
+ extensions->addResource(m_id, this);
+
+ // Update cached resources of pending clients.
+ const HashSet<SVGStyledElement*>::const_iterator end = clients->end();
+ for (HashSet<SVGStyledElement*>::const_iterator it = clients->begin(); it != end; ++it) {
+ RenderObject* renderer = (*it)->renderer();
+ if (!renderer)
+ continue;
+ SVGResourcesCache::clientUpdatedFromElement(renderer, renderer->style());
+ renderer->setNeedsLayout(true);
}
+}
+
+// FIXME: This does not belong here.
+AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderObject* object, const AffineTransform& resourceTransform)
+{
+ if (!object->isRenderPath())
+ return resourceTransform;
- return false;
+ SVGStyledTransformableElement* element = static_cast<SVGStyledTransformableElement*>(object->node());
+ AffineTransform transform = resourceTransform;
+ transform.multiply(element->getScreenCTM());
+ return transform;
}
}
diff --git a/WebCore/rendering/RenderSVGResourceContainer.h b/WebCore/rendering/RenderSVGResourceContainer.h
index d57b1db..4271a5f 100644
--- a/WebCore/rendering/RenderSVGResourceContainer.h
+++ b/WebCore/rendering/RenderSVGResourceContainer.h
@@ -23,10 +23,7 @@
#if ENABLE(SVG)
#include "RenderSVGHiddenContainer.h"
-
-#include "SVGStyledTransformableElement.h"
#include "RenderSVGResource.h"
-#include "RenderSVGShadowTreeRootContainer.h"
namespace WebCore {
@@ -36,27 +33,40 @@ public:
RenderSVGResourceContainer(SVGStyledElement*);
virtual ~RenderSVGResourceContainer();
- void idChanged();
+ virtual void layout();
+ virtual void destroy();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
virtual bool isSVGResourceContainer() const { return true; }
virtual bool drawsContents() { return false; }
-
virtual RenderSVGResourceContainer* toRenderSVGResourceContainer() { return this; }
- virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const { return false; }
static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
- bool containsCyclicReference(const Node* startNode) const;
+ void idChanged();
+
+protected:
+ enum InvalidationMode {
+ LayoutAndBoundariesInvalidation,
+ BoundariesInvalidation,
+ RepaintInvalidation
+ };
+
+ // Used from the invalidateClient/invalidateClients methods from classes, inheriting from us.
+ void markAllClientsForInvalidation(InvalidationMode);
+ void markClientForInvalidation(RenderObject*, InvalidationMode);
private:
friend class SVGResourcesCache;
-
- // FIXME: No-ops for now, until follow-up patch on bug 43031 lands.
- void addClient(RenderObject*) { }
- void removeClient(RenderObject*) { }
+ void addClient(RenderObject*);
+ void removeClient(RenderObject*);
private:
+ void registerResource();
+
AtomicString m_id;
+ bool m_registered;
+ HashSet<RenderObject*> m_clients;
};
inline RenderSVGResourceContainer* getRenderSVGResourceContainerById(Document* document, const AtomicString& id)
diff --git a/WebCore/rendering/RenderSVGResourceFilter.cpp b/WebCore/rendering/RenderSVGResourceFilter.cpp
index a6358f0..bc5feaf 100644
--- a/WebCore/rendering/RenderSVGResourceFilter.cpp
+++ b/WebCore/rendering/RenderSVGResourceFilter.cpp
@@ -60,28 +60,32 @@ RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement* node)
RenderSVGResourceFilter::~RenderSVGResourceFilter()
{
+ if (m_filter.isEmpty())
+ return;
+
deleteAllValues(m_filter);
m_filter.clear();
}
void RenderSVGResourceFilter::invalidateClients()
{
- HashMap<RenderObject*, FilterData*>::const_iterator end = m_filter.end();
- for (HashMap<RenderObject*, FilterData*>::const_iterator it = m_filter.begin(); it != end; ++it)
- markForLayoutAndResourceInvalidation(it->first);
+ if (!m_filter.isEmpty()) {
+ deleteAllValues(m_filter);
+ m_filter.clear();
+ }
- deleteAllValues(m_filter);
- m_filter.clear();
+ markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
}
-void RenderSVGResourceFilter::invalidateClient(RenderObject* object)
+void RenderSVGResourceFilter::invalidateClient(RenderObject* client)
{
- ASSERT(object);
- if (!m_filter.contains(object))
- return;
+ ASSERT(client);
+ ASSERT(client->selfNeedsLayout());
+
+ if (m_filter.contains(client))
+ delete m_filter.take(client);
- delete m_filter.take(object);
- markForLayoutAndResourceInvalidation(object);
+ markClientForInvalidation(client, BoundariesInvalidation);
}
PassRefPtr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives()
diff --git a/WebCore/rendering/RenderSVGResourceGradient.cpp b/WebCore/rendering/RenderSVGResourceGradient.cpp
index ce51369..73b2ab6 100644
--- a/WebCore/rendering/RenderSVGResourceGradient.cpp
+++ b/WebCore/rendering/RenderSVGResourceGradient.cpp
@@ -43,28 +43,32 @@ RenderSVGResourceGradient::RenderSVGResourceGradient(SVGGradientElement* node)
RenderSVGResourceGradient::~RenderSVGResourceGradient()
{
+ if (m_gradient.isEmpty())
+ return;
+
deleteAllValues(m_gradient);
m_gradient.clear();
}
void RenderSVGResourceGradient::invalidateClients()
{
- const HashMap<RenderObject*, GradientData*>::const_iterator end = m_gradient.end();
- for (HashMap<RenderObject*, GradientData*>::const_iterator it = m_gradient.begin(); it != end; ++it)
- markForLayoutAndResourceInvalidation(it->first, false);
+ if (!m_gradient.isEmpty()) {
+ deleteAllValues(m_gradient);
+ m_gradient.clear();
+ }
- deleteAllValues(m_gradient);
- m_gradient.clear();
+ markAllClientsForInvalidation(RepaintInvalidation);
}
-void RenderSVGResourceGradient::invalidateClient(RenderObject* object)
+void RenderSVGResourceGradient::invalidateClient(RenderObject* client)
{
- ASSERT(object);
- if (!m_gradient.contains(object))
- return;
+ ASSERT(client);
+ ASSERT(client->selfNeedsLayout());
+
+ if (m_gradient.contains(client))
+ delete m_gradient.take(client);
- delete m_gradient.take(object);
- markForLayoutAndResourceInvalidation(object, false);
+ markClientForInvalidation(client, RepaintInvalidation);
}
#if PLATFORM(CG)
diff --git a/WebCore/rendering/RenderSVGResourceMarker.cpp b/WebCore/rendering/RenderSVGResourceMarker.cpp
index 4f0cace..fa00fa3 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMarker.cpp
@@ -21,6 +21,7 @@
*/
#include "config.h"
+
#if ENABLE(SVG)
#include "RenderSVGResourceMarker.h"
@@ -43,39 +44,30 @@ RenderSVGResourceMarker::RenderSVGResourceMarker(SVGMarkerElement* node)
RenderSVGResourceMarker::~RenderSVGResourceMarker()
{
- m_marker.clear();
}
void RenderSVGResourceMarker::layout()
{
+ // Invalidate all resources if our layout changed.
+ if (m_everHadLayout && selfNeedsLayout())
+ invalidateClients();
+
// RenderSVGHiddenContainer overwrites layout(). We need the
// layouting of RenderSVGContainer for calculating local
// transformations and repaint.
RenderSVGContainer::layout();
}
-void RenderSVGResourceMarker::addClient(const RenderObject* object)
-{
- m_marker.add(object);
-}
-
void RenderSVGResourceMarker::invalidateClients()
{
- const HashSet<const RenderObject*>::const_iterator end = m_marker.end();
- for (HashSet<const RenderObject*>::const_iterator it = m_marker.begin(); it != end; ++it)
- markForLayoutAndResourceInvalidation(const_cast<RenderObject*>(*it));
-
- m_marker.clear();
+ markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
}
-void RenderSVGResourceMarker::invalidateClient(RenderObject* object)
+void RenderSVGResourceMarker::invalidateClient(RenderObject* client)
{
- ASSERT(object);
- if (!m_marker.contains(object))
- return;
-
- m_marker.remove(object);
- markForLayoutAndResourceInvalidation(object);
+ ASSERT(client);
+ ASSERT(client->selfNeedsLayout());
+ markClientForInvalidation(client, BoundariesInvalidation);
}
void RenderSVGResourceMarker::applyViewportClip(PaintInfo& paintInfo)
@@ -140,20 +132,11 @@ AffineTransform RenderSVGResourceMarker::markerTransformation(const FloatPoint&
void RenderSVGResourceMarker::draw(PaintInfo& paintInfo, const AffineTransform& transform)
{
- DEFINE_STATIC_LOCAL(HashSet<RenderSVGResourceMarker*>, currentlyDrawingMarkers, ());
-
- // avoid drawing circular marker references
- if (currentlyDrawingMarkers.contains(this))
- return;
-
- currentlyDrawingMarkers.add(this);
PaintInfo info(paintInfo);
info.context->save();
info.applyTransform(transform);
RenderSVGContainer::paint(info, 0, 0);
info.context->restore();
-
- currentlyDrawingMarkers.remove(this);
}
AffineTransform RenderSVGResourceMarker::markerContentTransformation(const AffineTransform& contentTransformation, const FloatPoint& origin, float strokeWidth) const
diff --git a/WebCore/rendering/RenderSVGResourceMarker.h b/WebCore/rendering/RenderSVGResourceMarker.h
index 75c442e..8509aca 100644
--- a/WebCore/rendering/RenderSVGResourceMarker.h
+++ b/WebCore/rendering/RenderSVGResourceMarker.h
@@ -41,7 +41,6 @@ public:
virtual const char* renderName() const { return "RenderSVGResourceMarker"; }
- void addClient(const RenderObject*);
virtual void invalidateClients();
virtual void invalidateClient(RenderObject*);
@@ -74,9 +73,6 @@ private:
AffineTransform viewportTransform() const;
- // Save objects using this marker for invalidation.
- HashSet<const RenderObject*> m_marker;
-
mutable AffineTransform m_localToParentTransform;
FloatRect m_viewport;
};
diff --git a/WebCore/rendering/RenderSVGResourceMasker.cpp b/WebCore/rendering/RenderSVGResourceMasker.cpp
index 83a64b5..2c36c96 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.cpp
+++ b/WebCore/rendering/RenderSVGResourceMasker.cpp
@@ -19,6 +19,7 @@
*/
#include "config.h"
+
#if ENABLE(SVG)
#include "RenderSVGResourceMasker.h"
@@ -51,37 +52,33 @@ RenderSVGResourceMasker::RenderSVGResourceMasker(SVGMaskElement* node)
RenderSVGResourceMasker::~RenderSVGResourceMasker()
{
+ if (m_masker.isEmpty())
+ return;
+
deleteAllValues(m_masker);
m_masker.clear();
}
void RenderSVGResourceMasker::invalidateClients()
{
- HashMap<RenderObject*, MaskerData*>::const_iterator end = m_masker.end();
- for (HashMap<RenderObject*, MaskerData*>::const_iterator it = m_masker.begin(); it != end; ++it)
- markForLayoutAndResourceInvalidation(it->first);
-
- deleteAllValues(m_masker);
- m_masker.clear();
m_maskBoundaries = FloatRect();
-}
-
-void RenderSVGResourceMasker::invalidateClient(RenderObject* object)
-{
- ASSERT(object);
- if (!m_masker.contains(object))
- return;
+ if (!m_masker.isEmpty()) {
+ deleteAllValues(m_masker);
+ m_masker.clear();
+ }
- delete m_masker.take(object);
- markForLayoutAndResourceInvalidation(object);
+ markAllClientsForInvalidation(LayoutAndBoundariesInvalidation);
}
-bool RenderSVGResourceMasker::childElementReferencesResource(const SVGRenderStyle* style, const String& referenceId) const
+void RenderSVGResourceMasker::invalidateClient(RenderObject* client)
{
- if (!style->hasMasker())
- return false;
+ ASSERT(client);
+ ASSERT(client->selfNeedsLayout());
- return style->maskerResource() == referenceId;
+ if (m_masker.contains(client))
+ delete m_masker.take(client);
+
+ markClientForInvalidation(client, BoundariesInvalidation);
}
bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*, GraphicsContext*& context, unsigned short resourceMode)
@@ -102,11 +99,6 @@ bool RenderSVGResourceMasker::applyResource(RenderObject* object, RenderStyle*,
SVGMaskElement* maskElement = static_cast<SVGMaskElement*>(node());
if (!maskElement)
return false;
-
- // Early exit, if this resource contains a child which references ourselves.
- if (containsCyclicReference(node()))
- return false;
-
createMaskImage(maskerData, maskElement, object);
}
diff --git a/WebCore/rendering/RenderSVGResourceMasker.h b/WebCore/rendering/RenderSVGResourceMasker.h
index 56f657b..f6301cb 100644
--- a/WebCore/rendering/RenderSVGResourceMasker.h
+++ b/WebCore/rendering/RenderSVGResourceMasker.h
@@ -69,8 +69,6 @@ private:
void createMaskImage(MaskerData*, const SVGMaskElement*, RenderObject*);
void calculateMaskContentRepaintRect();
- virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const;
-
FloatRect m_maskBoundaries;
HashMap<RenderObject*, MaskerData*> m_masker;
};
diff --git a/WebCore/rendering/RenderSVGResourcePattern.cpp b/WebCore/rendering/RenderSVGResourcePattern.cpp
index a2234c8..902ff02 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.cpp
+++ b/WebCore/rendering/RenderSVGResourcePattern.cpp
@@ -40,43 +40,32 @@ RenderSVGResourcePattern::RenderSVGResourcePattern(SVGPatternElement* node)
RenderSVGResourcePattern::~RenderSVGResourcePattern()
{
- deleteAllValues(m_pattern);
- m_pattern.clear();
-}
-
-void RenderSVGResourcePattern::invalidateClients()
-{
- const HashMap<RenderObject*, PatternData*>::const_iterator end = m_pattern.end();
- for (HashMap<RenderObject*, PatternData*>::const_iterator it = m_pattern.begin(); it != end; ++it)
- markForLayoutAndResourceInvalidation(it->first, false);
+ if (m_pattern.isEmpty())
+ return;
deleteAllValues(m_pattern);
m_pattern.clear();
}
-void RenderSVGResourcePattern::invalidateClient(RenderObject* object)
+void RenderSVGResourcePattern::invalidateClients()
{
- ASSERT(object);
- if (!m_pattern.contains(object))
- return;
+ if (!m_pattern.isEmpty()) {
+ deleteAllValues(m_pattern);
+ m_pattern.clear();
+ }
- delete m_pattern.take(object);
- markForLayoutAndResourceInvalidation(object, false);
+ markAllClientsForInvalidation(RepaintInvalidation);
}
-bool RenderSVGResourcePattern::childElementReferencesResource(const SVGRenderStyle* style, const String& referenceId) const
+void RenderSVGResourcePattern::invalidateClient(RenderObject* client)
{
- if (style->hasFill()) {
- if (style->fillPaint()->matchesTargetURI(referenceId))
- return true;
- }
+ ASSERT(client);
+ ASSERT(client->selfNeedsLayout());
- if (style->hasStroke()) {
- if (style->strokePaint()->matchesTargetURI(referenceId))
- return true;
- }
+ if (m_pattern.contains(client))
+ delete m_pattern.take(client);
- return false;
+ markClientForInvalidation(client, RepaintInvalidation);
}
bool RenderSVGResourcePattern::applyResource(RenderObject* object, RenderStyle* style, GraphicsContext*& context, unsigned short resourceMode)
@@ -244,10 +233,6 @@ PassOwnPtr<ImageBuffer> RenderSVGResourcePattern::createTileImage(PatternData* p
if (!attributes.patternContentElement())
return 0;
- // Early exit, if this resource contains a child which references ourselves.
- if (containsCyclicReference(attributes.patternContentElement()))
- return 0;
-
FloatRect objectBoundingBox = object->objectBoundingBox();
FloatRect patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement);
AffineTransform patternTransform = attributes.patternTransform();
diff --git a/WebCore/rendering/RenderSVGResourcePattern.h b/WebCore/rendering/RenderSVGResourcePattern.h
index ec89777..690b0de 100644
--- a/WebCore/rendering/RenderSVGResourcePattern.h
+++ b/WebCore/rendering/RenderSVGResourcePattern.h
@@ -67,8 +67,6 @@ private:
FloatRect calculatePatternBoundariesIncludingOverflow(PatternAttributes&, const FloatRect& objectBoundingBox,
const AffineTransform& viewBoxCTM, const FloatRect& patternBoundaries) const;
- virtual bool childElementReferencesResource(const SVGRenderStyle*, const String&) const;
-
HashMap<RenderObject*, PatternData*> m_pattern;
};
diff --git a/WebCore/rendering/RenderSVGRoot.cpp b/WebCore/rendering/RenderSVGRoot.cpp
index 1659e40..7ddebf2 100644
--- a/WebCore/rendering/RenderSVGRoot.cpp
+++ b/WebCore/rendering/RenderSVGRoot.cpp
@@ -26,14 +26,19 @@
#include "RenderSVGRoot.h"
#include "GraphicsContext.h"
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
#include "HitTestResult.h"
#endif
+=======
+#include "HitTestResult.h"
+>>>>>>> webkit.org at r64523
#include "RenderSVGContainer.h"
#include "RenderSVGResource.h"
#include "RenderView.h"
#include "SVGLength.h"
#include "SVGRenderSupport.h"
+#include "SVGResources.h"
#include "SVGSVGElement.h"
#include "SVGStyledElement.h"
#include "TransformState.h"
@@ -131,15 +136,14 @@ void RenderSVGRoot::layout()
setNeedsLayout(false);
}
-bool RenderSVGRoot::selfWillPaint() const
+bool RenderSVGRoot::selfWillPaint()
{
#if ENABLE(FILTERS)
- const SVGRenderStyle* svgStyle = style()->svgStyle();
- RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document(), svgStyle->filterResource());
- if (filter)
- return true;
-#endif
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(this);
+ return resources && resources->filter();
+#else
return false;
+#endif
}
void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
@@ -194,10 +198,22 @@ void RenderSVGRoot::paint(PaintInfo& paintInfo, int parentX, int parentY)
void RenderSVGRoot::destroy()
{
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+ SVGResourcesCache::clientDestroyed(this);
RenderBox::destroy();
}
+void RenderSVGRoot::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
+{
+ RenderBox::styleDidChange(diff, oldStyle);
+ SVGResourcesCache::clientStyleChanged(this, diff, style());
+}
+
+void RenderSVGRoot::updateFromElement()
+{
+ RenderBox::updateFromElement();
+ SVGResourcesCache::clientUpdatedFromElement(this, style());
+}
+
void RenderSVGRoot::calcViewport()
{
SVGSVGElement* svg = static_cast<SVGSVGElement*>(node());
@@ -322,6 +338,7 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) {
// FIXME: CSS/HTML assumes the local point is relative to the border box, right?
updateHitTestResult(result, pointInBorderBox);
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
// TODO: nodeAtFloatPoint() doesn't handle region test yet.
if (result.isRegionTest()) {
@@ -329,6 +346,10 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
result.addRawNode(node());
} else
#endif
+=======
+ // FIXME: nodeAtFloatPoint() doesn't handle rect-based hit tests yet.
+ result.addNodeToRectBasedTestResult(child->node(), _x, _y);
+>>>>>>> webkit.org at r64523
return true;
}
}
diff --git a/WebCore/rendering/RenderSVGRoot.h b/WebCore/rendering/RenderSVGRoot.h
index 0a08ab5..b90113c 100644
--- a/WebCore/rendering/RenderSVGRoot.h
+++ b/WebCore/rendering/RenderSVGRoot.h
@@ -58,6 +58,8 @@ private:
virtual void paint(PaintInfo&, int parentX, int parentY);
virtual void destroy();
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+ virtual void updateFromElement();
virtual const AffineTransform& localToParentTransform() const;
@@ -77,7 +79,7 @@ private:
void calcViewport();
- bool selfWillPaint() const;
+ bool selfWillPaint();
IntSize parentOriginToBorderBox() const;
IntSize borderOriginToContentBox() const;
diff --git a/WebCore/rendering/RenderSVGText.cpp b/WebCore/rendering/RenderSVGText.cpp
index 58348db..c4fc353 100644
--- a/WebCore/rendering/RenderSVGText.cpp
+++ b/WebCore/rendering/RenderSVGText.cpp
@@ -98,9 +98,9 @@ void RenderSVGText::layout()
ASSERT(childrenInline());
forceLayoutInlineChildren();
- // Invalidate all resources of this client, if we changed something.
+ // Invalidate all resources of this client if our layout changed.
if (m_everHadLayout && selfNeedsLayout())
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
+ SVGResourcesCache::clientLayoutChanged(this);
repainter.repaintAfterLayout();
setNeedsLayout(false);
@@ -132,12 +132,6 @@ bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResul
return false;
}
-void RenderSVGText::destroy()
-{
- RenderSVGResource::invalidateAllResourcesOfRenderer(this);
- RenderSVGBlock::destroy();
-}
-
bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, int, int, int, int, HitTestAction)
{
ASSERT_NOT_REACHED();
diff --git a/WebCore/rendering/RenderSVGText.h b/WebCore/rendering/RenderSVGText.h
index 6e7d03a..be19419 100644
--- a/WebCore/rendering/RenderSVGText.h
+++ b/WebCore/rendering/RenderSVGText.h
@@ -51,8 +51,6 @@ private:
virtual bool requiresLayer() const { return false; }
virtual void layout();
- virtual void destroy();
-
virtual void absoluteQuads(Vector<FloatQuad>&);
virtual IntRect clippedOverflowRectForRepaint(RenderBoxModelObject* repaintContainer);
diff --git a/WebCore/rendering/RenderScrollbar.cpp b/WebCore/rendering/RenderScrollbar.cpp
index 63fce8d..817dd02 100644
--- a/WebCore/rendering/RenderScrollbar.cpp
+++ b/WebCore/rendering/RenderScrollbar.cpp
@@ -130,6 +130,9 @@ ScrollbarPart RenderScrollbar::partForStyleResolve()
PassRefPtr<RenderStyle> RenderScrollbar::getScrollbarPseudoStyle(ScrollbarPart partType, PseudoId pseudoId)
{
+ if (!m_owner)
+ return 0;
+
s_styleResolvePart = partType;
s_styleResolveScrollbar = this;
RefPtr<RenderStyle> result = m_owner->getUncachedPseudoStyle(pseudoId, m_owner->style());
diff --git a/WebCore/rendering/RenderScrollbar.h b/WebCore/rendering/RenderScrollbar.h
index b3c00ef..8cc263a 100644
--- a/WebCore/rendering/RenderScrollbar.h
+++ b/WebCore/rendering/RenderScrollbar.h
@@ -49,6 +49,7 @@ public:
static RenderScrollbar* scrollbarForStyleResolve();
RenderBox* owningRenderer() const { return m_owner; }
+ void clearOwningRenderer() { m_owner = 0; }
void paintPart(GraphicsContext*, ScrollbarPart, const IntRect&);
diff --git a/WebCore/rendering/RenderTable.cpp b/WebCore/rendering/RenderTable.cpp
index 6359c09..7c54837 100644
--- a/WebCore/rendering/RenderTable.cpp
+++ b/WebCore/rendering/RenderTable.cpp
@@ -31,9 +31,13 @@
#include "Document.h"
#include "FixedTableLayout.h"
#include "FrameView.h"
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
#include "HitTestResult.h"
#endif
+=======
+#include "HitTestResult.h"
+>>>>>>> webkit.org at r64523
#include "HTMLNames.h"
#include "RenderLayer.h"
#include "RenderTableCell.h"
@@ -1183,11 +1187,15 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
ty += y();
// Check kids first.
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (!hasOverflowClip() || result.intersects(xPos, yPos, overflowClipRect(tx, ty))) {
#else
if (!hasOverflowClip() || overflowClipRect(tx, ty).contains(xPos, yPos)) {
#endif
+=======
+ if (!hasOverflowClip() || overflowClipRect(tx, ty).intersects(result.rectFromPoint(xPos, yPos))) {
+>>>>>>> webkit.org at r64523
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
if (child->isBox() && !toRenderBox(child)->hasSelfPaintingLayer() && (child->isTableSection() || child == m_caption) &&
child->nodeAtPoint(request, result, xPos, yPos, tx, ty, action)) {
@@ -1198,6 +1206,7 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
// Check our bounds next.
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
IntRect boundsRect = IntRect(tx, ty, width(), height());
if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && result.intersects(xPos, yPos, boundsRect)) {
@@ -1214,6 +1223,13 @@ bool RenderTable::nodeAtPoint(const HitTestRequest& request, HitTestResult& resu
}
#endif
return true;
+=======
+ IntRect boundsRect = IntRect(tx, ty, width(), height());
+ if (visibleToHitTesting() && (action == HitTestBlockBackground || action == HitTestChildBlockBackground) && boundsRect.intersects(result.rectFromPoint(xPos, yPos))) {
+ updateHitTestResult(result, IntPoint(xPos - tx, yPos - ty));
+ if (!result.addNodeToRectBasedTestResult(node(), xPos, yPos, boundsRect))
+ return true;
+>>>>>>> webkit.org at r64523
}
return false;
diff --git a/WebCore/rendering/RenderTableSection.cpp b/WebCore/rendering/RenderTableSection.cpp
index c439a13..e094f36 100644
--- a/WebCore/rendering/RenderTableSection.cpp
+++ b/WebCore/rendering/RenderTableSection.cpp
@@ -28,9 +28,13 @@
#include "CachedImage.h"
#include "Document.h"
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
#include "HitTestResult.h"
#endif
+=======
+#include "HitTestResult.h"
+>>>>>>> webkit.org at r64523
#include "HTMLNames.h"
#include "RenderTableCell.h"
#include "RenderTableCol.h"
@@ -1289,11 +1293,15 @@ bool RenderTableSection::nodeAtPoint(const HitTestRequest& request, HitTestResul
tx += x();
ty += y();
+<<<<<<< HEAD
#ifdef ANDROID_HITTEST_WITHSIZE
if (hasOverflowClip() && !result.intersects(xPos, yPos, overflowClipRect(tx, ty)))
#else
if (hasOverflowClip() && !overflowClipRect(tx, ty).contains(xPos, yPos))
#endif
+=======
+ if (hasOverflowClip() && !overflowClipRect(tx, ty).intersects(result.rectFromPoint(xPos, yPos)))
+>>>>>>> webkit.org at r64523
return false;
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
diff --git a/WebCore/rendering/RenderTextControlSingleLine.cpp b/WebCore/rendering/RenderTextControlSingleLine.cpp
index 5b57513..4ba2dc7 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.cpp
+++ b/WebCore/rendering/RenderTextControlSingleLine.cpp
@@ -2,6 +2,7 @@
* Copyright (C) 2006, 2007, 2010 Apple Inc. All rights reserved.
* (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
* Copyright (C) 2010 Google Inc. All rights reserved.
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,6 +24,7 @@
#include "config.h"
#include "RenderTextControlSingleLine.h"
+#include "Chrome.h"
#include "CSSStyleSelector.h"
#include "Event.h"
#include "EventNames.h"
@@ -38,7 +40,6 @@
#include "RenderLayer.h"
#include "RenderScrollbar.h"
#include "RenderTheme.h"
-#include "SearchPopupMenu.h"
#include "SelectionController.h"
#include "Settings.h"
#include "SimpleFontData.h"
@@ -62,7 +63,7 @@ RenderTextControlSingleLine::RenderTextControlSingleLine(Node* node, bool placeh
RenderTextControlSingleLine::~RenderTextControlSingleLine()
{
if (m_searchPopup) {
- m_searchPopup->disconnectClient();
+ m_searchPopup->popupMenu()->disconnectClient();
m_searchPopup = 0;
}
@@ -107,7 +108,7 @@ void RenderTextControlSingleLine::addSearchResult()
const AtomicString& name = autosaveName();
if (!m_searchPopup)
- m_searchPopup = SearchPopupMenu::create(this);
+ m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
m_searchPopup->saveRecentSearches(name, m_recentSearches);
}
@@ -125,7 +126,7 @@ void RenderTextControlSingleLine::showPopup()
return;
if (!m_searchPopup)
- m_searchPopup = SearchPopupMenu::create(this);
+ m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
if (!m_searchPopup->enabled())
return;
@@ -145,14 +146,14 @@ void RenderTextControlSingleLine::showPopup()
m_searchPopup->saveRecentSearches(name, m_recentSearches);
}
- m_searchPopup->show(absoluteBoundingBoxRect(true), document()->view(), -1);
+ m_searchPopup->popupMenu()->show(absoluteBoundingBoxRect(true), document()->view(), -1);
}
void RenderTextControlSingleLine::hidePopup()
{
ASSERT(node()->isHTMLElement());
if (m_searchPopup)
- m_searchPopup->hide();
+ m_searchPopup->popupMenu()->hide();
}
void RenderTextControlSingleLine::subtreeHasChanged()
@@ -689,7 +690,7 @@ void RenderTextControlSingleLine::updateFromElement()
}
if (m_searchPopupIsVisible)
- m_searchPopup->updateFromElement();
+ m_searchPopup->popupMenu()->updateFromElement();
}
void RenderTextControlSingleLine::cacheSelection(int start, int end)
@@ -887,7 +888,7 @@ void RenderTextControlSingleLine::valueChanged(unsigned listIndex, bool fireEven
const AtomicString& name = autosaveName();
if (!name.isEmpty()) {
if (!m_searchPopup)
- m_searchPopup = SearchPopupMenu::create(this);
+ m_searchPopup = document()->page()->chrome()->createSearchPopupMenu(this);
m_searchPopup->saveRecentSearches(name, m_recentSearches);
}
}
diff --git a/WebCore/rendering/RenderTextControlSingleLine.h b/WebCore/rendering/RenderTextControlSingleLine.h
index 8c7e844..4bc80cf 100644
--- a/WebCore/rendering/RenderTextControlSingleLine.h
+++ b/WebCore/rendering/RenderTextControlSingleLine.h
@@ -1,6 +1,7 @@
/*
* Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved.
* Copyright (C) 2008 Torch Mobile Inc. All rights reserved. (http://www.torchmobile.com/)
+ * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -24,6 +25,7 @@
#include "PopupMenuClient.h"
#include "RenderTextControl.h"
+#include "SearchPopupMenu.h"
#include "Timer.h"
namespace WebCore {
@@ -32,7 +34,6 @@ class InputElement;
class InputFieldSpeechButtonElement;
class SearchFieldCancelButtonElement;
class SearchFieldResultsButtonElement;
-class SearchPopupMenu;
class SpinButtonElement;
class TextControlInnerElement;
diff --git a/WebCore/rendering/RenderWidget.cpp b/WebCore/rendering/RenderWidget.cpp
index bebe6c8..3854e6a 100644
--- a/WebCore/rendering/RenderWidget.cpp
+++ b/WebCore/rendering/RenderWidget.cpp
@@ -396,7 +396,7 @@ bool RenderWidget::nodeAtPoint(const HitTestRequest& request, HitTestResult& res
bool inside = RenderReplaced::nodeAtPoint(request, result, x, y, tx, ty, action);
// Check to see if we are really over the widget itself (and not just in the border/padding area).
- if (inside && !hadResult && result.innerNode() == node())
+ if ((inside || result.isRectBasedTest()) && !hadResult && result.innerNode() == node())
result.setIsOverWidget(contentBoxRect().contains(result.localPoint()));
#ifdef ANDROID_HITTEST_WITHSIZE
else if (result.isRegionTest() && !hadResult && result.innerNode() == node()) {
diff --git a/WebCore/rendering/SVGInlineTextBox.cpp b/WebCore/rendering/SVGInlineTextBox.cpp
index 8e498ad..a293124 100644
--- a/WebCore/rendering/SVGInlineTextBox.cpp
+++ b/WebCore/rendering/SVGInlineTextBox.cpp
@@ -295,17 +295,16 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, int, int)
ASSERT(!m_paintingResource);
}
-bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, RenderStyle* style)
+bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, RenderObject* renderer, RenderStyle* style)
{
+ ASSERT(renderer);
+ ASSERT(style);
ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
- RenderObject* parentRenderer = parent()->renderer();
- ASSERT(parentRenderer);
-
if (m_paintingResourceMode & ApplyToFillMode)
- m_paintingResource = RenderSVGResource::fillPaintingResource(parentRenderer, style);
+ m_paintingResource = RenderSVGResource::fillPaintingResource(renderer, style);
else if (m_paintingResourceMode & ApplyToStrokeMode)
- m_paintingResource = RenderSVGResource::strokePaintingResource(parentRenderer, style);
+ m_paintingResource = RenderSVGResource::strokePaintingResource(renderer, style);
else {
// We're either called for stroking or filling.
ASSERT_NOT_REACHED();
@@ -314,7 +313,7 @@ bool SVGInlineTextBox::acquirePaintingResource(GraphicsContext*& context, Render
if (!m_paintingResource)
return false;
- m_paintingResource->applyResource(parentRenderer, style, context, m_paintingResourceMode);
+ m_paintingResource->applyResource(renderer, style, context, m_paintingResourceMode);
return true;
}
@@ -331,7 +330,7 @@ void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context)
bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& context, TextRun& textRun, RenderStyle* style)
{
- bool acquiredResource = acquirePaintingResource(context, style);
+ bool acquiredResource = acquirePaintingResource(context, parent()->renderer(), style);
#if ENABLE(SVG_FONTS)
// SVG Fonts need access to the painting resource used to draw the current text chunk.
@@ -508,21 +507,24 @@ void SVGInlineTextBox::paintDecoration(GraphicsContext* context, const FloatPoin
if (hasDecorationFill) {
m_paintingResourceMode = ApplyToFillMode;
- paintDecorationWithStyle(context, textOrigin, decorationStyle, decoration);
+ paintDecorationWithStyle(context, textOrigin, decorationRenderer, decoration);
}
if (hasDecorationStroke) {
m_paintingResourceMode = ApplyToStrokeMode;
- paintDecorationWithStyle(context, textOrigin, decorationStyle, decoration);
+ paintDecorationWithStyle(context, textOrigin, decorationRenderer, decoration);
}
}
-void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, const FloatPoint& textOrigin, RenderStyle* decorationStyle, ETextDecoration decoration)
+void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, const FloatPoint& textOrigin, RenderObject* decorationRenderer, ETextDecoration decoration)
{
ASSERT(!m_paintingResource);
ASSERT(m_paintingResourceMode != ApplyToDefaultMode);
ASSERT(m_currentChunkPart.isValid());
+ RenderStyle* decorationStyle = decorationRenderer->style();
+ ASSERT(decorationStyle);
+
const Font& font = decorationStyle->font();
// The initial y value refers to overline position.
@@ -534,7 +536,7 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, const
context->beginPath();
context->addPath(Path::createRectangle(FloatRect(x, y, m_currentChunkPart.width, thickness)));
- if (acquirePaintingResource(context, decorationStyle))
+ if (acquirePaintingResource(context, decorationRenderer, decorationStyle))
releasePaintingResource(context);
context->restore();
@@ -614,9 +616,15 @@ void SVGInlineTextBox::paintText(GraphicsContext* context, const FloatPoint& tex
paintTextWithShadows(context, textOrigin, style, textRun, 0, startPos);
// Draw text using selection style from the start to the end position of the selection
+ if (style != selectionStyle)
+ SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, selectionStyle);
+
TextRun selectionTextRun(constructTextRun(selectionStyle));
paintTextWithShadows(context, textOrigin, selectionStyle, textRun, startPos, endPos);
+ if (style != selectionStyle)
+ SVGResourcesCache::clientStyleChanged(parent()->renderer(), StyleDifferenceRepaint, style);
+
// Eventually draw text using regular style from the end position of the selection to the end of the current chunk part
if (endPos < m_currentChunkPart.length && !paintSelectedTextOnly)
paintTextWithShadows(context, textOrigin, style, textRun, endPos, m_currentChunkPart.length);
diff --git a/WebCore/rendering/SVGInlineTextBox.h b/WebCore/rendering/SVGInlineTextBox.h
index 602fff1..7711db4 100644
--- a/WebCore/rendering/SVGInlineTextBox.h
+++ b/WebCore/rendering/SVGInlineTextBox.h
@@ -75,7 +75,7 @@ private:
TextRun constructTextRun(RenderStyle*) const;
AffineTransform buildChunkTransformation(SVGChar& firstCharacter) const;
- bool acquirePaintingResource(GraphicsContext*&, RenderStyle*);
+ bool acquirePaintingResource(GraphicsContext*&, RenderObject*, RenderStyle*);
void releasePaintingResource(GraphicsContext*&);
bool prepareGraphicsContextForTextPainting(GraphicsContext*&, TextRun&, RenderStyle*);
@@ -83,7 +83,7 @@ private:
void computeTextMatchMarkerRect(RenderStyle*);
void paintDecoration(GraphicsContext*, const FloatPoint& textOrigin, ETextDecoration, bool hasSelection);
- void paintDecorationWithStyle(GraphicsContext*, const FloatPoint& textOrigin, RenderStyle*, ETextDecoration);
+ void paintDecorationWithStyle(GraphicsContext*, const FloatPoint& textOrigin, RenderObject*, ETextDecoration);
void paintSelection(GraphicsContext*, const FloatPoint& textOrigin, RenderStyle*);
void paintText(GraphicsContext*, const FloatPoint& textOrigin, RenderStyle*, RenderStyle* selectionStyle, bool hasSelection, bool paintSelectedTextOnly);
void paintTextWithShadows(GraphicsContext*, const FloatPoint& textOrigin, RenderStyle*, TextRun&, int startPos, int endPos);
diff --git a/WebCore/rendering/SVGRenderSupport.cpp b/WebCore/rendering/SVGRenderSupport.cpp
index 0d4a42b..34f6659 100644
--- a/WebCore/rendering/SVGRenderSupport.cpp
+++ b/WebCore/rendering/SVGRenderSupport.cpp
@@ -40,6 +40,7 @@
#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceMasker.h"
#include "RenderSVGRoot.h"
+#include "SVGResources.h"
#include "SVGStyledElement.h"
#include "TransformState.h"
#include <wtf/UnusedParam.h>
@@ -79,10 +80,7 @@ void SVGRenderSupport::mapLocalToContainer(const RenderObject* object, RenderBox
bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo& paintInfo)
{
ASSERT(object);
- SVGElement* svgElement = static_cast<SVGElement*>(object->node());
- ASSERT(svgElement && svgElement->document() && svgElement->isStyled());
- SVGStyledElement* styledElement = static_cast<SVGStyledElement*>(svgElement);
RenderStyle* style = object->style();
ASSERT(style);
@@ -109,33 +107,22 @@ bool SVGRenderSupport::prepareToRenderSVGContent(RenderObject* object, PaintInfo
paintInfo.context->beginTransparencyLayer(1);
}
- Document* document = object->document();
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
+ if (!resources)
+ return true;
- if (svgStyle->hasMasker()) {
- AtomicString maskerId(svgStyle->maskerResource());
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, maskerId)) {
- if (!masker->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
- return false;
- } else
- document->accessSVGExtensions()->addPendingResource(maskerId, styledElement);
+ if (RenderSVGResourceMasker* masker = resources->masker()) {
+ if (!masker->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
+ return false;
}
- if (svgStyle->hasClipper()) {
- AtomicString clipperId(svgStyle->clipperResource());
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, clipperId))
- clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
- else
- document->accessSVGExtensions()->addPendingResource(clipperId, styledElement);
- }
+ if (RenderSVGResourceClipper* clipper = resources->clipper())
+ clipper->applyResource(object, style, paintInfo.context, ApplyToDefaultMode);
#if ENABLE(FILTERS)
- if (svgStyle->hasFilter()) {
- AtomicString filterId(svgStyle->filterResource());
- if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, filterId)) {
- if (!filter->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
- return false;
- } else
- document->accessSVGExtensions()->addPendingResource(filterId, styledElement);
+ if (RenderSVGResourceFilter* filter = resources->filter()) {
+ if (!filter->applyResource(object, style, paintInfo.context, ApplyToDefaultMode))
+ return false;
}
#endif
@@ -157,9 +144,9 @@ void SVGRenderSupport::finishRenderSVGContent(RenderObject* object, PaintInfo& p
ASSERT(svgStyle);
#if ENABLE(FILTERS)
- if (svgStyle->hasFilter()) {
- AtomicString filterId(svgStyle->filterResource());
- if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), filterId)) {
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
+ if (resources) {
+ if (RenderSVGResourceFilter* filter = resources->filter()) {
filter->postApplyResource(object, paintInfo.context, ApplyToDefaultMode);
paintInfo.context = savedContext;
}
@@ -289,49 +276,46 @@ bool SVGRenderSupport::isOverflowHidden(const RenderObject* object)
void SVGRenderSupport::intersectRepaintRectWithResources(const RenderObject* object, FloatRect& repaintRect)
{
ASSERT(object);
- ASSERT(object->style());
- const SVGRenderStyle* svgStyle = object->style()->svgStyle();
- if (!svgStyle)
- return;
-
+
+ RenderStyle* style = object->style();
+ ASSERT(style);
+
+ const SVGRenderStyle* svgStyle = style->svgStyle();
+ ASSERT(svgStyle);
+
RenderObject* renderer = const_cast<RenderObject*>(object);
-#if ENABLE(FILTERS)
- if (svgStyle->hasFilter()) {
- if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object->document(), svgStyle->filterResource()))
- repaintRect = filter->resourceBoundingBox(renderer);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
+ if (!resources) {
+ svgStyle->inflateForShadow(repaintRect);
+ return;
}
+
+#if ENABLE(FILTERS)
+ if (RenderSVGResourceFilter* filter = resources->filter())
+ repaintRect = filter->resourceBoundingBox(renderer);
#endif
- if (svgStyle->hasClipper()) {
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object->document(), svgStyle->clipperResource()))
- repaintRect.intersect(clipper->resourceBoundingBox(renderer));
- }
-
- if (svgStyle->hasMasker()) {
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object->document(), svgStyle->maskerResource()))
- repaintRect.intersect(masker->resourceBoundingBox(renderer));
- }
-
+ if (RenderSVGResourceClipper* clipper = resources->clipper())
+ repaintRect.intersect(clipper->resourceBoundingBox(renderer));
+
+ if (RenderSVGResourceMasker* masker = resources->masker())
+ repaintRect.intersect(masker->resourceBoundingBox(renderer));
+
svgStyle->inflateForShadow(repaintRect);
}
-bool SVGRenderSupport::pointInClippingArea(const RenderObject* object, const FloatPoint& point)
+bool SVGRenderSupport::pointInClippingArea(RenderObject* object, const FloatPoint& point)
{
ASSERT(object);
- ASSERT(object->style());
-
- Document* document = object->document();
- ASSERT(document);
-
- const SVGRenderStyle* svgStyle = object->style()->svgStyle();
- ASSERT(svgStyle);
// We just take clippers into account to determine if a point is on the node. The Specification may
// change later and we also need to check maskers.
- if (svgStyle->hasClipper()) {
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, svgStyle->clipperResource()))
- return clipper->hitTestClipContent(object->objectBoundingBox(), point);
- }
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object);
+ if (!resources)
+ return true;
+
+ if (RenderSVGResourceClipper* clipper = resources->clipper())
+ return clipper->hitTestClipContent(object->objectBoundingBox(), point);
return true;
}
diff --git a/WebCore/rendering/SVGRenderSupport.h b/WebCore/rendering/SVGRenderSupport.h
index 8eb486e6..371ac75 100644
--- a/WebCore/rendering/SVGRenderSupport.h
+++ b/WebCore/rendering/SVGRenderSupport.h
@@ -56,7 +56,7 @@ public:
static void intersectRepaintRectWithResources(const RenderObject*, FloatRect&);
// Determines whether the passed point lies in a clipping area
- static bool pointInClippingArea(const RenderObject*, const FloatPoint&);
+ static bool pointInClippingArea(RenderObject*, const FloatPoint&);
enum ContainerBoundingBoxMode {
ObjectBoundingBox,
diff --git a/WebCore/rendering/SVGRenderTreeAsText.cpp b/WebCore/rendering/SVGRenderTreeAsText.cpp
index bec78e7..d298544 100644
--- a/WebCore/rendering/SVGRenderTreeAsText.cpp
+++ b/WebCore/rendering/SVGRenderTreeAsText.cpp
@@ -366,7 +366,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
if (object.isRenderPath()) {
const RenderPath& path = static_cast<const RenderPath&>(object);
- if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(&path, path.style())) {
+ if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderPath*>(&path), path.style())) {
TextStreamSeparator s(" ");
ts << " [stroke={" << s;
writeSVGPaintingResource(ts, strokePaintingResource);
@@ -387,7 +387,7 @@ static void writeStyle(TextStream& ts, const RenderObject& object)
ts << "}]";
}
- if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(&path, path.style())) {
+ if (RenderSVGResource* fillPaintingResource = RenderSVGResource::fillPaintingResource(const_cast<RenderPath*>(&path), path.style())) {
TextStreamSeparator s(" ");
ts << " [fill={" << s;
writeSVGPaintingResource(ts, fillPaintingResource);
@@ -734,6 +734,8 @@ void writeResources(TextStream& ts, const RenderObject& object, int indent)
const RenderStyle* style = object.style();
const SVGRenderStyle* svgStyle = style->svgStyle();
+ // FIXME: We want to use SVGResourcesCache to determine which resources are present, instead of quering the resource <-> id cache.
+ // For now leave the DRT output as is, but later on we should change this so cycles are properly ignored in the DRT output.
RenderObject& renderer = const_cast<RenderObject&>(object);
if (!svgStyle->maskerResource().isEmpty()) {
if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle->maskerResource())) {
diff --git a/WebCore/rendering/SVGResources.cpp b/WebCore/rendering/SVGResources.cpp
index de23ce1..fa1677b 100644
--- a/WebCore/rendering/SVGResources.cpp
+++ b/WebCore/rendering/SVGResources.cpp
@@ -25,24 +25,128 @@
#include "RenderSVGResourceFilter.h"
#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceMasker.h"
+#include "SVGFilterElement.h"
+#include "SVGGradientElement.h"
#include "SVGPaint.h"
+#include "SVGPatternElement.h"
#include "SVGRenderStyle.h"
#include "SVGURIReference.h"
namespace WebCore {
SVGResources::SVGResources()
- : m_clipper(0)
-#if ENABLE(FILTERS)
- , m_filter(0)
-#endif
- , m_markerStart(0)
- , m_markerMid(0)
- , m_markerEnd(0)
- , m_masker(0)
- , m_fill(0)
- , m_stroke(0)
+ : m_clipperFilterMaskerData(0)
+ , m_markerData(0)
+ , m_fillStrokeData(0)
+ , m_linkedResource(0)
+{
+}
+
+static HashSet<AtomicStringImpl*>& clipperFilterMaskerTags()
{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+ if (s_tagList.isEmpty()) {
+ // "container elements": http://www.w3.org/TR/SVG11/intro.html#TermContainerElement
+ // "graphics elements" : http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement
+ s_tagList.add(SVGNames::aTag.localName().impl());
+ s_tagList.add(SVGNames::circleTag.localName().impl());
+ s_tagList.add(SVGNames::ellipseTag.localName().impl());
+ s_tagList.add(SVGNames::glyphTag.localName().impl());
+ s_tagList.add(SVGNames::gTag.localName().impl());
+ s_tagList.add(SVGNames::imageTag.localName().impl());
+ s_tagList.add(SVGNames::lineTag.localName().impl());
+ s_tagList.add(SVGNames::markerTag.localName().impl());
+ s_tagList.add(SVGNames::maskTag.localName().impl());
+ s_tagList.add(SVGNames::missing_glyphTag.localName().impl());
+ s_tagList.add(SVGNames::pathTag.localName().impl());
+ s_tagList.add(SVGNames::polygonTag.localName().impl());
+ s_tagList.add(SVGNames::polylineTag.localName().impl());
+ s_tagList.add(SVGNames::rectTag.localName().impl());
+ s_tagList.add(SVGNames::svgTag.localName().impl());
+ s_tagList.add(SVGNames::textTag.localName().impl());
+ s_tagList.add(SVGNames::useTag.localName().impl());
+
+ // Not listed in the definitions is the clipPath element, the SVG spec says though:
+ // The "clipPath" element or any of its children can specify property "clip-path".
+ // So we have to add clipPathTag here, otherwhise clip-path on clipPath will fail.
+ // (Already mailed SVG WG, waiting for a solution)
+ s_tagList.add(SVGNames::clipPathTag.localName().impl());
+
+ // Not listed in the definitions are the text content elements, though filter/clipper/masker on tspan/text/.. is allowed.
+ // (Already mailed SVG WG, waiting for a solution)
+ s_tagList.add(SVGNames::altGlyphTag.localName().impl());
+ s_tagList.add(SVGNames::textPathTag.localName().impl());
+ s_tagList.add(SVGNames::trefTag.localName().impl());
+ s_tagList.add(SVGNames::tspanTag.localName().impl());
+
+ // Elements that we ignore, as it doesn't make any sense.
+ // defs, pattern, switch (FIXME: Mail SVG WG about these)
+ // symbol (is converted to a svg element, when referenced by use, we can safely ignore it.)
+ }
+
+ return s_tagList;
+}
+
+static HashSet<AtomicStringImpl*>& markerTags()
+{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+ if (s_tagList.isEmpty()) {
+ s_tagList.add(SVGNames::lineTag.localName().impl());
+ s_tagList.add(SVGNames::pathTag.localName().impl());
+ s_tagList.add(SVGNames::polygonTag.localName().impl());
+ s_tagList.add(SVGNames::polylineTag.localName().impl());
+ }
+
+ return s_tagList;
+}
+
+static HashSet<AtomicStringImpl*>& fillAndStrokeTags()
+{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+ if (s_tagList.isEmpty()) {
+ s_tagList.add(SVGNames::altGlyphTag.localName().impl());
+ s_tagList.add(SVGNames::circleTag.localName().impl());
+ s_tagList.add(SVGNames::ellipseTag.localName().impl());
+ s_tagList.add(SVGNames::lineTag.localName().impl());
+ s_tagList.add(SVGNames::pathTag.localName().impl());
+ s_tagList.add(SVGNames::polygonTag.localName().impl());
+ s_tagList.add(SVGNames::polylineTag.localName().impl());
+ s_tagList.add(SVGNames::rectTag.localName().impl());
+ s_tagList.add(SVGNames::textTag.localName().impl());
+ s_tagList.add(SVGNames::textPathTag.localName().impl());
+ s_tagList.add(SVGNames::trefTag.localName().impl());
+ s_tagList.add(SVGNames::tspanTag.localName().impl());
+ }
+
+ return s_tagList;
+}
+
+static HashSet<AtomicStringImpl*>& chainableResourceTags()
+{
+ DEFINE_STATIC_LOCAL(HashSet<AtomicStringImpl*>, s_tagList, ());
+ if (s_tagList.isEmpty()) {
+ s_tagList.add(SVGNames::linearGradientTag.localName().impl());
+ s_tagList.add(SVGNames::filterTag.localName().impl());
+ s_tagList.add(SVGNames::patternTag.localName().impl());
+ s_tagList.add(SVGNames::radialGradientTag.localName().impl());
+ }
+
+ return s_tagList;
+}
+
+static inline String targetReferenceFromResource(SVGElement* element)
+{
+ String target;
+ 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();
+ else if (element->hasTagName(SVGNames::filterTag))
+ target = static_cast<SVGFilterElement*>(element)->href();
+ else
+ ASSERT_NOT_REACHED();
+
+ return SVGURIReference::getTarget(target);
}
static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document* document, SVGPaint* paint, AtomicString& id, bool& hasPendingResource)
@@ -61,17 +165,13 @@ static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document*
return 0;
}
-static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, Node* node)
+static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, SVGElement* element)
{
- ASSERT(node);
- if (!node->isSVGElement())
- return;
-
- SVGElement* svgElement = static_cast<SVGElement*>(node);
- if (!svgElement->isStyled())
+ ASSERT(element);
+ if (!element->isStyled())
return;
- extensions->addPendingResource(id, static_cast<SVGStyledElement*>(svgElement));
+ extensions->addPendingResource(id, static_cast<SVGStyledElement*>(element));
}
bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRenderStyle* style)
@@ -81,6 +181,11 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
Node* node = object->node();
ASSERT(node);
+ ASSERT(node->isSVGElement());
+
+ SVGElement* element = static_cast<SVGElement*>(node);
+ if (!element)
+ return false;
Document* document = object->document();
ASSERT(document);
@@ -88,77 +193,85 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
SVGDocumentExtensions* extensions = document->accessSVGExtensions();
ASSERT(extensions);
- bool foundResources = false;
- if (style->hasClipper()) {
- AtomicString id(style->clipperResource());
- m_clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(document, id);
- if (m_clipper)
- foundResources = true;
- else
- registerPendingResource(extensions, id, node);
- }
+ AtomicStringImpl* tagNameImpl = element->tagQName().localName().impl();
+ if (!tagNameImpl)
+ return false;
- if (style->hasMasker()) {
- AtomicString id(style->maskerResource());
- m_masker = getRenderSVGResourceById<RenderSVGResourceMasker>(document, id);
- if (m_masker)
- foundResources = true;
- else
- registerPendingResource(extensions, id, node);
- }
+ bool foundResources = false;
+ if (clipperFilterMaskerTags().contains(tagNameImpl)) {
+ if (style->hasClipper()) {
+ AtomicString id(style->clipperResource());
+ if (setClipper(getRenderSVGResourceById<RenderSVGResourceClipper>(document, id)))
+ foundResources = true;
+ else
+ registerPendingResource(extensions, id, element);
+ }
#if ENABLE(FILTERS)
- if (style->hasFilter()) {
- AtomicString id(style->filterResource());
- m_filter = getRenderSVGResourceById<RenderSVGResourceFilter>(document, id);
- if (m_filter)
- foundResources = true;
- else
- registerPendingResource(extensions, id, node);
- }
+ if (style->hasFilter()) {
+ AtomicString id(style->filterResource());
+ if (setFilter(getRenderSVGResourceById<RenderSVGResourceFilter>(document, id)))
+ foundResources = true;
+ else
+ registerPendingResource(extensions, id, element);
+ }
#endif
- if (style->hasMarkers()) {
+ if (style->hasMasker()) {
+ AtomicString id(style->maskerResource());
+ if (setMasker(getRenderSVGResourceById<RenderSVGResourceMasker>(document, id)))
+ foundResources = true;
+ else
+ registerPendingResource(extensions, id, element);
+ }
+ }
+
+ if (markerTags().contains(tagNameImpl) && style->hasMarkers()) {
AtomicString markerStartId(style->markerStartResource());
- m_markerStart = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId);
- if (m_markerStart)
+ if (setMarkerStart(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerStartId)))
foundResources = true;
else
- registerPendingResource(extensions, markerStartId, node);
+ registerPendingResource(extensions, markerStartId, element);
AtomicString markerMidId(style->markerMidResource());
- m_markerMid = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerMidId);
- if (m_markerMid)
+ if (setMarkerMid(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerMidId)))
foundResources = true;
else
- registerPendingResource(extensions, markerMidId, node);
+ registerPendingResource(extensions, markerMidId, element);
AtomicString markerEndId(style->markerEndResource());
- m_markerEnd = getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerEndId);
- if (m_markerEnd)
+ if (setMarkerEnd(getRenderSVGResourceById<RenderSVGResourceMarker>(document, markerEndId)))
foundResources = true;
else
- registerPendingResource(extensions, markerEndId, node);
+ registerPendingResource(extensions, markerEndId, element);
}
- if (style->hasFill()) {
- bool hasPendingResource = false;
- AtomicString id;
- m_fill = paintingResourceFromSVGPaint(document, style->fillPaint(), id, hasPendingResource);
- if (m_fill)
- foundResources = true;
- else if (hasPendingResource)
- registerPendingResource(extensions, id, node);
+ if (fillAndStrokeTags().contains(tagNameImpl)) {
+ if (style->hasFill()) {
+ bool hasPendingResource = false;
+ AtomicString id;
+ if (setFill(paintingResourceFromSVGPaint(document, style->fillPaint(), id, hasPendingResource)))
+ foundResources = true;
+ else if (hasPendingResource)
+ registerPendingResource(extensions, id, element);
+ }
+
+ if (style->hasStroke()) {
+ bool hasPendingResource = false;
+ AtomicString id;
+ if (setStroke(paintingResourceFromSVGPaint(document, style->strokePaint(), id, hasPendingResource)))
+ foundResources = true;
+ else if (hasPendingResource)
+ registerPendingResource(extensions, id, element);
+ }
}
- if (style->hasStroke()) {
- bool hasPendingResource = false;
- AtomicString id;
- m_stroke = paintingResourceFromSVGPaint(document, style->strokePaint(), id, hasPendingResource);
- if (m_stroke)
+ if (chainableResourceTags().contains(tagNameImpl)) {
+ AtomicString id(targetReferenceFromResource(element));
+ if (setLinkedResource(getRenderSVGResourceContainerById(document, id)))
foundResources = true;
- else if (hasPendingResource)
- registerPendingResource(extensions, id, node);
+ else
+ registerPendingResource(extensions, id, element);
}
return foundResources;
@@ -166,81 +279,115 @@ bool SVGResources::buildCachedResources(const RenderObject* object, const SVGRen
void SVGResources::invalidateClient(RenderObject* object) const
{
- // Ordinary resources
- if (m_clipper)
- m_clipper->invalidateClient(object);
+ if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData && !m_linkedResource)
+ return;
+
+ if (m_linkedResource) {
+ ASSERT(!m_clipperFilterMaskerData);
+ ASSERT(!m_markerData);
+ ASSERT(!m_fillStrokeData);
+ m_linkedResource->invalidateClient(object);
+ return;
+ }
+
+ if (m_clipperFilterMaskerData) {
+ if (m_clipperFilterMaskerData->clipper)
+ m_clipperFilterMaskerData->clipper->invalidateClient(object);
#if ENABLE(FILTERS)
- if (m_filter)
- m_filter->invalidateClient(object);
+ if (m_clipperFilterMaskerData->filter)
+ m_clipperFilterMaskerData->filter->invalidateClient(object);
#endif
- if (m_masker)
- m_masker->invalidateClient(object);
- if (m_markerStart)
- m_markerStart->invalidateClient(object);
- if (m_markerMid)
- m_markerMid->invalidateClient(object);
- if (m_markerEnd)
- m_markerEnd->invalidateClient(object);
-
- // Paint servers
- if (m_fill)
- m_fill->invalidateClient(object);
- if (m_stroke)
- m_stroke->invalidateClient(object);
+ if (m_clipperFilterMaskerData->masker)
+ m_clipperFilterMaskerData->masker->invalidateClient(object);
+ }
+
+ if (m_markerData) {
+ if (m_markerData->markerStart)
+ m_markerData->markerStart->invalidateClient(object);
+ if (m_markerData->markerMid)
+ m_markerData->markerMid->invalidateClient(object);
+ if (m_markerData->markerEnd)
+ m_markerData->markerEnd->invalidateClient(object);
+ }
+
+ if (m_fillStrokeData) {
+ if (m_fillStrokeData->fill)
+ m_fillStrokeData->fill->invalidateClient(object);
+ if (m_fillStrokeData->stroke)
+ m_fillStrokeData->stroke->invalidateClient(object);
+ }
}
void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
{
ASSERT(resource);
+ if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData && !m_linkedResource)
+ return;
+
+ if (m_linkedResource == resource) {
+ ASSERT(!m_clipperFilterMaskerData);
+ ASSERT(!m_markerData);
+ ASSERT(!m_fillStrokeData);
+ m_linkedResource->invalidateClients();
+ m_linkedResource = 0;
+ return;
+ }
switch (resource->resourceType()) {
case MaskerResourceType:
- if (m_masker == resource) {
- m_masker->invalidateClients();
- m_masker = 0;
+ if (!m_clipperFilterMaskerData)
+ break;
+ if (m_clipperFilterMaskerData->masker == resource) {
+ m_clipperFilterMaskerData->masker->invalidateClients();
+ m_clipperFilterMaskerData->masker = 0;
}
break;
case MarkerResourceType:
- if (m_markerStart == resource) {
- m_markerStart->invalidateClients();
- m_markerStart = 0;
+ if (!m_markerData)
+ break;
+ if (m_markerData->markerStart == resource) {
+ m_markerData->markerStart->invalidateClients();
+ m_markerData->markerStart = 0;
}
-
- if (m_markerMid == resource) {
- m_markerMid->invalidateClients();
- m_markerMid = 0;
+ if (m_markerData->markerMid == resource) {
+ m_markerData->markerMid->invalidateClients();
+ m_markerData->markerMid = 0;
}
-
- if (m_markerEnd == resource) {
- m_markerEnd->invalidateClients();
- m_markerEnd = 0;
+ if (m_markerData->markerEnd == resource) {
+ m_markerData->markerEnd->invalidateClients();
+ m_markerData->markerEnd = 0;
}
break;
case PatternResourceType:
case LinearGradientResourceType:
case RadialGradientResourceType:
- if (m_fill == resource) {
- m_fill->invalidateClients();
- m_fill = 0;
+ if (!m_fillStrokeData)
+ break;
+ if (m_fillStrokeData->fill == resource) {
+ m_fillStrokeData->fill->invalidateClients();
+ m_fillStrokeData->fill = 0;
}
-
- if (m_stroke == resource) {
- m_stroke->invalidateClients();
- m_stroke = 0;
+ if (m_fillStrokeData->stroke == resource) {
+ m_fillStrokeData->stroke->invalidateClients();
+ m_fillStrokeData->stroke = 0;
}
break;
#if ENABLE(FILTERS)
case FilterResourceType:
- if (m_filter == resource) {
- m_filter->invalidateClients();
- m_filter = 0;
+ if (!m_clipperFilterMaskerData)
+ break;
+ if (m_clipperFilterMaskerData->filter == resource) {
+ m_clipperFilterMaskerData->filter->invalidateClients();
+ m_clipperFilterMaskerData->filter = 0;
}
break;
#endif
case ClipperResourceType:
- if (m_clipper == resource) {
- m_clipper->invalidateClients();
- m_clipper = 0;
+ if (!m_clipperFilterMaskerData)
+ break;
+ if (m_clipperFilterMaskerData->clipper == resource) {
+ m_clipperFilterMaskerData->clipper->invalidateClients();
+ m_clipperFilterMaskerData->clipper = 0;
}
break;
case SolidColorResourceType:
@@ -250,77 +397,212 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer* resource)
void SVGResources::buildSetOfResources(HashSet<RenderSVGResourceContainer*>& set)
{
- // Ordinary resources
- if (m_clipper)
- set.add(m_clipper);
+ if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData && !m_linkedResource)
+ return;
+
+ if (m_linkedResource) {
+ ASSERT(!m_clipperFilterMaskerData);
+ ASSERT(!m_markerData);
+ ASSERT(!m_fillStrokeData);
+ set.add(m_linkedResource);
+ return;
+ }
+
+ if (m_clipperFilterMaskerData) {
+ if (m_clipperFilterMaskerData->clipper)
+ set.add(m_clipperFilterMaskerData->clipper);
#if ENABLE(FILTERS)
- if (m_filter)
- set.add(m_filter);
+ if (m_clipperFilterMaskerData->filter)
+ set.add(m_clipperFilterMaskerData->filter);
#endif
- if (m_markerStart)
- set.add(m_markerStart);
- if (m_markerMid)
- set.add(m_markerMid);
- if (m_markerEnd)
- set.add(m_markerEnd);
- if (m_masker)
- set.add(m_masker);
-
- // Paint servers
- if (m_fill)
- set.add(m_fill);
- if (m_stroke)
- set.add(m_stroke);
+ if (m_clipperFilterMaskerData->masker)
+ set.add(m_clipperFilterMaskerData->masker);
+ }
+
+ if (m_markerData) {
+ if (m_markerData->markerStart)
+ set.add(m_markerData->markerStart);
+ if (m_markerData->markerMid)
+ set.add(m_markerData->markerMid);
+ if (m_markerData->markerEnd)
+ set.add(m_markerData->markerEnd);
+ }
+
+ if (m_fillStrokeData) {
+ if (m_fillStrokeData->fill)
+ set.add(m_fillStrokeData->fill);
+ if (m_fillStrokeData->stroke)
+ set.add(m_fillStrokeData->stroke);
+ }
+}
+
+bool SVGResources::setClipper(RenderSVGResourceClipper* clipper)
+{
+ if (!clipper)
+ return false;
+
+ if (!m_clipperFilterMaskerData)
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+ m_clipperFilterMaskerData->clipper = clipper;
+ return true;
}
void SVGResources::resetClipper()
{
- ASSERT(m_clipper);
- m_clipper = 0;
+ ASSERT(m_clipperFilterMaskerData);
+ ASSERT(m_clipperFilterMaskerData->clipper);
+ m_clipperFilterMaskerData->clipper = 0;
}
#if ENABLE(FILTERS)
+bool SVGResources::setFilter(RenderSVGResourceFilter* filter)
+{
+ if (!filter)
+ return false;
+
+ if (!m_clipperFilterMaskerData)
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+ m_clipperFilterMaskerData->filter = filter;
+ return true;
+}
+
void SVGResources::resetFilter()
{
- ASSERT(m_filter);
- m_filter = 0;
+ ASSERT(m_clipperFilterMaskerData);
+ ASSERT(m_clipperFilterMaskerData->filter);
+ m_clipperFilterMaskerData->filter = 0;
}
#endif
+bool SVGResources::setMarkerStart(RenderSVGResourceMarker* markerStart)
+{
+ if (!markerStart)
+ return false;
+
+ if (!m_markerData)
+ m_markerData = MarkerData::create();
+
+ m_markerData->markerStart = markerStart;
+ return true;
+}
+
void SVGResources::resetMarkerStart()
{
- ASSERT(m_markerStart);
- m_markerStart = 0;
+ ASSERT(m_markerData);
+ ASSERT(m_markerData->markerStart);
+ m_markerData->markerStart = 0;
+}
+
+bool SVGResources::setMarkerMid(RenderSVGResourceMarker* markerMid)
+{
+ if (!markerMid)
+ return false;
+
+ if (!m_markerData)
+ m_markerData = MarkerData::create();
+
+ m_markerData->markerMid = markerMid;
+ return true;
}
void SVGResources::resetMarkerMid()
{
- ASSERT(m_markerMid);
- m_markerMid = 0;
+ ASSERT(m_markerData);
+ ASSERT(m_markerData->markerMid);
+ m_markerData->markerMid = 0;
+}
+
+bool SVGResources::setMarkerEnd(RenderSVGResourceMarker* markerEnd)
+{
+ if (!markerEnd)
+ return false;
+
+ if (!m_markerData)
+ m_markerData = MarkerData::create();
+
+ m_markerData->markerEnd = markerEnd;
+ return true;
}
void SVGResources::resetMarkerEnd()
{
- ASSERT(m_markerEnd);
- m_markerEnd = 0;
+ ASSERT(m_markerData);
+ ASSERT(m_markerData->markerEnd);
+ m_markerData->markerEnd = 0;
+}
+
+bool SVGResources::setMasker(RenderSVGResourceMasker* masker)
+{
+ if (!masker)
+ return false;
+
+ if (!m_clipperFilterMaskerData)
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
+
+ m_clipperFilterMaskerData->masker = masker;
+ return true;
}
void SVGResources::resetMasker()
{
- ASSERT(m_masker);
- m_masker = 0;
+ ASSERT(m_clipperFilterMaskerData);
+ ASSERT(m_clipperFilterMaskerData->masker);
+ m_clipperFilterMaskerData->masker = 0;
+}
+
+bool SVGResources::setFill(RenderSVGResourceContainer* fill)
+{
+ if (!fill)
+ return false;
+
+ if (!m_fillStrokeData)
+ m_fillStrokeData = FillStrokeData::create();
+
+ m_fillStrokeData->fill = fill;
+ return true;
}
void SVGResources::resetFill()
{
- ASSERT(m_fill);
- m_fill = 0;
+ ASSERT(m_fillStrokeData);
+ ASSERT(m_fillStrokeData->fill);
+ m_fillStrokeData->fill = 0;
+}
+
+bool SVGResources::setStroke(RenderSVGResourceContainer* stroke)
+{
+ if (!stroke)
+ return false;
+
+ if (!m_fillStrokeData)
+ m_fillStrokeData = FillStrokeData::create();
+
+ m_fillStrokeData->stroke = stroke;
+ return true;
}
void SVGResources::resetStroke()
{
- ASSERT(m_stroke);
- m_stroke = 0;
+ ASSERT(m_fillStrokeData);
+ ASSERT(m_fillStrokeData->stroke);
+ m_fillStrokeData->stroke = 0;
+}
+
+bool SVGResources::setLinkedResource(RenderSVGResourceContainer* linkedResource)
+{
+ if (!linkedResource)
+ return false;
+
+ m_linkedResource = linkedResource;
+ return true;
+}
+
+void SVGResources::resetLinkedResource()
+{
+ ASSERT(m_linkedResource);
+ m_linkedResource = 0;
}
#ifndef NDEBUG
@@ -334,24 +616,35 @@ void SVGResources::dump(const RenderObject* object)
object->node()->showTreeForThis();
fprintf(stderr, "\n | List of resources:\n");
- if (m_clipper)
- fprintf(stderr, " |-> Clipper : %p (node=%p)\n", m_clipper, m_clipper->node());
+ if (m_clipperFilterMaskerData) {
+ if (RenderSVGResourceClipper* clipper = m_clipperFilterMaskerData->clipper)
+ fprintf(stderr, " |-> Clipper : %p (node=%p)\n", clipper, clipper->node());
#if ENABLE(FILTERS)
- if (m_filter)
- fprintf(stderr, " |-> Filter : %p (node=%p)\n", m_filter, m_filter->node());
+ if (RenderSVGResourceFilter* filter = m_clipperFilterMaskerData->filter)
+ fprintf(stderr, " |-> Filter : %p (node=%p)\n", filter, filter->node());
#endif
- if (m_markerStart)
- fprintf(stderr, " |-> MarkerStart: %p (node=%p)\n", m_markerStart, m_markerStart->node());
- if (m_markerMid)
- fprintf(stderr, " |-> MarkerMid : %p (node=%p)\n", m_markerMid, m_markerMid->node());
- if (m_markerEnd)
- fprintf(stderr, " |-> MarkerEnd : %p (node=%p)\n", m_markerEnd, m_markerEnd->node());
- if (m_masker)
- fprintf(stderr, " |-> Masker : %p (node=%p)\n", m_masker, m_masker->node());
- if (m_fill)
- fprintf(stderr, " |-> Fill : %p (node=%p)\n", m_fill, m_fill->node());
- if (m_stroke)
- fprintf(stderr, " |-> Stroke : %p (node=%p)\n", m_stroke, m_stroke->node());
+ if (RenderSVGResourceMasker* masker = m_clipperFilterMaskerData->masker)
+ fprintf(stderr, " |-> Masker : %p (node=%p)\n", masker, masker->node());
+ }
+
+ if (m_markerData) {
+ if (RenderSVGResourceMarker* markerStart = m_markerData->markerStart)
+ fprintf(stderr, " |-> MarkerStart: %p (node=%p)\n", markerStart, markerStart->node());
+ if (RenderSVGResourceMarker* markerMid = m_markerData->markerMid)
+ fprintf(stderr, " |-> MarkerMid : %p (node=%p)\n", markerMid, markerMid->node());
+ if (RenderSVGResourceMarker* markerEnd = m_markerData->markerEnd)
+ fprintf(stderr, " |-> MarkerEnd : %p (node=%p)\n", markerEnd, markerEnd->node());
+ }
+
+ if (m_fillStrokeData) {
+ if (RenderSVGResourceContainer* fill = m_fillStrokeData->fill)
+ fprintf(stderr, " |-> Fill : %p (node=%p)\n", fill, fill->node());
+ if (RenderSVGResourceContainer* stroke = m_fillStrokeData->stroke)
+ fprintf(stderr, " |-> Stroke : %p (node=%p)\n", stroke, stroke->node());
+ }
+
+ if (m_linkedResource)
+ fprintf(stderr, " |-> xlink:href : %p (node=%p)\n", m_linkedResource, m_linkedResource->node());
}
#endif
diff --git a/WebCore/rendering/SVGResources.h b/WebCore/rendering/SVGResources.h
index 57a4140..a07a990 100644
--- a/WebCore/rendering/SVGResources.h
+++ b/WebCore/rendering/SVGResources.h
@@ -23,6 +23,8 @@
#if ENABLE(SVG)
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -43,18 +45,21 @@ public:
bool buildCachedResources(const RenderObject*, const SVGRenderStyle*);
// Ordinary resources
- RenderSVGResourceClipper* clipper() const { return m_clipper; }
+ RenderSVGResourceClipper* clipper() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->clipper : 0; }
#if ENABLE(FILTERS)
- RenderSVGResourceFilter* filter() const { return m_filter; }
+ RenderSVGResourceFilter* filter() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->filter : 0; }
#endif
- RenderSVGResourceMarker* markerStart() const { return m_markerStart; }
- RenderSVGResourceMarker* markerMid() const { return m_markerMid; }
- RenderSVGResourceMarker* markerEnd() const { return m_markerEnd; }
- RenderSVGResourceMasker* masker() const { return m_masker; }
+ RenderSVGResourceMarker* markerStart() const { return m_markerData ? m_markerData->markerStart : 0; }
+ RenderSVGResourceMarker* markerMid() const { return m_markerData ? m_markerData->markerMid : 0; }
+ RenderSVGResourceMarker* markerEnd() const { return m_markerData ? m_markerData->markerEnd : 0; }
+ RenderSVGResourceMasker* masker() const { return m_clipperFilterMaskerData ? m_clipperFilterMaskerData->masker : 0; }
// Paint servers
- RenderSVGResourceContainer* fill() const { return m_fill; }
- RenderSVGResourceContainer* stroke() const { return m_stroke; }
+ RenderSVGResourceContainer* fill() const { return m_fillStrokeData ? m_fillStrokeData->fill : 0; }
+ RenderSVGResourceContainer* stroke() const { return m_fillStrokeData ? m_fillStrokeData->stroke : 0; }
+
+ // Chainable resources - linked through xlink:href
+ RenderSVGResourceContainer* linkedResource() const { return m_linkedResource; }
void buildSetOfResources(HashSet<RenderSVGResourceContainer*>&);
@@ -80,21 +85,92 @@ private:
void resetMasker();
void resetFill();
void resetStroke();
+ void resetLinkedResource();
private:
- // Ordinary resources
- RenderSVGResourceClipper* m_clipper;
+ bool setClipper(RenderSVGResourceClipper*);
+#if ENABLE(FILTERS)
+ bool setFilter(RenderSVGResourceFilter*);
+#endif
+ bool setMarkerStart(RenderSVGResourceMarker*);
+ bool setMarkerMid(RenderSVGResourceMarker*);
+ bool setMarkerEnd(RenderSVGResourceMarker*);
+ bool setMasker(RenderSVGResourceMasker*);
+ bool setFill(RenderSVGResourceContainer*);
+ bool setStroke(RenderSVGResourceContainer*);
+ bool setLinkedResource(RenderSVGResourceContainer*);
+
+ // From SVG 1.1 2nd Edition
+ // clipper: 'container elements' and 'graphics elements'
+ // filter: 'container elements' and 'graphics elements'
+ // masker: 'container elements' and 'graphics elements'
+ // -> a, circle, defs, ellipse, glyph, g, image, line, marker, mask, missing-glyph, path, pattern, polygon, polyline, rect, svg, switch, symbol, text, use
+ struct ClipperFilterMaskerData {
+ ClipperFilterMaskerData()
+ : clipper(0)
#if ENABLE(FILTERS)
- RenderSVGResourceFilter* m_filter;
+ , filter(0)
#endif
- RenderSVGResourceMarker* m_markerStart;
- RenderSVGResourceMarker* m_markerMid;
- RenderSVGResourceMarker* m_markerEnd;
- RenderSVGResourceMasker* m_masker;
+ , masker(0)
+ {
+ }
- // Paint servers
- RenderSVGResourceContainer* m_fill;
- RenderSVGResourceContainer* m_stroke;
+ static PassOwnPtr<ClipperFilterMaskerData> create()
+ {
+ return new ClipperFilterMaskerData;
+ }
+
+ RenderSVGResourceClipper* clipper;
+#if ENABLE(FILTERS)
+ RenderSVGResourceFilter* filter;
+#endif
+ RenderSVGResourceMasker* masker;
+ };
+
+ // From SVG 1.1 2nd Edition
+ // marker: line, path, polygon, polyline
+ struct MarkerData {
+ MarkerData()
+ : markerStart(0)
+ , markerMid(0)
+ , markerEnd(0)
+ {
+ }
+
+ static PassOwnPtr<MarkerData> create()
+ {
+ return new MarkerData;
+ }
+
+ RenderSVGResourceMarker* markerStart;
+ RenderSVGResourceMarker* markerMid;
+ RenderSVGResourceMarker* markerEnd;
+ };
+
+ // From SVG 1.1 2nd Edition
+ // fill: 'shapes' and 'text content elements'
+ // stroke: 'shapes' and 'text content elements'
+ // -> altGlyph, circle, ellipse, line, path, polygon, polyline, rect, text, textPath, tref, tspan
+ struct FillStrokeData {
+ FillStrokeData()
+ : fill(0)
+ , stroke(0)
+ {
+ }
+
+ static PassOwnPtr<FillStrokeData> create()
+ {
+ return new FillStrokeData;
+ }
+
+ RenderSVGResourceContainer* fill;
+ RenderSVGResourceContainer* stroke;
+ };
+
+ OwnPtr<ClipperFilterMaskerData> m_clipperFilterMaskerData;
+ OwnPtr<MarkerData> m_markerData;
+ OwnPtr<FillStrokeData> m_fillStrokeData;
+ RenderSVGResourceContainer* m_linkedResource;
};
}
diff --git a/WebCore/rendering/SVGResourcesCache.cpp b/WebCore/rendering/SVGResourcesCache.cpp
index 46586cc..b922b44 100644
--- a/WebCore/rendering/SVGResourcesCache.cpp
+++ b/WebCore/rendering/SVGResourcesCache.cpp
@@ -131,17 +131,7 @@ void SVGResourcesCache::clientStyleChanged(RenderObject* renderer, StyleDifferen
return;
clientUpdatedFromElement(renderer, newStyle);
-
- // Invalidate resources in ancestor chain, if needed.
- RenderObject* parent = renderer->parent();
- while (parent) {
- if (parent->isSVGResourceContainer()) {
- parent->toRenderSVGResourceContainer()->invalidateClients();
- break;
- }
-
- parent = parent->parent();
- }
+ RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
}
void SVGResourcesCache::clientUpdatedFromElement(RenderObject* renderer, const RenderStyle* newStyle)
diff --git a/WebCore/rendering/SVGResourcesCycleSolver.cpp b/WebCore/rendering/SVGResourcesCycleSolver.cpp
index e150144..ec2e036 100644
--- a/WebCore/rendering/SVGResourcesCycleSolver.cpp
+++ b/WebCore/rendering/SVGResourcesCycleSolver.cpp
@@ -94,6 +94,7 @@ bool SVGResourcesCycleSolver::resourceContainsCycles(RenderObject* renderer) con
return false;
}
+<<<<<<< HEAD
static inline String targetReferenceFromResource(SVGElement* element, bool& isValid)
{
String target;
@@ -177,6 +178,8 @@ bool SVGResourcesCycleSolver::chainableResourceContainsCycles(RenderSVGResourceC
return false;
}
+=======
+>>>>>>> webkit.org at r64523
void SVGResourcesCycleSolver::resolveCycles()
{
ASSERT(m_allResources.isEmpty());
@@ -221,6 +224,10 @@ void SVGResourcesCycleSolver::resolveCycles()
for (HashSet<RenderSVGResourceContainer*>::iterator it = parentResources.begin(); it != end; ++it)
m_allResources.add(*it);
+ // If we're a resource, add ourselves to the HashSet.
+ if (m_renderer->isSVGResourceContainer())
+ m_allResources.add(m_renderer->toRenderSVGResourceContainer());
+
ASSERT(!m_allResources.isEmpty());
// The job of this function is to determine wheter any of the 'resources' associated with the given 'renderer'
@@ -228,22 +235,6 @@ void SVGResourcesCycleSolver::resolveCycles()
end = localResources.end();
for (HashSet<RenderSVGResourceContainer*>::iterator it = localResources.begin(); it != end; ++it) {
RenderSVGResourceContainer* resource = *it;
-
- // Special handling for resources that can be chained using xlink:href - need to detect cycles as well!
- switch (resource->resourceType()) {
- case PatternResourceType:
- case LinearGradientResourceType:
- case RadialGradientResourceType:
- case FilterResourceType:
- if (chainableResourceContainsCycles(resource)) {
- breakCycle(resource);
- continue;
- }
- break;
- default:
- break;
- }
-
if (parentResources.contains(resource) || resourceContainsCycles(resource))
breakCycle(resource);
}
@@ -259,6 +250,11 @@ void SVGResourcesCycleSolver::resolveCycles()
void SVGResourcesCycleSolver::breakCycle(RenderSVGResourceContainer* resourceLeadingToCycle)
{
ASSERT(resourceLeadingToCycle);
+ if (resourceLeadingToCycle == m_resources->linkedResource()) {
+ m_resources->resetLinkedResource();
+ return;
+ }
+
switch (resourceLeadingToCycle->resourceType()) {
case MaskerResourceType:
ASSERT(resourceLeadingToCycle == m_resources->masker());
diff --git a/WebCore/rendering/SVGResourcesCycleSolver.h b/WebCore/rendering/SVGResourcesCycleSolver.h
index 1f49354..e63ee63 100644
--- a/WebCore/rendering/SVGResourcesCycleSolver.h
+++ b/WebCore/rendering/SVGResourcesCycleSolver.h
@@ -38,7 +38,6 @@ public:
private:
bool resourceContainsCycles(RenderObject*) const;
- bool chainableResourceContainsCycles(RenderSVGResourceContainer*) const;
void breakCycle(RenderSVGResourceContainer*);
RenderObject* m_renderer;
diff --git a/WebCore/rendering/style/SVGRenderStyle.cpp b/WebCore/rendering/style/SVGRenderStyle.cpp
index 93e50cc..2a9003c 100644
--- a/WebCore/rendering/style/SVGRenderStyle.cpp
+++ b/WebCore/rendering/style/SVGRenderStyle.cpp
@@ -165,13 +165,14 @@ StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
// Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
if (stroke != other->stroke) {
if (stroke->width != other->stroke->width
+ || stroke->paint != other->stroke->paint
|| stroke->miterLimit != other->stroke->miterLimit
|| stroke->dashArray != other->stroke->dashArray
|| stroke->dashOffset != other->stroke->dashOffset)
return StyleDifferenceLayout;
- // Only these two cases remain, where we only need a repaint.
- ASSERT(stroke->paint != other->stroke->paint || stroke->opacity != other->stroke->opacity);
+ // Only the stroke-opacity case remains, where we only need a repaint.
+ ASSERT(stroke->opacity != other->stroke->opacity);
return StyleDifferenceRepaint;
}
diff --git a/WebCore/rendering/style/SVGRenderStyle.h b/WebCore/rendering/style/SVGRenderStyle.h
index c87dd2b..c1d72e9 100644
--- a/WebCore/rendering/style/SVGRenderStyle.h
+++ b/WebCore/rendering/style/SVGRenderStyle.h
@@ -56,59 +56,237 @@ public:
bool operator==(const SVGRenderStyle&) const;
bool operator!=(const SVGRenderStyle& o) const { return !(*this == o); }
- // SVG CSS Properties
- SVG_RS_DEFINE_ATTRIBUTE(EAlignmentBaseline, AlignmentBaseline, alignmentBaseline, AB_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE(EDominantBaseline, DominantBaseline, dominantBaseline, DB_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE(EBaselineShift, BaselineShift, baselineShift, BS_BASELINE)
- SVG_RS_DEFINE_ATTRIBUTE(EVectorEffect, VectorEffect, vectorEffect, VE_NONE)
-
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(LineCap, CapStyle, capStyle, ButtCap)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(WindRule, ClipRule, clipRule, RULE_NONZERO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorInterpolation, ColorInterpolation, colorInterpolation, CI_SRGB)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorInterpolation, ColorInterpolationFilters, colorInterpolationFilters, CI_LINEARRGB)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EColorRendering, ColorRendering, colorRendering, CR_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(WindRule, FillRule, fillRule, RULE_NONZERO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EImageRendering, ImageRendering, imageRendering, IR_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(LineJoin, JoinStyle, joinStyle, MiterJoin)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EShapeRendering, ShapeRendering, shapeRendering, SR_AUTO)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(ETextAnchor, TextAnchor, textAnchor, TA_START)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EWritingMode, WritingMode, writingMode, WM_LRTB)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EGlyphOrientation, GlyphOrientationHorizontal, glyphOrientationHorizontal, GO_0DEG)
- SVG_RS_DEFINE_ATTRIBUTE_INHERITED(EGlyphOrientation, GlyphOrientationVertical, glyphOrientationVertical, GO_AUTO)
-
- // SVG CSS Properties (using DataRef's)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, fill, opacity, FillOpacity, fillOpacity, 1.0f)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(SVGPaint, fill, paint, FillPaint, fillPaint, SVGPaint::defaultFill())
-
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stroke, opacity, StrokeOpacity, strokeOpacity, 1.0f)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(SVGPaint, stroke, paint, StrokePaint, strokePaint, SVGPaint::defaultStroke())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValueList, stroke, dashArray, StrokeDashArray, strokeDashArray, 0)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stroke, miterLimit, StrokeMiterLimit, strokeMiterLimit, 4.0f)
+ // Initial values for all the properties
+ static EAlignmentBaseline initialAlignmentBaseline() { return AB_AUTO; }
+ static EDominantBaseline initialDominantBaseline() { return DB_AUTO; }
+ static EBaselineShift initialBaselineShift() { return BS_BASELINE; }
+ static EVectorEffect initialVectorEffect() { return VE_NONE; }
+ static LineCap initialCapStyle() { return ButtCap; }
+ static WindRule initialClipRule() { return RULE_NONZERO; }
+ static EColorInterpolation initialColorInterpolation() { return CI_SRGB; }
+ static EColorInterpolation initialColorInterpolationFilters() { return CI_LINEARRGB; }
+ static EColorRendering initialColorRendering() { return CR_AUTO; }
+ static WindRule initialFillRule() { return RULE_NONZERO; }
+ static EImageRendering initialImageRendering() { return IR_AUTO; }
+ static LineJoin initialJoinStyle() { return MiterJoin; }
+ static EShapeRendering initialShapeRendering() { return SR_AUTO; }
+ static ETextAnchor initialTextAnchor() { return TA_START; }
+ static EWritingMode initialWritingMode() { return WM_LRTB; }
+ static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; }
+ static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; }
+ static float initialFillOpacity() { return 1.0f; }
+ static SVGPaint* initialFillPaint() { return SVGPaint::defaultFill(); }
+ static float initialStrokeOpacity() { return 1.0f; }
+ static SVGPaint* initialStrokePaint() { return SVGPaint::defaultStroke(); }
+ static CSSValueList* initialStrokeDashArray() { return 0; }
+ static float initialStrokeMiterLimit() { return 4.0f; }
+ static CSSValue* initialStrokeWidth() { return 0; }
+ static CSSValue* initialStrokeDashOffset() { return 0; };
+ static CSSValue* initialKerning() { return 0; }
+ static float initialStopOpacity() { return 1.0f; }
+ static Color initialStopColor() { return Color(0, 0, 0); }
+ static float initialFloodOpacity() { return 1.0f; }
+ static Color initialFloodColor() { return Color(0, 0, 0); }
+ static Color initialLightingColor() { return Color(255, 255, 255); }
+ static CSSValue* initialBaselineShiftValue() { return 0; }
+ static ShadowData* initialShadow() { return 0; }
+ static String initialClipperResource() { return String(); }
+ static String initialFilterResource() { return String(); }
+ static String initialMaskerResource() { return String(); }
+ static String initialMarkerStartResource() { return String(); }
+ static String initialMarkerMidResource() { return String(); }
+ static String initialMarkerEndResource() { return String(); }
+
+ // SVG CSS Property setters
+ void setAlignmentBaseline(EAlignmentBaseline val) { svg_noninherited_flags.f._alignmentBaseline = val; }
+ void setDominantBaseline(EDominantBaseline val) { svg_noninherited_flags.f._dominantBaseline = val; }
+ void setBaselineShift(EBaselineShift val) { svg_noninherited_flags.f._baselineShift = val; }
+ void setVectorEffect(EVectorEffect val) { svg_noninherited_flags.f._vectorEffect = val; }
+ void setCapStyle(LineCap val) { svg_inherited_flags._capStyle = val; }
+ void setClipRule(WindRule val) { svg_inherited_flags._clipRule = val; }
+ void setColorInterpolation(EColorInterpolation val) { svg_inherited_flags._colorInterpolation = val; }
+ void setColorInterpolationFilters(EColorInterpolation val) { svg_inherited_flags._colorInterpolationFilters = val; }
+ void setColorRendering(EColorRendering val) { svg_inherited_flags._colorRendering = val; }
+ void setFillRule(WindRule val) { svg_inherited_flags._fillRule = val; }
+ void setImageRendering(EImageRendering val) { svg_inherited_flags._imageRendering = val; }
+ void setJoinStyle(LineJoin val) { svg_inherited_flags._joinStyle = val; }
+ void setShapeRendering(EShapeRendering val) { svg_inherited_flags._shapeRendering = val; }
+ void setTextAnchor(ETextAnchor val) { svg_inherited_flags._textAnchor = val; }
+ void setWritingMode(EWritingMode val) { svg_inherited_flags._writingMode = val; }
+ void setGlyphOrientationHorizontal(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationHorizontal = val; }
+ void setGlyphOrientationVertical(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationVertical = val; }
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, stroke, width, StrokeWidth, strokeWidth, 0)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, stroke, dashOffset, StrokeDashOffset, strokeDashOffset, 0);
+ void setFillOpacity(float obj)
+ {
+ if (!(fill->opacity == obj))
+ fill.access()->opacity = obj;
+ }
+
+ void setFillPaint(PassRefPtr<SVGPaint> obj)
+ {
+ if (!(fill->paint == obj))
+ fill.access()->paint = obj;
+ }
+
+ void setStrokeOpacity(float obj)
+ {
+ if (!(stroke->opacity == obj))
+ stroke.access()->opacity = obj;
+ }
+
+ void setStrokePaint(PassRefPtr<SVGPaint> obj)
+ {
+ if (!(stroke->paint == obj))
+ stroke.access()->paint = obj;
+ }
+
+ void setStrokeDashArray(PassRefPtr<CSSValueList> obj)
+ {
+ if (!(stroke->dashArray == obj))
+ stroke.access()->dashArray = obj;
+ }
+
+ void setStrokeMiterLimit(float obj)
+ {
+ if (!(stroke->miterLimit == obj))
+ stroke.access()->miterLimit = obj;
+ }
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, text, kerning, Kerning, kerning, 0)
+ void setStrokeWidth(PassRefPtr<CSSValue> obj)
+ {
+ if (!(stroke->width == obj))
+ stroke.access()->width = obj;
+ }
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, stops, opacity, StopOpacity, stopOpacity, 1.0f)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, stops, color, StopColor, stopColor, Color(0, 0, 0))
+ void setStrokeDashOffset(PassRefPtr<CSSValue> obj)
+ {
+ if (!(stroke->dashOffset == obj))
+ stroke.access()->dashOffset = obj;
+ }
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(float, misc, floodOpacity, FloodOpacity, floodOpacity, 1.0f)
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, floodColor, FloodColor, floodColor, Color(0, 0, 0))
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Color, misc, lightingColor, LightingColor, lightingColor, Color(255, 255, 255))
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(CSSValue, misc, baselineShiftValue, BaselineShiftValue, baselineShiftValue, 0)
+ void setKerning(PassRefPtr<CSSValue> obj)
+ {
+ if (!(text->kerning == obj))
+ text.access()->kerning = obj;
+ }
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_OWNPTR(ShadowData, shadowSVG, shadow, Shadow, shadow, 0)
+ void setStopOpacity(float obj)
+ {
+ if (!(stops->opacity == obj))
+ stops.access()->opacity = obj;
+ }
- // Non-inherited resources
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, resources, clipper, ClipperResource, clipperResource, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, resources, filter, FilterResource, filterResource, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, resources, masker, MaskerResource, maskerResource, String())
+ void setStopColor(Color obj)
+ {
+ if (!(stops->color == obj))
+ stops.access()->color = obj;
+ }
+
+ void setFloodOpacity(float obj)
+ {
+ if (!(misc->floodOpacity == obj))
+ misc.access()->floodOpacity = obj;
+ }
+
+ void setFloodColor(Color obj)
+ {
+ if (!(misc->floodColor == obj))
+ misc.access()->floodColor = obj;
+ }
+
+ void setLightingColor(Color obj)
+ {
+ if (!(misc->lightingColor == obj))
+ misc.access()->lightingColor = obj;
+ }
+
+ void setBaselineShiftValue(PassRefPtr<CSSValue> obj)
+ {
+ if (!(misc->baselineShiftValue == obj))
+ misc.access()->baselineShiftValue = obj;
+ }
+
+ void setShadow(PassOwnPtr<ShadowData> obj) { shadowSVG.access()->shadow = obj;
+ }
+
+ // Setters for non-inherited resources
+ void setClipperResource(String obj)
+ {
+ if (!(resources->clipper == obj))
+ resources.access()->clipper = obj;
+ }
+
+ void setFilterResource(String obj)
+ {
+ if (!(resources->filter == obj))
+ resources.access()->filter = obj;
+ }
+
+ void setMaskerResource(String obj)
+ {
+ if (!(resources->masker == obj))
+ resources.access()->masker = obj;
+ }
+
+ // Setters for inherited resources
+ void setMarkerStartResource(String obj)
+ {
+ if (!(inheritedResources->markerStart == obj))
+ inheritedResources.access()->markerStart = obj;
+ }
+
+ void setMarkerMidResource(String obj)
+ {
+ if (!(inheritedResources->markerMid == obj))
+ inheritedResources.access()->markerMid = obj;
+ }
+
+ void setMarkerEndResource(String obj)
+ {
+ if (!(inheritedResources->markerEnd == obj))
+ inheritedResources.access()->markerEnd = obj;
+ }
- // Inherited resources
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, inheritedResources, markerStart, MarkerStartResource, markerStartResource, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, inheritedResources, markerMid, MarkerMidResource, markerMidResource, String())
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(String, inheritedResources, markerEnd, MarkerEndResource, markerEndResource, String())
+ // Read accessors for all the properties
+ EAlignmentBaseline alignmentBaseline() const { return (EAlignmentBaseline) svg_noninherited_flags.f._alignmentBaseline; }
+ EDominantBaseline dominantBaseline() const { return (EDominantBaseline) svg_noninherited_flags.f._dominantBaseline; }
+ EBaselineShift baselineShift() const { return (EBaselineShift) svg_noninherited_flags.f._baselineShift; }
+ EVectorEffect vectorEffect() const { return (EVectorEffect) svg_noninherited_flags.f._vectorEffect; }
+ LineCap capStyle() const { return (LineCap) svg_inherited_flags._capStyle; }
+ WindRule clipRule() const { return (WindRule) svg_inherited_flags._clipRule; }
+ EColorInterpolation colorInterpolation() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolation; }
+ EColorInterpolation colorInterpolationFilters() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolationFilters; }
+ EColorRendering colorRendering() const { return (EColorRendering) svg_inherited_flags._colorRendering; }
+ WindRule fillRule() const { return (WindRule) svg_inherited_flags._fillRule; }
+ EImageRendering imageRendering() const { return (EImageRendering) svg_inherited_flags._imageRendering; }
+ LineJoin joinStyle() const { return (LineJoin) svg_inherited_flags._joinStyle; }
+ EShapeRendering shapeRendering() const { return (EShapeRendering) svg_inherited_flags._shapeRendering; }
+ ETextAnchor textAnchor() const { return (ETextAnchor) svg_inherited_flags._textAnchor; }
+ EWritingMode writingMode() const { return (EWritingMode) svg_inherited_flags._writingMode; }
+ EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationHorizontal; }
+ EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationVertical; }
+ float fillOpacity() const { return fill->opacity; }
+ SVGPaint* fillPaint() const { return fill->paint.get(); }
+ float strokeOpacity() const { return stroke->opacity; }
+ SVGPaint* strokePaint() const { return stroke->paint.get(); }
+ CSSValueList* strokeDashArray() const { return stroke->dashArray.get(); }
+ float strokeMiterLimit() const { return stroke->miterLimit; }
+ CSSValue* strokeWidth() const { return stroke->width.get(); }
+ CSSValue* strokeDashOffset() const { return stroke->dashOffset.get(); }
+ CSSValue* kerning() const { return text->kerning.get(); }
+ float stopOpacity() const { return stops->opacity; }
+ Color stopColor() const { return stops->color; }
+ float floodOpacity() const { return misc->floodOpacity; }
+ Color floodColor() const { return misc->floodColor; }
+ Color lightingColor() const { return misc->lightingColor; }
+ CSSValue* baselineShiftValue() const { return misc->baselineShiftValue.get(); }
+ ShadowData* shadow() const { return shadowSVG->shadow.get(); }
+ String clipperResource() const { return resources->clipper; }
+ String filterResource() const { return resources->filter; }
+ String maskerResource() const { return resources->masker; }
+ String markerStartResource() const { return inheritedResources->markerStart; }
+ String markerMidResource() const { return inheritedResources->markerMid; }
+ String markerEndResource() const { return inheritedResources->markerEnd; }
// convenience
bool hasClipper() const { return !clipperResource().isEmpty(); }
diff --git a/WebCore/rendering/style/SVGRenderStyleDefs.h b/WebCore/rendering/style/SVGRenderStyleDefs.h
index 5173894..adb890c 100644
--- a/WebCore/rendering/style/SVGRenderStyleDefs.h
+++ b/WebCore/rendering/style/SVGRenderStyleDefs.h
@@ -38,46 +38,6 @@
#include <wtf/RefCounted.h>
#include <wtf/RefPtr.h>
-// Helper macros for 'SVGRenderStyle'
-#define SVG_RS_DEFINE_ATTRIBUTE(Data, Type, Name, Initial) \
- void set##Type(Data val) { svg_noninherited_flags.f._##Name = val; } \
- Data Name() const { return (Data) svg_noninherited_flags.f._##Name; } \
- static Data initial##Type() { return Initial; }
-
-#define SVG_RS_DEFINE_ATTRIBUTE_INHERITED(Data, Type, Name, Initial) \
- void set##Type(Data val) { svg_inherited_flags._##Name = val; } \
- Data Name() const { return (Data) svg_inherited_flags._##Name; } \
- static Data initial##Type() { return Initial; }
-
-// "Helper" macros for SVG's RenderStyle properties
-// FIXME: These are impossible to work with or debug.
-#define SVG_RS_DEFINE_ATTRIBUTE_DATAREF(Data, Group, Variable, Type, Name) \
- Data Name() const { return Group->Variable; } \
- void set##Type(Data obj) { SVG_RS_SET_VARIABLE(Group, Variable, obj) }
-
-#define SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL(Data, Group, Variable, Type, Name, Initial) \
- SVG_RS_DEFINE_ATTRIBUTE_DATAREF(Data, Group, Variable, Type, Name) \
- static Data initial##Type() { return Initial; }
-
-#define SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_REFCOUNTED(Data, Group, Variable, Type, Name, Initial) \
- Data* Name() const { return Group->Variable.get(); } \
- void set##Type(PassRefPtr<Data> obj) { \
- if (!(Group->Variable == obj)) \
- Group.access()->Variable = obj; \
- } \
- static Data* initial##Type() { return Initial; }
-
-#define SVG_RS_DEFINE_ATTRIBUTE_DATAREF_WITH_INITIAL_OWNPTR(Data, Group, Variable, Type, Name, Initial) \
- Data* Name() const { return Group->Variable.get(); } \
- void set##Type(PassOwnPtr<Data> obj) { \
- Group.access()->Variable = obj; \
- } \
- static Data* initial##Type() { return Initial; }
-
-#define SVG_RS_SET_VARIABLE(Group, Variable, Value) \
- if (!(Group->Variable == Value)) \
- Group.access()->Variable = Value;
-
namespace WebCore {
enum EBaselineShift {