Unreviewed, rolling out r116498.
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 11 May 2012 21:12:02 +0000 (21:12 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 11 May 2012 21:12:02 +0000 (21:12 +0000)
http://trac.webkit.org/changeset/116498
https://bugs.webkit.org/show_bug.cgi?id=86251

Causes crashes in major sites and security issues (Requested
by schenney on #webkit).

Patch by Sheriff Bot <webkit.review.bot@gmail.com> on 2012-05-11

Source/WebCore:

* rendering/svg/RenderSVGInline.cpp:
(WebCore::RenderSVGInline::addChild):
* rendering/svg/RenderSVGInlineText.cpp:
(WebCore::RenderSVGInlineText::willBeDestroyed):
(WebCore::RenderSVGInlineText::setTextInternal):
(WebCore::RenderSVGInlineText::styleDidChange):
* rendering/svg/RenderSVGText.cpp:
(WebCore::recursiveUpdateLayoutAttributes):
(WebCore::RenderSVGText::layoutAttributesChanged):
(WebCore::RenderSVGText::layoutAttributesWillBeDestroyed):
(WebCore::RenderSVGText::invalidateTextPositioningElements):
(WebCore::recursiveUpdateScaledFont):
(WebCore::RenderSVGText::layout):
(WebCore::RenderSVGText::addChild):
(WebCore::recursiveCollectLayoutAttributes):
(WebCore::RenderSVGText::rebuildLayoutAttributes):
(WebCore):
* rendering/svg/RenderSVGText.h:
(RenderSVGText):
(WebCore::RenderSVGText::layoutAttributes):
* rendering/svg/SVGRootInlineBox.cpp:
(WebCore::SVGRootInlineBox::computePerCharacterLayoutInformation):
* rendering/svg/SVGTextLayoutAttributesBuilder.cpp:
(WebCore::SVGTextLayoutAttributesBuilder::buildLayoutAttributes):

LayoutTests:

* svg/text/add-tspan-position-bug-expected.html: Removed.
* svg/text/add-tspan-position-bug.html: Removed.
* svg/text/modify-tspan-position-bug-expected.html: Removed.
* svg/text/modify-tspan-position-bug.html: Removed.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@116801 268f45cc-cd09-0410-ab3c-d52691b4dbfc

12 files changed:
LayoutTests/ChangeLog
LayoutTests/svg/text/add-tspan-position-bug-expected.html [deleted file]
LayoutTests/svg/text/add-tspan-position-bug.html [deleted file]
LayoutTests/svg/text/modify-tspan-position-bug-expected.html [deleted file]
LayoutTests/svg/text/modify-tspan-position-bug.html [deleted file]
Source/WebCore/ChangeLog
Source/WebCore/rendering/svg/RenderSVGInline.cpp
Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
Source/WebCore/rendering/svg/RenderSVGText.cpp
Source/WebCore/rendering/svg/RenderSVGText.h
Source/WebCore/rendering/svg/SVGRootInlineBox.cpp
Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp

index 1eeea21..9c6a688 100644 (file)
@@ -1,3 +1,17 @@
+2012-05-11  Sheriff Bot  <webkit.review.bot@gmail.com>
+
+        Unreviewed, rolling out r116498.
+        http://trac.webkit.org/changeset/116498
+        https://bugs.webkit.org/show_bug.cgi?id=86251
+
+        Causes crashes in major sites and security issues (Requested
+        by schenney on #webkit).
+
+        * svg/text/add-tspan-position-bug-expected.html: Removed.
+        * svg/text/add-tspan-position-bug.html: Removed.
+        * svg/text/modify-tspan-position-bug-expected.html: Removed.
+        * svg/text/modify-tspan-position-bug.html: Removed.
+
 2012-05-11  Alexandru Chiculita  <achicu@adobe.com>
 
         [CSS Shaders] Make CSS Shaders render to texture framebuffers
diff --git a/LayoutTests/svg/text/add-tspan-position-bug-expected.html b/LayoutTests/svg/text/add-tspan-position-bug-expected.html
deleted file mode 100644 (file)
index d1f889b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<svg>
-<text id="text" y="50"><tspan>Should be on</tspan><tspan dy="30">different lines</tspan></text>
-</svg>
-</body>
-</html>
diff --git a/LayoutTests/svg/text/add-tspan-position-bug.html b/LayoutTests/svg/text/add-tspan-position-bug.html
deleted file mode 100644 (file)
index d33c57f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body onload="loaded()">
-<svg>
-<title>This test used to be laid out on a single line, instead of multiple ones</title>
-<text id="text" y="50"></text>
-
-<script>
-var text = document.getElementsByTagName("text")[0];
-
-function addSpans() {
-    var tspan1 = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
-    tspan1.appendChild(document.createTextNode("Should be on"));
-
-    var tspan2 = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
-    tspan2.setAttribute("dy", "30");
-    tspan2.appendChild(document.createTextNode("different lines"));
-
-    text.appendChild(tspan1);
-    text.appendChild(tspan2);
-
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
-if (window.layoutTestController)
-    layoutTestController.waitUntilDone();
-
-function loaded() {
-    // Bug is only trigger from another loop.
-    setTimeout(addSpans, 0);
-}
-</script>
-</svg>
-</body>
-</html>
diff --git a/LayoutTests/svg/text/modify-tspan-position-bug-expected.html b/LayoutTests/svg/text/modify-tspan-position-bug-expected.html
deleted file mode 100644 (file)
index d1f889b..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body>
-<svg>
-<text id="text" y="50"><tspan>Should be on</tspan><tspan dy="30">different lines</tspan></text>
-</svg>
-</body>
-</html>
diff --git a/LayoutTests/svg/text/modify-tspan-position-bug.html b/LayoutTests/svg/text/modify-tspan-position-bug.html
deleted file mode 100644 (file)
index 4ea9d07..0000000
+++ /dev/null
@@ -1,42 +0,0 @@
-<!DOCTYPE html>
-<html>
-<body onload="loaded()">
-<svg>
-<title>This test used to be laid out on a single line, instead of multiple ones</title>
-<text id="text" y="50"></text>
-
-<script>
-var text = document.getElementsByTagName("text")[0];
-
-function addSpans() {
-    var tspan1 = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
-    tspan1.appendChild(document.createTextNode("Should be on"));
-
-    tspan2 = document.createElementNS("http://www.w3.org/2000/svg", "tspan");
-    tspan2.appendChild(document.createTextNode("different lines"));
-
-    text.appendChild(tspan1);
-    text.appendChild(tspan2);
-
-    // Bug is only trigger from another loop.
-    setTimeout(moveSpan, 0);
-}
-
-function moveSpan() {
-    tspan2.setAttribute("dy", "30");
-
-    if (window.layoutTestController)
-        layoutTestController.notifyDone();
-}
-
-if (window.layoutTestController)
-    layoutTestController.waitUntilDone();
-
-function loaded() {
-    // Bug is only trigger from another loop.
-    setTimeout(addSpans, 0);
-}
-</script>
-</svg>
-</body>
-</html>
index c2bf3c0..1c9b224 100644 (file)
@@ -1,3 +1,37 @@
+2012-05-11  Sheriff Bot  <webkit.review.bot@gmail.com>
+
+        Unreviewed, rolling out r116498.
+        http://trac.webkit.org/changeset/116498
+        https://bugs.webkit.org/show_bug.cgi?id=86251
+
+        Causes crashes in major sites and security issues (Requested
+        by schenney on #webkit).
+
+        * rendering/svg/RenderSVGInline.cpp:
+        (WebCore::RenderSVGInline::addChild):
+        * rendering/svg/RenderSVGInlineText.cpp:
+        (WebCore::RenderSVGInlineText::willBeDestroyed):
+        (WebCore::RenderSVGInlineText::setTextInternal):
+        (WebCore::RenderSVGInlineText::styleDidChange):
+        * rendering/svg/RenderSVGText.cpp:
+        (WebCore::recursiveUpdateLayoutAttributes):
+        (WebCore::RenderSVGText::layoutAttributesChanged):
+        (WebCore::RenderSVGText::layoutAttributesWillBeDestroyed):
+        (WebCore::RenderSVGText::invalidateTextPositioningElements):
+        (WebCore::recursiveUpdateScaledFont):
+        (WebCore::RenderSVGText::layout):
+        (WebCore::RenderSVGText::addChild):
+        (WebCore::recursiveCollectLayoutAttributes):
+        (WebCore::RenderSVGText::rebuildLayoutAttributes):
+        (WebCore):
+        * rendering/svg/RenderSVGText.h:
+        (RenderSVGText):
+        (WebCore::RenderSVGText::layoutAttributes):
+        * rendering/svg/SVGRootInlineBox.cpp:
+        (WebCore::SVGRootInlineBox::computePerCharacterLayoutInformation):
+        * rendering/svg/SVGTextLayoutAttributesBuilder.cpp:
+        (WebCore::SVGTextLayoutAttributesBuilder::buildLayoutAttributes):
+
 2012-05-11  Tim Horton  <timothy_horton@apple.com>
 
         FrameView->m_lastPaintTime is not updated in the tiled drawing case
index 98af8e9..ab8cc1a 100644 (file)
@@ -124,7 +124,7 @@ void RenderSVGInline::addChild(RenderObject* child, RenderObject* beforeChild)
 {
     RenderInline::addChild(child, beforeChild);
     if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
-        textRenderer->subtreeChildAdded(child);
+        textRenderer->layoutAttributesChanged(child);
 }
 
 }
index a0df411..09d446b 100644 (file)
@@ -81,16 +81,28 @@ void RenderSVGInlineText::willBeDestroyed()
     }
 
     Vector<SVGTextLayoutAttributes*> affectedAttributes;
-    textRenderer->subtreeChildWillBeDestroyed(this, affectedAttributes);
+    textRenderer->layoutAttributesWillBeDestroyed(this, affectedAttributes);
+
     RenderText::willBeDestroyed();
-    textRenderer->subtreeChildWasDestroyed(this, affectedAttributes);
+    if (affectedAttributes.isEmpty())
+        return;
+
+    if (!documentBeingDestroyed())
+        textRenderer->rebuildLayoutAttributes(affectedAttributes);
 }
 
 void RenderSVGInlineText::setTextInternal(PassRefPtr<StringImpl> text)
 {
     RenderText::setTextInternal(text);
-    if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
-        textRenderer->subtreeTextChanged(this);
+
+    // When the underlying text content changes, call both textDOMChanged() & layoutAttributesChanged()
+    // The former will clear the SVGTextPositioningElement cache, which depends on the textLength() of
+    // the RenderSVGInlineText objects, and thus needs to be rebuild. The latter will assure that the
+    // SVGTextLayoutAttributes associated with the RenderSVGInlineText will be updated.
+    if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this)) {
+        textRenderer->invalidateTextPositioningElements();
+        textRenderer->layoutAttributesChanged(this);
+    }
 }
 
 void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
