void RenderSVGText::subtreeChildWillBeRemoved(RenderObject* child, Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes) { ASSERT(child); if (!shouldHandleSubtreeMutations()) return; checkLayoutAttributesConsistency(this, m_layoutAttributes); // 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. m_layoutAttributesBuilder.clearTextPositioningElements(); if (m_layoutAttributes.isEmpty() || !child->isSVGInlineText()) return; // This logic requires that the 'text' child is still inserted in the tree. RenderSVGInlineText* text = toRenderSVGInlineText(child); bool stopAfterNext = false; SVGTextLayoutAttributes* previous = 0; SVGTextLayoutAttributes* next = 0; if (!documentBeingDestroyed()) findPreviousAndNextAttributes(this, text, stopAfterNext, previous, next); if (previous) affectedAttributes.append(previous); if (next) affectedAttributes.append(next); size_t position = m_layoutAttributes.find(text->layoutAttributes()); ASSERT(position != notFound); m_layoutAttributes.remove(position); }
void RenderSVGText::subtreeChildWasAdded(RenderObject* child) { ASSERT(child); if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) return; // Always protect the cache before clearing text positioning elements when the cache will subsequently be rebuilt. FontCachePurgePreventer fontCachePurgePreventer; // The positioning elements cache doesn't include the new 'child' yet. Clear the // cache, as the next buildLayoutAttributesForTextRenderer() call rebuilds it. m_layoutAttributesBuilder.clearTextPositioningElements(); if (!child->isSVGInlineText() && !child->isSVGInline()) return; // Detect changes in layout attributes and only measure those text parts that have changed! Vector<SVGTextLayoutAttributes*> newLayoutAttributes; collectLayoutAttributes(this, newLayoutAttributes); if (newLayoutAttributes.isEmpty()) { ASSERT(m_layoutAttributes.isEmpty()); return; } // Compare m_layoutAttributes with newLayoutAttributes to figure out which attribute got added. size_t size = newLayoutAttributes.size(); SVGTextLayoutAttributes* attributes = 0; for (size_t i = 0; i < size; ++i) { attributes = newLayoutAttributes[i]; if (m_layoutAttributes.find(attributes) == notFound) { // Every time this is invoked, there's only a single new entry in the newLayoutAttributes list, compared to the old in m_layoutAttributes. bool stopAfterNext = false; SVGTextLayoutAttributes* previous = 0; SVGTextLayoutAttributes* next = 0; ASSERT_UNUSED(child, &attributes->context() == child); findPreviousAndNextAttributes(this, &attributes->context(), stopAfterNext, previous, next); if (previous) m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(previous->context()); m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(attributes->context()); if (next) m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(next->context()); break; } } #ifndef NDEBUG // Verify that m_layoutAttributes only differs by a maximum of one entry. for (size_t i = 0; i < size; ++i) ASSERT(m_layoutAttributes.find(newLayoutAttributes[i]) != notFound || newLayoutAttributes[i] == attributes); #endif m_layoutAttributes = newLayoutAttributes; }
void RenderSVGText::subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes) { if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) { ASSERT(affectedAttributes.isEmpty()); return; } // This is called immediately after subtreeChildWillBeDestroyed, once the RenderSVGInlineText::willBeDestroyed() method // passes on to the base class, which removes us from the render tree. At this point we can update the layout attributes. unsigned size = affectedAttributes.size(); for (unsigned i = 0; i < size; ++i) m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(affectedAttributes[i]->context()); }
void RenderSVGText::subtreeStyleDidChange() { if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) return; checkLayoutAttributesConsistency(this, m_layoutAttributes); // 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 = firstChild(); descendant; descendant = descendant->nextInPreOrder(this)) { if (descendant->isSVGInlineText()) m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(toRenderSVGInlineText(descendant)); } }
void RenderSVGText::subtreeStyleDidChange(RenderSVGInlineText* text) { ASSERT(text); if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) return; checkLayoutAttributesConsistency(this, m_layoutAttributes); // Only update the metrics cache, but not the text positioning element cache // nor the layout attributes cached in the leaf #text renderers. for (RenderObject* descendant = text; descendant; descendant = descendant->nextInPreOrder(text)) { if (is<RenderSVGInlineText>(*descendant)) m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(downcast<RenderSVGInlineText>(*descendant)); } }