diff options
author | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
---|---|---|
committer | Lorry Tar Creator <lorry-tar-importer@lorry> | 2017-06-27 06:07:23 +0000 |
commit | 1bf1084f2b10c3b47fd1a588d85d21ed0eb41d0c (patch) | |
tree | 46dcd36c86e7fbc6e5df36deb463b33e9967a6f7 /Source/WebCore/rendering/svg/RenderSVGText.cpp | |
parent | 32761a6cee1d0dee366b885b7b9c777e67885688 (diff) | |
download | WebKitGtk-tarball-master.tar.gz |
webkitgtk-2.16.5HEADwebkitgtk-2.16.5master
Diffstat (limited to 'Source/WebCore/rendering/svg/RenderSVGText.cpp')
-rw-r--r-- | Source/WebCore/rendering/svg/RenderSVGText.cpp | 155 |
1 files changed, 66 insertions, 89 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp index 22c1cdaab..8f3b60f0d 100644 --- a/Source/WebCore/rendering/svg/RenderSVGText.cpp +++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006 Apple Computer, Inc. + * Copyright (C) 2006 Apple Inc. * Copyright (C) 2006 Alexander Kellett <lypanov@kde.org> * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz> * Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org> @@ -25,17 +25,17 @@ */ #include "config.h" - -#if ENABLE(SVG) #include "RenderSVGText.h" #include "FloatQuad.h" -#include "FontCache.h" +#include "Font.h" #include "GraphicsContext.h" #include "HitTestRequest.h" #include "HitTestResult.h" #include "LayoutRepainter.h" #include "PointerEventsHitRules.h" +#include "RenderIterator.h" +#include "RenderSVGInline.h" #include "RenderSVGInlineText.h" #include "RenderSVGResource.h" #include "RenderSVGRoot.h" @@ -43,18 +43,15 @@ #include "SVGResourcesCache.h" #include "SVGRootInlineBox.h" #include "SVGTextElement.h" -#include "SVGTextRunRenderingContext.h" -#include "SVGTransformList.h" #include "SVGURIReference.h" -#include "SimpleFontData.h" #include "TransformState.h" #include "VisiblePosition.h" #include <wtf/StackStats.h> namespace WebCore { -RenderSVGText::RenderSVGText(SVGTextElement& element, PassRef<RenderStyle> style) - : RenderSVGBlock(element, std::move(style)) +RenderSVGText::RenderSVGText(SVGTextElement& element, RenderStyle&& style) + : RenderSVGBlock(element, WTFMove(style)) , m_needsReordering(false) , m_needsPositioningValuesUpdate(false) , m_needsTransformUpdate(true) @@ -69,7 +66,7 @@ RenderSVGText::~RenderSVGText() SVGTextElement& RenderSVGText::textElement() const { - return toSVGTextElement(RenderSVGBlock::graphicsElement()); + return downcast<SVGTextElement>(RenderSVGBlock::graphicsElement()); } bool RenderSVGText::isChildAllowed(const RenderObject& child, const RenderStyle&) const @@ -77,24 +74,14 @@ bool RenderSVGText::isChildAllowed(const RenderObject& child, const RenderStyle& return child.isInline(); } -RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(RenderObject* start) +RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(RenderObject& start) { - ASSERT(start); - while (start && !start->isSVGText()) - start = start->parent(); - if (!start || !start->isSVGText()) - return 0; - return toRenderSVGText(start); + return lineageOfType<RenderSVGText>(start).first(); } -const RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(const RenderObject* start) +const RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(const RenderObject& start) { - ASSERT(start); - while (start && !start->isSVGText()) - start = start->parent(); - if (!start || !start->isSVGText()) - return 0; - return toRenderSVGText(start); + return lineageOfType<RenderSVGText>(start).first(); } LayoutRect RenderSVGText::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const @@ -102,16 +89,14 @@ LayoutRect RenderSVGText::clippedOverflowRectForRepaint(const RenderLayerModelOb return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer); } -void RenderSVGText::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& rect, bool fixed) const +LayoutRect RenderSVGText::computeRectForRepaint(const LayoutRect& rect, const RenderLayerModelObject* repaintContainer, RepaintContext context) const { - FloatRect repaintRect = rect; - computeFloatRectForRepaint(repaintContainer, repaintRect, fixed); - rect = enclosingLayoutRect(repaintRect); + return enclosingLayoutRect(computeFloatRectForRepaint(rect, repaintContainer, context.m_hasPositionFixedDescendant)); } -void RenderSVGText::computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const +FloatRect RenderSVGText::computeFloatRectForRepaint(const FloatRect& repaintRect, const RenderLayerModelObject* repaintContainer, bool fixed) const { - SVGRenderSupport::computeFloatRectForRepaint(*this, repaintContainer, repaintRect, fixed); + return SVGRenderSupport::computeFloatRectForRepaint(*this, repaintRect, repaintContainer, fixed); } void RenderSVGText::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const @@ -127,26 +112,25 @@ const RenderObject* RenderSVGText::pushMappingToContainer(const RenderLayerModel static inline void collectLayoutAttributes(RenderObject* text, Vector<SVGTextLayoutAttributes*>& attributes) { for (RenderObject* descendant = text; descendant; descendant = descendant->nextInPreOrder(text)) { - if (descendant->isSVGInlineText()) - attributes.append(toRenderSVGInlineText(descendant)->layoutAttributes()); + if (is<RenderSVGInlineText>(*descendant)) + attributes.append(downcast<RenderSVGInlineText>(*descendant).layoutAttributes()); } } -static inline bool findPreviousAndNextAttributes(RenderElement* start, RenderSVGInlineText* locateElement, bool& stopAfterNext, SVGTextLayoutAttributes*& previous, SVGTextLayoutAttributes*& next) +static inline bool findPreviousAndNextAttributes(RenderElement& start, RenderSVGInlineText* locateElement, bool& stopAfterNext, SVGTextLayoutAttributes*& previous, SVGTextLayoutAttributes*& next) { - ASSERT(start); ASSERT(locateElement); // FIXME: Make this iterative. - for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) { - if (child->isSVGInlineText()) { - RenderSVGInlineText* text = toRenderSVGInlineText(child); - if (locateElement != text) { + for (auto& child : childrenOfType<RenderObject>(start)) { + if (is<RenderSVGInlineText>(child)) { + auto& text = downcast<RenderSVGInlineText>(child); + if (locateElement != &text) { if (stopAfterNext) { - next = text->layoutAttributes(); + next = text.layoutAttributes(); return true; } - previous = text->layoutAttributes(); + previous = text.layoutAttributes(); continue; } @@ -154,10 +138,10 @@ static inline bool findPreviousAndNextAttributes(RenderElement* start, RenderSVG continue; } - if (!child->isSVGInline()) + if (!is<RenderSVGInline>(child)) continue; - if (findPreviousAndNextAttributes(toRenderElement(child), locateElement, stopAfterNext, previous, next)) + if (findPreviousAndNextAttributes(downcast<RenderElement>(child), locateElement, stopAfterNext, previous, next)) return true; } @@ -177,12 +161,9 @@ inline bool RenderSVGText::shouldHandleSubtreeMutations() const void RenderSVGText::subtreeChildWasAdded(RenderObject* child) { ASSERT(child); - if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) + if (!shouldHandleSubtreeMutations() || renderTreeBeingDestroyed()) 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(); @@ -209,7 +190,7 @@ void RenderSVGText::subtreeChildWasAdded(RenderObject* child) SVGTextLayoutAttributes* previous = 0; SVGTextLayoutAttributes* next = 0; ASSERT_UNUSED(child, &attributes->context() == child); - findPreviousAndNextAttributes(this, &attributes->context(), stopAfterNext, previous, next); + findPreviousAndNextAttributes(*this, &attributes->context(), stopAfterNext, previous, next); if (previous) m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(previous->context()); @@ -264,26 +245,25 @@ void RenderSVGText::subtreeChildWillBeRemoved(RenderObject* child, Vector<SVGTex return; // This logic requires that the 'text' child is still inserted in the tree. - RenderSVGInlineText* text = toRenderSVGInlineText(child); + auto& text = downcast<RenderSVGInlineText>(*child); bool stopAfterNext = false; - SVGTextLayoutAttributes* previous = 0; - SVGTextLayoutAttributes* next = 0; - if (!documentBeingDestroyed()) - findPreviousAndNextAttributes(this, text, stopAfterNext, previous, next); + SVGTextLayoutAttributes* previous = nullptr; + SVGTextLayoutAttributes* next = nullptr; + if (!renderTreeBeingDestroyed()) + 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); + bool removed = m_layoutAttributes.removeFirst(text.layoutAttributes()); + ASSERT_UNUSED(removed, removed); } void RenderSVGText::subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes) { - if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) { + if (!shouldHandleSubtreeMutations() || renderTreeBeingDestroyed()) { ASSERT(affectedAttributes.isEmpty()); return; } @@ -298,17 +278,16 @@ void RenderSVGText::subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes* void RenderSVGText::subtreeStyleDidChange(RenderSVGInlineText* text) { ASSERT(text); - if (!shouldHandleSubtreeMutations() || documentBeingDestroyed()) + if (!shouldHandleSubtreeMutations() || renderTreeBeingDestroyed()) 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 = text; descendant; descendant = descendant->nextInPreOrder(text)) { - if (descendant->isSVGInlineText()) - m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(toRenderSVGInlineText(descendant)); + if (is<RenderSVGInlineText>(*descendant)) + m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(downcast<RenderSVGInlineText>(*descendant)); } } @@ -327,29 +306,26 @@ void RenderSVGText::subtreeTextDidChange(RenderSVGInlineText* text) return; } - // Always protect the cache before clearing text positioning elements when the cache will subsequently be rebuilt. - FontCachePurgePreventer fontCachePurgePreventer; - // 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(); checkLayoutAttributesConsistency(this, m_layoutAttributes); for (RenderObject* descendant = text; descendant; descendant = descendant->nextInPreOrder(text)) { - if (descendant->isSVGInlineText()) - m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(toRenderSVGInlineText(*descendant)); + if (is<RenderSVGInlineText>(*descendant)) + m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(downcast<RenderSVGInlineText>(*descendant)); } } -static inline void updateFontInAllDescendants(RenderObject* start, SVGTextLayoutAttributesBuilder* builder = 0) +static inline void updateFontInAllDescendants(RenderObject* start, SVGTextLayoutAttributesBuilder* builder = nullptr) { for (RenderObject* descendant = start; descendant; descendant = descendant->nextInPreOrder(start)) { - if (!descendant->isSVGInlineText()) + if (!is<RenderSVGInlineText>(*descendant)) continue; - RenderSVGInlineText& text = toRenderSVGInlineText(*descendant); + auto& text = downcast<RenderSVGInlineText>(*descendant); text.updateScaledFont(); if (builder) - builder->rebuildMetricsForTextRenderer(&text); + builder->rebuildMetricsForTextRenderer(text); } } @@ -372,7 +348,7 @@ void RenderSVGText::layout() ASSERT(m_layoutAttributes.isEmpty()); collectLayoutAttributes(this, m_layoutAttributes); updateFontInAllDescendants(this); - m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(this); + m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this); m_needsReordering = true; m_needsTextMetricsUpdate = false; @@ -386,11 +362,11 @@ void RenderSVGText::layout() m_needsTextMetricsUpdate = false; } - m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(this); + m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this); m_needsReordering = true; m_needsPositioningValuesUpdate = false; updateCachedBoundariesInParents = true; - } else if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(*this).isLayoutSizeChanged()) { + } else if (m_needsTextMetricsUpdate || SVGRenderSupport::findTreeRootObject(*this)->isLayoutSizeChanged()) { // If the root layout size changed (eg. window size changes) or the transform to the root // context has changed then recompute the on-screen font size. updateFontInAllDescendants(this, &m_layoutAttributesBuilder); @@ -409,7 +385,7 @@ void RenderSVGText::layout() ASSERT(!simplifiedLayout()); ASSERT(!scrollsOverflow()); ASSERT(!hasControlClip()); - ASSERT(!hasColumns()); + ASSERT(!multiColumnFlowThread()); ASSERT(!positionedObjects()); ASSERT(!m_overflow); ASSERT(!isAnonymousBlock()); @@ -422,7 +398,7 @@ void RenderSVGText::layout() ASSERT(childrenInline()); LayoutUnit repaintLogicalTop = 0; LayoutUnit repaintLogicalBottom = 0; - clearFloats(); + rebuildFloatingObjectSetFromIntrudingFloats(); layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom); if (m_needsReordering) @@ -447,7 +423,7 @@ std::unique_ptr<RootInlineBox> RenderSVGText::createRootInlineBox() { auto box = std::make_unique<SVGRootInlineBox>(*this); box->setHasVirtualLogicalHeight(); - return std::move(box); + return WTFMove(box); } bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction) @@ -457,7 +433,7 @@ bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResul if (isVisible || !hitRules.requireVisible) { if ((hitRules.canHitStroke && (style().svgStyle().hasStroke() || !hitRules.requireStroke)) || (hitRules.canHitFill && (style().svgStyle().hasFill() || !hitRules.requireFill))) { - FloatPoint localPoint = localToParentTransform().inverse().mapPoint(pointInParent); + FloatPoint localPoint = localToParentTransform().inverse().value_or(AffineTransform()).mapPoint(pointInParent); if (!SVGRenderSupport::pointInClippingArea(*this, localPoint)) return false; @@ -476,42 +452,46 @@ bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, const Hit return false; } -VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInContents) +VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInContents, const RenderRegion* region) { RootInlineBox* rootBox = firstRootBox(); if (!rootBox) return createVisiblePosition(0, DOWNSTREAM); - ASSERT_WITH_SECURITY_IMPLICATION(rootBox->isSVGRootInlineBox()); ASSERT(!rootBox->nextRootBox()); ASSERT(childrenInline()); - InlineBox* closestBox = toSVGRootInlineBox(rootBox)->closestLeafChildForPosition(pointInContents); + InlineBox* closestBox = downcast<SVGRootInlineBox>(*rootBox).closestLeafChildForPosition(pointInContents); if (!closestBox) return createVisiblePosition(0, DOWNSTREAM); - return closestBox->renderer().positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y())); + return closestBox->renderer().positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()), region); } void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const { - quads.append(localToAbsoluteQuad(strokeBoundingBox(), 0 /* mode */, wasFixed)); + quads.append(localToAbsoluteQuad(strokeBoundingBox(), UseTransforms, wasFixed)); } void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&) { - if (paintInfo.context->paintingDisabled()) + if (paintInfo.context().paintingDisabled()) return; if (paintInfo.phase != PaintPhaseForeground - && paintInfo.phase != PaintPhaseSelfOutline && paintInfo.phase != PaintPhaseSelection) return; PaintInfo blockInfo(paintInfo); - GraphicsContextStateSaver stateSaver(*blockInfo.context); + GraphicsContextStateSaver stateSaver(blockInfo.context()); blockInfo.applyTransform(localToParentTransform()); RenderBlock::paint(blockInfo, LayoutPoint()); + + // Paint the outlines, if any + if (paintInfo.phase == PaintPhaseForeground) { + blockInfo.phase = PaintPhaseSelfOutline; + RenderBlock::paint(blockInfo, LayoutPoint()); + } } FloatRect RenderSVGText::strokeBoundingBox() const @@ -522,7 +502,7 @@ FloatRect RenderSVGText::strokeBoundingBox() const return strokeBoundaries; SVGLengthContext lengthContext(&textElement()); - strokeBoundaries.inflate(svgStyle.strokeWidth().value(lengthContext)); + strokeBoundaries.inflate(lengthContext.valueForLength(style().strokeWidth())); return strokeBoundaries; } @@ -550,7 +530,6 @@ void RenderSVGText::removeChild(RenderObject& child) SVGResourcesCache::clientWillBeRemovedFromTree(child); Vector<SVGTextLayoutAttributes*, 2> affectedAttributes; - FontCachePurgePreventer fontCachePurgePreventer; subtreeChildWillBeRemoved(&child, affectedAttributes); RenderSVGBlock::removeChild(child); subtreeChildWasRemoved(affectedAttributes); @@ -565,10 +544,8 @@ RenderBlock* RenderSVGText::firstLineBlock() const // Fix for <rdar://problem/8048875>. We should not render :first-letter CSS Style // in a SVG text element context. -void RenderSVGText::updateFirstLetter() +void RenderSVGText::updateFirstLetter(RenderTreeMutationIsAllowed) { } } - -#endif // ENABLE(SVG) |