@@ -115,7 +127,7 @@ void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle
 
     // The text metrics may be influenced by style changes.
     if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
-        textRenderer->subtreeStyleChanged(this);
+        textRenderer->layoutAttributesChanged(this);
 }
 
 InlineTextBox* RenderSVGInlineText::createTextBox()
index f0f0b9c..f512ab8 100644 (file)
@@ -110,22 +110,24 @@ void RenderSVGText::mapLocalToContainer(RenderBoxModelObject* repaintContainer,
     SVGRenderSupport::mapLocalToContainer(this, repaintContainer, transformState, wasFixed);
 }
 
-void RenderSVGText::subtreeChildAdded(RenderObject* child)
+static inline void recursiveUpdateLayoutAttributes(RenderObject* start, SVGTextLayoutAttributesBuilder& builder)
 {
-    ASSERT(child);
-    if (m_needsPositioningValuesUpdate)
+    if (start->isSVGInlineText()) {
+        builder.buildLayoutAttributesForTextRenderer(toRenderSVGInlineText(start));
         return;
+    }
 
-    // The positioning elements cache doesn't include the new 'child' yet. Clear the
-    // cache, as the next buildLayoutAttributesForTextRenderer() call rebuilds it.
-    invalidateTextPositioningElements();
+    for (RenderObject* child = start->firstChild(); child; child = child->nextSibling())
+        recursiveUpdateLayoutAttributes(child, builder);
+}
 
+void RenderSVGText::layoutAttributesChanged(RenderObject* child)
+{
+    ASSERT(child);
+    if (m_needsPositioningValuesUpdate)
+        return;
     FontCachePurgePreventer fontCachePurgePreventer;
-    for (RenderObject* descendant = child; descendant; descendant = descendant->nextInPreOrder(child)) {
-        if (descendant->isSVGInlineText())
-            m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(toRenderSVGInlineText(descendant));
-    }
-
+    recursiveUpdateLayoutAttributes(child, m_layoutAttributesBuilder);
     rebuildLayoutAttributes();
 }
 
@@ -160,18 +162,12 @@ static inline bool findPreviousAndNextAttributes(RenderObject* start, RenderSVGI
     return false;
 }
 
-void RenderSVGText::subtreeChildWillBeDestroyed(RenderSVGInlineText* text, Vector<SVGTextLayoutAttributes*>& affectedAttributes)
+void RenderSVGText::layoutAttributesWillBeDestroyed(RenderSVGInlineText* text, Vector<SVGTextLayoutAttributes*>& affectedAttributes)
 {
     ASSERT(text);
-
-    // The positioning elements cache depends on the size of each text renderer in the
-    // subtree. If this changes, clear the cache. It's going to be rebuilt below.
-    invalidateTextPositioningElements();
-
     if (m_needsPositioningValuesUpdate)
         return;
 
-    // This logic requires that the 'text' child is still inserted in the tree.
     bool stopAfterNext = false;
     SVGTextLayoutAttributes* previous = 0;
     SVGTextLayoutAttributes* next = 0;
@@ -180,94 +176,29 @@ void RenderSVGText::subtreeChildWillBeDestroyed(RenderSVGInlineText* text, Vecto
         affectedAttributes.append(previous);
     if (next)
         affectedAttributes.append(next);
+}
 
-    SVGTextLayoutAttributes* currentLayoutAttributes = text->layoutAttributes();
-
-    size_t position = m_layoutAttributes.find(currentLayoutAttributes);
-    ASSERT(position != notFound);
-    m_layoutAttributes.remove(position);
-
-    ASSERT(!m_layoutAttributes.contains(currentLayoutAttributes));
+void RenderSVGText::invalidateTextPositioningElements()
+{
+    // Clear the text positioning elements. This should be called when either the children
+    // of a DOM text element have changed, or the length of the text in any child element
+    // has changed. Failure to clear may leave us with invalid elements, as other code paths
+    // do not always cause the position elements to be marked invalid before use.
+    m_layoutAttributesBuilder.clearTextPositioningElements();
 }
 
-static inline void recursiveCollectLayoutAttributes(RenderObject* start, Vector<SVGTextLayoutAttributes*>& attributes)
+static inline void recursiveUpdateScaledFont(RenderObject* start)
 {
     for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
         if (child->isSVGInlineText()) {
-            attributes.append(toRenderSVGInlineText(child)->layoutAttributes());
+            toRenderSVGInlineText(child)->updateScaledFont();
             continue;
         }
 
-        recursiveCollectLayoutAttributes(child, attributes);
-    }
-}
-
-static inline void checkLayoutAttributesConsistency(RenderSVGText* text, Vector<SVGTextLayoutAttributes*>& expectedLayoutAttributes)
-{
-#ifndef NDEBUG
-    Vector<SVGTextLayoutAttributes*> newLayoutAttributes;
-    recursiveCollectLayoutAttributes(text, newLayoutAttributes);
-    ASSERT(newLayoutAttributes == expectedLayoutAttributes);
-#else
-    UNUSED_PARAM(text);
-    UNUSED_PARAM(expectedLayoutAttributes);
-#endif
-}
-
-void RenderSVGText::subtreeChildWasDestroyed(RenderSVGInlineText*, Vector<SVGTextLayoutAttributes*>& affectedAttributes)
-{
-    if (documentBeingDestroyed() || affectedAttributes.isEmpty())
-        return;
-
-    checkLayoutAttributesConsistency(this, m_layoutAttributes);
-
-    size_t size = affectedAttributes.size();
-    for (size_t i = 0; i < size; ++i)
-        m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(affectedAttributes[i]->context());
-}
-
-void RenderSVGText::subtreeStyleChanged(RenderSVGInlineText* text)
-{
-    ASSERT(text);
-    if (m_needsPositioningValuesUpdate)
-        return;
-
-    // Only update the metrics cache, but not the text positioning element cache
-    // nor the layout attributes cached in the leaf #text renderers.
-    FontCachePurgePreventer fontCachePurgePreventer;
-    for (RenderObject* descendant = text; descendant; descendant = descendant->nextInPreOrder(text)) {
-        if (descendant->isSVGInlineText())
-            m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(toRenderSVGInlineText(descendant));
-    }
-}
-
-void RenderSVGText::subtreeTextChanged(RenderSVGInlineText* text)
-{
-    ASSERT(text);
-
-    // The positioning elements cache depends on the size of each text renderer in the
-    // subtree. If this changes, clear the cache. It's going to be rebuilt below.
-    invalidateTextPositioningElements();
-
-    if (m_needsPositioningValuesUpdate)
-        return;
-
-    FontCachePurgePreventer fontCachePurgePreventer;
-    for (RenderObject* descendant = text; descendant; descendant = descendant->nextInPreOrder(text)) {
-        if (descendant->isSVGInlineText())
-            m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(toRenderSVGInlineText(descendant));
+        recursiveUpdateScaledFont(child);
     }
 }
 
-void RenderSVGText::invalidateTextPositioningElements()
-{
-    // Clear the text positioning elements. This should be called when either the children
-    // of a DOM text element have changed, or the length of the text in any child element
-    // has changed. Failure to clear may leave us with invalid elements, as other code paths
-    // do not always cause the position elements to be marked invalid before use.
-    m_layoutAttributesBuilder.clearTextPositioningElements();
-}
-
 void RenderSVGText::layout()
 {
     ASSERT(needsLayout());
@@ -284,12 +215,8 @@ void RenderSVGText::layout()
     // If the root layout size changed (eg. window size changes) or the positioning values change
     // or the transform to the root context has changed then recompute the on-screen font size.
     if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(this)->isLayoutSizeChanged()) {
-        for (RenderObject* descendant = this; descendant; descendant = descendant->nextInPreOrder(this)) {
-            if (descendant->isSVGInlineText())
-                toRenderSVGInlineText(descendant)->updateScaledFont();
-        }
-
-        rebuildAllLayoutAttributes();
+        recursiveUpdateScaledFont(this);
+        rebuildLayoutAttributes(true);
         updateCachedBoundariesInParents = true;
         m_needsTextMetricsUpdate = false;
     }
@@ -437,7 +364,7 @@ FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
 void RenderSVGText::addChild(RenderObject* child, RenderObject* beforeChild)
 {
     RenderSVGBlock::addChild(child, beforeChild);
-    subtreeChildAdded(child);
+    layoutAttributesChanged(child);
 }
 
 // Fix for <rdar://problem/8048875>. We should not render :first-line CSS Style
@@ -453,23 +380,38 @@ void RenderSVGText::updateFirstLetter()
 {
 }
 
-void RenderSVGText::rebuildAllLayoutAttributes()
+static inline void recursiveCollectLayoutAttributes(RenderObject* start, Vector<SVGTextLayoutAttributes*>& attributes)
 {
-    m_layoutAttributes.clear();
-    recursiveCollectLayoutAttributes(this, m_layoutAttributes);
-    if (m_layoutAttributes.isEmpty())
-        return;
+    for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
+        if (child->isSVGInlineText()) {
+            attributes.append(toRenderSVGInlineText(child)->layoutAttributes());
+            continue;
+        }
 
-    m_layoutAttributesBuilder.rebuildMetricsForWholeTree(this);
+        recursiveCollectLayoutAttributes(child, attributes);
+    }
 }
 
-void RenderSVGText::rebuildLayoutAttributes()
+void RenderSVGText::rebuildLayoutAttributes(bool performFullRebuild)
 {
+    if (performFullRebuild)
+        m_layoutAttributes.clear();
+
     if (m_layoutAttributes.isEmpty()) {
-        rebuildAllLayoutAttributes();
+        recursiveCollectLayoutAttributes(this, m_layoutAttributes);
+        if (m_layoutAttributes.isEmpty() || !performFullRebuild)
+            return;
+
+        m_layoutAttributesBuilder.rebuildMetricsForWholeTree(this);
         return;
     }
 
+    Vector<SVGTextLayoutAttributes*> affectedAttributes;
+    rebuildLayoutAttributes(affectedAttributes);
+}
+
+void RenderSVGText::rebuildLayoutAttributes(Vector<SVGTextLayoutAttributes*>& affectedAttributes)
+{
     // Detect changes in layout attributes and only measure those text parts that have changed!
     Vector<SVGTextLayoutAttributes*> newLayoutAttributes;
     recursiveCollectLayoutAttributes(this, newLayoutAttributes);
@@ -478,7 +420,7 @@ void RenderSVGText::rebuildLayoutAttributes()
         return;
     }
 
-    // Compare m_layoutAttributes with newLayoutAttributes to figure out which attributes got added.
+    // Compare m_layoutAttributes with newLayoutAttributes to figure out which attributes got added/removed.
     size_t size = newLayoutAttributes.size();
     for (size_t i = 0; i < size; ++i) {
         SVGTextLayoutAttributes* attributes = newLayoutAttributes[i];
@@ -486,6 +428,10 @@ void RenderSVGText::rebuildLayoutAttributes()
             m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(attributes->context());
     }
 
+    size = affectedAttributes.size();
+    for (size_t i = 0; i < size; ++i)
+        m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(affectedAttributes[i]->context());
+
     m_layoutAttributes = newLayoutAttributes;
 }
 
index 23a0b6a..5665b44 100644 (file)
@@ -48,18 +48,18 @@ public:
     static const RenderSVGText* locateRenderSVGTextAncestor(const RenderObject*);
 
     bool needsReordering() const { return m_needsReordering; }
-    Vector<SVGTextLayoutAttributes*>& layoutAttributes() { return m_layoutAttributes; }
-
-    void subtreeChildAdded(RenderObject*);
-    void subtreeChildWillBeDestroyed(RenderSVGInlineText*, Vector<SVGTextLayoutAttributes*>& affectedAttributes);
-    void subtreeChildWasDestroyed(RenderSVGInlineText*, Vector<SVGTextLayoutAttributes*>& affectedAttributes);
-    void subtreeStyleChanged(RenderSVGInlineText*);
-    void subtreeTextChanged(RenderSVGInlineText*);
 
     // Call this method when either the children of a DOM text element have changed, or the length of
     // the text in any child element has changed.
     void invalidateTextPositioningElements();
 
+    void layoutAttributesChanged(RenderObject*);
+    void layoutAttributesWillBeDestroyed(RenderSVGInlineText*, Vector<SVGTextLayoutAttributes*>& affectedAttributes);
+    void rebuildLayoutAttributes(bool performFullRebuild = false);
+    void rebuildLayoutAttributes(Vector<SVGTextLayoutAttributes*>& affectedAttributes);
+
+    Vector<SVGTextLayoutAttributes*>& layoutAttributes() { return m_layoutAttributes; }
+
 private:
     virtual const char* renderName() const { return "RenderSVGText"; }
     virtual bool isSVGText() const { return true; }
@@ -91,9 +91,6 @@ private:
     virtual RenderBlock* firstLineBlock() const;
     virtual void updateFirstLetter();
 
-    void rebuildAllLayoutAttributes();
-    void rebuildLayoutAttributes();
-
     bool m_needsReordering : 1;
     bool m_needsPositioningValuesUpdate : 1;
     bool m_needsTransformUpdate : 1;
index 34e93a0..57146c9 100644 (file)
@@ -73,6 +73,7 @@ void SVGRootInlineBox::computePerCharacterLayoutInformation()
     RenderSVGText* textRoot = toRenderSVGText(block());
     ASSERT(textRoot);
 
+    textRoot->rebuildLayoutAttributes();
     Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot->layoutAttributes();
     if (layoutAttributes.isEmpty())
         return;
index 067bf6b..02a2123 100644 (file)
@@ -26,6 +26,9 @@
 #include "RenderSVGText.h"
 #include "SVGTextPositioningElement.h"
 
+// Set to a value > 0 to dump the text layout attributes
+#define DUMP_TEXT_LAYOUT_ATTRIBUTES 0
+
 namespace WebCore {
 
 SVGTextLayoutAttributesBuilder::SVGTextLayoutAttributesBuilder()
@@ -170,6 +173,11 @@ void SVGTextLayoutAttributesBuilder::buildLayoutAttributes(RenderSVGText* textRo
     unsigned size = m_textPositions.size();
     for (unsigned i = 0; i < size; ++i)
         fillCharacterDataMap(m_textPositions[i]);
+
+#if DUMP_TEXT_LAYOUT_ATTRIBUTES > 0
+    fprintf(stderr, "\nDumping ALL layout attributes for RenderSVGText, renderer=%p, node=%p (m_textLength: %i)\n", textRoot, textRoot->node(), m_textLength);
+    m_characterDataMap.dump();
+#endif
 }
 
 static inline void updateCharacterData(unsigned i, float& lastRotation, SVGCharacterData& data, const SVGLengthContext& lengthContext, const SVGLengthList* xList, const SVGLengthList* yList, const SVGLengthList* dxList, const SVGLengthList* dyList, const SVGNumberList* rotateList)