⚠ Archived content — this site is no longer maintained.   Current WebKit documentation is at docs.webkit.org.

Changeset 294385 in webkit


Ignore:
Timestamp:
May 18, 2022, 1:47:17 AM (4 years ago)
Author:
commit-queue@webkit.org
Message:

Activate text rendering, by re-using RenderSVGText
​https://bugs.webkit.org/show_bug.cgi?id=239743

Patch by Nikolas Zimmermann <​nzimmermann@igalia.com> on 2022-05-18
Reviewed by Rob Buis.

Adapt RenderSVGText to be usable at the same time from legacy SVG engine (as
it is right now) and from LBSE. This requires minimal effort, since RenderSVGText
already inherited from RenderLayerModelObject, so there's no need for the creation
of LegacyRenderSVGText / RenderSVGText as separated legacy/LBSE implementations.

Most SVG 1.1 <text> testcases already pass out of the box with this change.
The next patch after text support will add a new 'macos-wk2-lbse-xxx' specific
platform baseline, so that we can run tests LBSE againt iself (finally we can
include the progressions in the form of TestExpectation file changes, once a certain
patch implements a new feature in LBSE. This makes sense now as enough is upstreamed
that a considerable amount of the SVG 1.1 testsuite already passes pixel perfect.

Covered by existing tests, no change in behaviour. (However testability for LBSE is ready soon!).

  • rendering/RenderLayerModelObject.cpp:

(WebCore::RenderLayerModelObject::computeVisibleRectInSVGContainer const):

  • rendering/RenderObject.cpp:

(WebCore::objectIsRelayoutBoundary):

  • rendering/svg/RenderSVGBlock.cpp:

(WebCore::RenderSVGBlock::updateFromStyle):
(WebCore::RenderSVGBlock::absoluteRects const):
(WebCore::RenderSVGBlock::absoluteQuads const):
(WebCore::RenderSVGBlock::styleDidChange):
(WebCore::RenderSVGBlock::computeOverflow):
(WebCore::RenderSVGBlock::clippedOverflowRect const):
(WebCore::RenderSVGBlock::computeVisibleRectInContainer const):
(WebCore::RenderSVGBlock::computeFloatVisibleRectInContainer const):
(WebCore::RenderSVGBlock::pushMappingToContainer const):
(WebCore::RenderSVGBlock::offsetFromContainer const):
(WebCore::RenderSVGBlock::nodeAtPoint): Deleted.

  • rendering/svg/RenderSVGBlock.h:
  • rendering/svg/RenderSVGText.cpp:

(WebCore::RenderSVGText::RenderSVGText):
(WebCore::RenderSVGText::layout):
(WebCore::RenderSVGText::nodeAtFloatPoint):
(WebCore::RenderSVGText::nodeAtPoint):
(WebCore::RenderSVGText::paint):
(WebCore::RenderSVGText::repaintRectInLocalCoordinates const):
(WebCore::RenderSVGText::updatePositionAndOverflow):
(WebCore::RenderSVGText::absoluteQuads const): Deleted.

  • rendering/svg/RenderSVGText.h:
  • rendering/svg/SVGRootInlineBox.cpp:

(WebCore::SVGRootInlineBox::renderSVGText const):
(WebCore::SVGRootInlineBox::paint):
(WebCore::SVGRootInlineBox::layoutRootBox):
(WebCore::SVGRootInlineBox::renderSVGText): Deleted.

  • rendering/svg/SVGRootInlineBox.h:
  • svg/SVGElement.cpp:

(WebCore::createSVGLayerAwareElementSet):

Canonical link: ​https://commits.webkit.org/250682@main

Location:
trunk/Source/WebCore
Files:
10 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/rendering/RenderElement.cpp

    r294195 r294385  
    11881188        return false;
    11891189
    1190     LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
    1191     if (deltaLeft > 0)
    1192         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
    1193     else if (deltaLeft < 0)
    1194         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
    1195 
    1196     LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
    1197     if (deltaRight > 0)
    1198         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
    1199     else if (deltaRight < 0)
    1200         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
    1201 
    1202     LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
    1203     if (deltaTop > 0)
    1204         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
    1205     else if (deltaTop < 0)
    1206         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
    1207 
    1208     LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
    1209     if (deltaBottom > 0)
    1210         repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
    1211     else if (deltaBottom < 0)
    1212         repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
     1190    if (newBounds.isEmpty() && !oldBounds.isEmpty())
     1191        repaintUsingContainer(repaintContainer, oldBounds);
     1192    else if (!newBounds.isEmpty() && oldBounds.isEmpty())
     1193        repaintUsingContainer(repaintContainer, newBounds);
     1194    else {
     1195        LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
     1196        if (deltaLeft > 0)
     1197            repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
     1198        else if (deltaLeft < 0)
     1199            repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
     1200
     1201        LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
     1202        if (deltaRight > 0)
     1203            repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
     1204        else if (deltaRight < 0)
     1205            repaintUsingContainer(repaintContainer, LayoutRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
     1206
     1207        LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
     1208        if (deltaTop > 0)
     1209            repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
     1210        else if (deltaTop < 0)
     1211            repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
     1212
     1213        LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
     1214        if (deltaBottom > 0)
     1215            repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
     1216        else if (deltaBottom < 0)
     1217            repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
     1218    }
    12131219
    12141220    if (newOutlineBox == oldOutlineBox)
  • trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp

    r293504 r294385  
    3030#include "RenderLayerCompositor.h"
    3131#include "RenderLayerScrollableArea.h"
     32#include "RenderSVGBlock.h"
    3233#include "RenderSVGModelObject.h"
    3334#include "RenderView.h"
    … …  
    246247std::optional<LayoutRect> RenderLayerModelObject::computeVisibleRectInSVGContainer(const LayoutRect& rect, const RenderLayerModelObject* container, RenderObject::VisibleRectContext context) const
    247248{
    248     // FIXME: [LBSE] Upstream RenderSVGBlock changes
    249     // ASSERT(is<RenderSVGModelObject>(this) || is<RenderSVGBlock>(this));
    250     ASSERT(is<RenderSVGModelObject>(this));
    251 
     249    ASSERT(is<RenderSVGModelObject>(this) || is<RenderSVGBlock>(this));
    252250    ASSERT(!style().hasInFlowPosition());
    253251    ASSERT(!view().frameView().layoutContext().isPaintOffsetCacheEnabled());
  • trunk/Source/WebCore/rendering/RenderObject.cpp

    r293900 r294385  
    522522        return false;
    523523
     524#if ENABLE(LAYER_BASED_SVG_ENGINE)
     525    if (object->document().settings().layerBasedSVGEngineEnabled() && object->isSVGLayerAwareRenderer())
     526        return false;
     527#endif
     528
    524529    if (object->style().width().isIntrinsicOrAuto() || object->style().height().isIntrinsicOrAuto() || object->style().height().isPercentOrCalculated())
    525530        return false;
  • trunk/Source/WebCore/rendering/svg/RenderSVGBlock.cpp

    r287877 r294385  
    2323#include "RenderSVGBlock.h"
    2424
     25#include "RenderSVGBlockInlines.h"
    2526#include "RenderSVGResource.h"
    2627#include "SVGGraphicsElement.h"
    … …  
    4344    RenderBlockFlow::updateFromStyle();
    4445
     46#if ENABLE(LAYER_BASED_SVG_ENGINE)
     47    if (document().settings().layerBasedSVGEngineEnabled()) {
     48        updateHasSVGTransformFlags(graphicsElement());
     49        return;
     50    }
     51#endif
     52
    4553    // RenderSVGlock, used by Render(SVGText|ForeignObject), is not allowed to call setHasNonVisibleOverflow(true).
    4654    // RenderBlock assumes a layer to be present when the overflow clip functionality is requested. Both
    … …  
    5866}
    5967
    60 void RenderSVGBlock::absoluteRects(Vector<IntRect>&, const LayoutPoint&) const
     68void RenderSVGBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
    6169{
     70#if ENABLE(LAYER_BASED_SVG_ENGINE)
     71    if (document().settings().layerBasedSVGEngineEnabled()) {
     72        rects.append(snappedIntRect(LayoutRect(accumulatedOffset + location(), size())));
     73        return;
     74    }
     75#else
     76    UNUSED_PARAM(rects);
     77    UNUSED_PARAM(accumulatedOffset);
     78#endif
     79
    6280    // This code path should never be taken for SVG, as we're assuming useTransforms=true everywhere, absoluteQuads should be used.
    6381    ASSERT_NOT_REACHED();
     82}
     83
     84void RenderSVGBlock::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
     85{
     86    quads.append(localToAbsoluteQuad(strokeBoundingBox(), UseTransforms, wasFixed));
    6487}
    6588
    … …  
    7295void RenderSVGBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
    7396{
     97#if ENABLE(LAYER_BASED_SVG_ENGINE)
     98    if (diff == StyleDifference::Layout && !document().settings().layerBasedSVGEngineEnabled())
     99#else
    74100    if (diff == StyleDifference::Layout)
     101#endif
    75102        setNeedsBoundariesUpdate();
    76103    RenderBlockFlow::styleDidChange(diff, oldStyle);
    … …  
    81108{
    82109    RenderBlockFlow::computeOverflow(oldClientAfterEdge, recomputeFloats);
     110
     111#if ENABLE(LAYER_BASED_SVG_ENGINE)
     112    if (document().settings().layerBasedSVGEngineEnabled())
     113        return;
     114#endif
    83115
    84116    const auto* textShadow = style().textShadow();
    … …  
    91123}
    92124
    93 LayoutRect RenderSVGBlock::clippedOverflowRect(const RenderLayerModelObject* repaintContainer, VisibleRectContext) const
     125LayoutRect RenderSVGBlock::clippedOverflowRect(const RenderLayerModelObject* repaintContainer, VisibleRectContext context) const
    94126{
     127#if ENABLE(LAYER_BASED_SVG_ENGINE)
     128    if (document().settings().layerBasedSVGEngineEnabled()) {
     129        if (isInsideEntirelyHiddenLayer())
     130            return { };
     131
     132        ASSERT(!view().frameView().layoutContext().isPaintOffsetCacheEnabled());
     133        return computeRect(visualOverflowRect(), repaintContainer, context);
     134    }
     135#else
     136    UNUSED_PARAM(context);
     137#endif
     138
    95139    return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer);
    96140}
    … …  
    98142std::optional<LayoutRect> RenderSVGBlock::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const
    99143{
     144#if ENABLE(LAYER_BASED_SVG_ENGINE)
     145    if (document().settings().layerBasedSVGEngineEnabled())
     146        return computeVisibleRectInSVGContainer(rect, container, context);
     147#endif
     148
    100149    std::optional<FloatRect> adjustedRect = computeFloatVisibleRectInContainer(rect, container, context);
    101150    if (adjustedRect)
    … …  
    106155std::optional<FloatRect> RenderSVGBlock::computeFloatVisibleRectInContainer(const FloatRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const
    107156{
     157#if ENABLE(LAYER_BASED_SVG_ENGINE)
     158    ASSERT(!document().settings().layerBasedSVGEngineEnabled());
     159#endif
    108160    return SVGRenderSupport::computeFloatVisibleRectInContainer(*this, rect, container, context);
    109161}
    … …  
    116168const RenderObject* RenderSVGBlock::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
    117169{
     170#if ENABLE(LAYER_BASED_SVG_ENGINE)
     171    if (document().settings().layerBasedSVGEngineEnabled())
     172        return RenderBox::pushMappingToContainer(ancestorToStopAt, geometryMap);
     173#endif
     174
    118175    return SVGRenderSupport::pushMappingToContainer(*this, ancestorToStopAt, geometryMap);
    119176}
    120177
    121 bool RenderSVGBlock::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction)
     178#if ENABLE(LAYER_BASED_SVG_ENGINE)
     179LayoutSize RenderSVGBlock::offsetFromContainer(RenderElement& container, const LayoutPoint&, bool*) const
    122180{
    123     ASSERT_NOT_REACHED();
    124     return false;
     181    ASSERT_UNUSED(container, &container == this->container());
     182    ASSERT(!isInFlowPositioned());
     183    ASSERT(!isAbsolutelyPositioned());
     184    ASSERT(!isInline());
     185    return LayoutSize();
    125186}
     187#endif
    126188
    127189}
  • trunk/Source/WebCore/rendering/svg/RenderSVGBlock.h

    r293504 r294385  
    4646
    4747    void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const override;
    48 
     48    void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
    4949    void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
    5050
    … …  
    6060    void mapLocalToContainer(const RenderLayerModelObject* ancestorContainer, TransformState&, OptionSet<MapCoordinatesMode>, bool* wasFixed) const final;
    6161    const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const final;
    62 
    63     bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) final;
     62#if ENABLE(LAYER_BASED_SVG_ENGINE)
     63    LayoutSize offsetFromContainer(RenderElement&, const LayoutPoint&, bool* offsetDependsOnPoint = nullptr) const override;
     64#endif
    6465};
    6566
  • trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp

    r290867 r294385  
    4141#include "RenderSVGInlineText.h"
    4242#include "RenderSVGResource.h"
     43#include "RenderSVGRoot.h"
    4344#include "SVGElementTypeHelpers.h"
    4445#include "SVGLengthList.h"
    … …  
    5859RenderSVGText::RenderSVGText(SVGTextElement& element, RenderStyle&& style)
    5960    : RenderSVGBlock(element, WTFMove(style))
    60     , m_needsReordering(false)
    61     , m_needsPositioningValuesUpdate(false)
    62     , m_needsTransformUpdate(true)
    63     , m_needsTextMetricsUpdate(false)
    6461{
    6562}
    … …  
    312309void RenderSVGText::layout()
    313310{
     311    auto isLayerBasedSVGEngineEnabled = [&]() {
     312#if ENABLE(LAYER_BASED_SVG_ENGINE)
     313        return document().settings().layerBasedSVGEngineEnabled();
     314#else
     315        return false;
     316#endif
     317    };
     318
    314319    StackStats::LayoutCheckPoint layoutCheckPoint;
    315320    ASSERT(needsLayout());
    316     LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(*this));
     321    LayoutRepainter repainter(*this, isLayerBasedSVGEngineEnabled() ? checkForRepaintDuringLayout() : SVGRenderSupport::checkForSVGRepaintDuringLayout(*this));
     322
     323    // FIXME: [LBSE] Upstream SVGLengthContext changes
     324    // textElement().updateLengthContext();
    317325
    318326    bool updateCachedBoundariesInParents = false;
    319     if (m_needsTransformUpdate) {
    320         m_localTransform = textElement().animatedLocalTransform();
    321         m_needsTransformUpdate = false;
    322         updateCachedBoundariesInParents = true;
     327    if (!isLayerBasedSVGEngineEnabled()) {
     328        if (m_needsTransformUpdate) {
     329            m_localTransform = textElement().animatedLocalTransform();
     330            m_needsTransformUpdate = false;
     331            updateCachedBoundariesInParents = true;
     332        }
    323333    }
    324334
    … …  
    348358        updateCachedBoundariesInParents = true;
    349359    } else {
    350         LegacyRenderSVGRoot* rootObj = SVGRenderSupport::findTreeRootObject(*this);
    351         if (m_needsTextMetricsUpdate || (rootObj && rootObj->isLayoutSizeChanged())) {
     360        bool isLayoutSizeChanged = false;
     361        if (auto* legacyRootObject = lineageOfType<LegacyRenderSVGRoot>(*this).first())
     362            isLayoutSizeChanged = legacyRootObject->isLayoutSizeChanged();
     363#if ENABLE(LAYER_BASED_SVG_ENGINE)
     364        else if (auto* rootObject = lineageOfType<RenderSVGRoot>(*this).first())
     365            isLayoutSizeChanged = rootObject->isLayoutSizeChanged();
     366#endif
     367
     368        if (m_needsTextMetricsUpdate || isLayoutSizeChanged) {
    352369            // If the root layout size changed (eg. window size changes) or the transform to the root
    353370            // context has changed then recompute the on-screen font size.
    … …  
    366383    // All if branches that could cause early exit in RenderBlocks layoutBlock() method are turned into assertions.
    367384    ASSERT(!isInline());
    368     ASSERT(!simplifiedLayout());
    369385    ASSERT(!scrollsOverflow());
    370386    ASSERT(!hasControlClip());
    371387    ASSERT(!multiColumnFlow());
    372388    ASSERT(!positionedObjects());
    373     ASSERT(!m_overflow);
    374389    ASSERT(!isAnonymousBlock());
    375 
    376     if (!firstChild())
     390    if (!isLayerBasedSVGEngineEnabled()) {
     391        ASSERT(!simplifiedLayout());
     392        ASSERT(!m_overflow);
     393    }
     394
     395    // FIXME: We need to find a way to only layout the child boxes, if needed.
     396    auto layoutChanged = everHadLayout() && selfNeedsLayout();
     397    auto oldBoundaries = objectBoundingBox();
     398
     399    if (!firstChild()) {
     400        updatePositionAndOverflow({ });
    377401        setChildrenInline(true);
    378 
    379     // FIXME: We need to find a way to only layout the child boxes, if needed.
    380     FloatRect oldBoundaries = objectBoundingBox();
     402    }
     403
    381404    ASSERT(childrenInline());
     405
    382406    LayoutUnit repaintLogicalTop;
    383407    LayoutUnit repaintLogicalBottom;
    … …  
    385409    layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
    386410
     411    // updatePositionAndOverflow() is called by SVGRootInlineBox, after forceLayoutInlineChildren() ran, before this point is reached.
    387412    if (m_needsReordering)
    388413        m_needsReordering = false;
    389414
    390     if (!updateCachedBoundariesInParents)
     415    if (isLayerBasedSVGEngineEnabled()) {
     416        updateLayerTransform();
     417        updateCachedBoundariesInParents = false; // No longer needed for LBSE.
     418    } else if (!updateCachedBoundariesInParents)
    391419        updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox();
    392420
    393421    // Invalidate all resources of this client if our layout changed.
    394     if (everHadLayout() && selfNeedsLayout())
     422    if (layoutChanged)
    395423        SVGResourcesCache::clientLayoutChanged(*this);
    396424
    … …  
    405433bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
    406434{
     435#if ENABLE(LAYER_BASED_SVG_ENGINE)
     436    ASSERT(!document().settings().layerBasedSVGEngineEnabled());
     437#endif
    407438    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, style().effectivePointerEvents());
    408439    bool isVisible = (style().visibility() == Visibility::Visible);
    … …  
    413444
    414445            if (!SVGRenderSupport::pointInClippingArea(*this, localPoint))
    415                 return false;       
     446                return false;
    416447
    417448            SVGHitTestCycleDetectionScope hitTestScope(*this);
    … …  
    424455    return false;
    425456}
     457
     458#if ENABLE(LAYER_BASED_SVG_ENGINE)
     459bool RenderSVGText::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
     460{
     461    ASSERT(document().settings().layerBasedSVGEngineEnabled());
     462    auto adjustedLocation = accumulatedOffset + location();
     463
     464    PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, style().pointerEvents());
     465    bool isVisible = (style().visibility() == Visibility::Visible);
     466    if (isVisible || !hitRules.requireVisible) {
     467        if ((hitRules.canHitStroke && (style().svgStyle().hasStroke() || !hitRules.requireStroke))
     468        || (hitRules.canHitFill && (style().svgStyle().hasFill() || !hitRules.requireFill))) {
     469            auto localPoint = locationInContainer.point();
     470            auto coordinateSystemOriginTranslation = nominalSVGLayoutLocation() - adjustedLocation;
     471            localPoint.move(coordinateSystemOriginTranslation);
     472
     473            if (!SVGRenderSupport::pointInClippingArea(*this, localPoint))
     474                return false;
     475
     476            SVGHitTestCycleDetectionScope hitTestScope(*this);
     477            return RenderBlock::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction);
     478        }
     479    }
     480
     481    return false;
     482}
     483#endif
    426484
    427485VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInContents, const RenderFragmentContainer* fragment)
    … …  
    441499}
    442500
    443 void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
    444 {
    445     quads.append(localToAbsoluteQuad(strokeBoundingBox(), UseTransforms, wasFixed));
    446 }
    447 
    448 void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&)
     501void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
    449502{
    450503    if (paintInfo.context().paintingDisabled())
    451504        return;
    452505
    453     if (paintInfo.phase != PaintPhase::Foreground && paintInfo.phase != PaintPhase::Selection)
    454          return;
     506    if (paintInfo.phase != PaintPhase::ClippingMask && paintInfo.phase != PaintPhase::Mask && paintInfo.phase != PaintPhase::Foreground && paintInfo.phase != PaintPhase::Outline && paintInfo.phase != PaintPhase::SelfOutline)
     507        return;
     508
     509    if (!paintInfo.shouldPaintWithinRoot(*this))
     510        return;
     511
     512#if ENABLE(LAYER_BASED_SVG_ENGINE)
     513    if (document().settings().layerBasedSVGEngineEnabled()) {
     514        if (style().visibility() == Visibility::Hidden || style().display() == DisplayType::None)
     515            return;
     516
     517        // FIXME: [LBSE] Upstream SVGRenderSupport changes
     518        // if (!SVGRenderSupport::shouldPaintHiddenRenderer(*this))
     519        //     return;
     520
     521        if (paintInfo.phase == PaintPhase::ClippingMask) {
     522            // FIXME: [LBSE] Upstream SVGRenderSupport changes
     523            // SVGRenderSupport::paintSVGClippingMask(*this, paintInfo);
     524            return;
     525        }
     526
     527        auto adjustedPaintOffset = paintOffset + location();
     528        if (paintInfo.phase == PaintPhase::Mask) {
     529            // FIXME: [LBSE] Upstream SVGRenderSupport changes
     530            // SVGRenderSupport::paintSVGMask(*this, paintInfo, adjustedPaintOffset);
     531            return;
     532        }
     533
     534        if (paintInfo.phase == PaintPhase::Outline || paintInfo.phase == PaintPhase::SelfOutline) {
     535            RenderBlock::paint(paintInfo, paintOffset);
     536            return;
     537        }
     538
     539        GraphicsContextStateSaver stateSaver(paintInfo.context());
     540
     541        auto coordinateSystemOriginTranslation = adjustedPaintOffset - nominalSVGLayoutLocation();
     542        paintInfo.context().translate(coordinateSystemOriginTranslation.width(), coordinateSystemOriginTranslation.height());
     543
     544        RenderBlock::paint(paintInfo, paintOffset);
     545        return;
     546    }
     547#else
     548    UNUSED_PARAM(paintOffset);
     549#endif
    455550
    456551    PaintInfo blockInfo(paintInfo);
    … …  
    480575FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
    481576{
     577#if ENABLE(LAYER_BASED_SVG_ENGINE)
     578    if (document().settings().layerBasedSVGEngineEnabled())
     579        return SVGBoundingBoxComputation::computeRepaintBoundingBox(*this);
     580#endif
     581
    482582    FloatRect repaintRect = strokeBoundingBox();
    483583    SVGRenderSupport::intersectRepaintRectWithResources(*this, repaintRect);
    … …  
    489589}
    490590
    491 }
     591void RenderSVGText::updatePositionAndOverflow(const FloatRect& boundaries)
     592{
     593#if ENABLE(LAYER_BASED_SVG_ENGINE)
     594    if (document().settings().layerBasedSVGEngineEnabled()) {
     595        clearOverflow();
     596
     597        m_objectBoundingBox = boundaries;
     598
     599        auto boundingRect = enclosingLayoutRect(m_objectBoundingBox);
     600        setLocation(boundingRect.location());
     601        setSize(boundingRect.size());
     602
     603        auto overflowRect = visualOverflowRectEquivalent();
     604        if (const auto* textShadow = style().textShadow())
     605            textShadow->adjustRectForShadow(overflowRect);
     606
     607        addVisualOverflow(overflowRect);
     608        return;
     609    }
     610#endif
     611
     612    auto boundingRect = enclosingLayoutRect(boundaries);
     613    setLocation(boundingRect.location());
     614    setSize(boundingRect.size());
     615    m_objectBoundingBox = boundingRect;
     616    ASSERT(m_objectBoundingBox == frameRect());
     617}
     618
     619}
  • trunk/Source/WebCore/rendering/svg/RenderSVGText.h

    r291992 r294385  
    2424#include "AffineTransform.h"
    2525#include "RenderSVGBlock.h"
     26#include "SVGBoundingBoxComputation.h"
    2627#include "SVGTextLayoutAttributesBuilder.h"
    2728
    … …  
    4344
    4445    void setNeedsPositioningValuesUpdate() { m_needsPositioningValuesUpdate = true; }
     46    void setNeedsTextMetricsUpdate() { m_needsTextMetricsUpdate = true; }
     47
     48    // FIXME: [LBSE] Only needed for legacy SVG engine.
    4549    void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
    46     void setNeedsTextMetricsUpdate() { m_needsTextMetricsUpdate = true; }
    47     FloatRect repaintRectInLocalCoordinates() const override;
    4850
    4951    static RenderSVGText* locateRenderSVGTextAncestor(RenderObject&);
    … …  
    5961    void subtreeTextDidChange(RenderSVGInlineText*);
    6062
    61     FloatRect objectBoundingBox() const override { return frameRect(); }
    62     FloatRect strokeBoundingBox() const override;
     63    FloatRect objectBoundingBox() const final { return m_objectBoundingBox; }
     64    FloatRect strokeBoundingBox() const final;
     65    FloatRect repaintRectInLocalCoordinates() const final;
     66
     67#if ENABLE(LAYER_BASED_SVG_ENGINE)
     68    LayoutRect visualOverflowRectEquivalent() const { return SVGBoundingBoxComputation::computeVisualOverflowRect(*this); }
     69#endif
     70    void updatePositionAndOverflow(const FloatRect&);
    6371
    6472private:
    … …  
    6977
    7078    void paint(PaintInfo&, const LayoutPoint&) override;
    71     bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) override;
     79#if ENABLE(LAYER_BASED_SVG_ENGINE)
     80    bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
     81#endif
    7282    VisiblePosition positionForPoint(const LayoutPoint&, const RenderFragmentContainer*) override;
    7383
    74     bool requiresLayer() const override { return false; }
     84    bool requiresLayer() const override
     85    {
     86#if ENABLE(LAYER_BASED_SVG_ENGINE)
     87        if (document().settings().layerBasedSVGEngineEnabled())
     88            return true;
     89#endif
     90        return false;
     91    }
     92
    7593    void layout() override;
    76 
    77     void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
    7894
    7995    void willBeDestroyed() override;
    8096
     97    // FIXME: [LBSE] Begin code only needed for legacy SVG engine.
     98    bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) override;
    8199    const AffineTransform& localToParentTransform() const override { return m_localTransform; }
    82100    AffineTransform localTransform() const override { return m_localTransform; }
     101    // FIXME: [LBSE] End code only needed for legacy SVG engine.
    83102
    84103    bool shouldHandleSubtreeMutations() const;
    85104
    86     bool m_needsReordering : 1;
    87     bool m_needsPositioningValuesUpdate : 1;
    88     bool m_needsTransformUpdate : 1;
    89     bool m_needsTextMetricsUpdate : 1;
    90     AffineTransform m_localTransform;
     105    bool m_needsReordering : 1 { false };
     106    bool m_needsPositioningValuesUpdate : 1 { false };
     107    bool m_needsTransformUpdate : 1 { true }; // FIXME: [LBSE] Only needed for legacy SVG engine.
     108    bool m_needsTextMetricsUpdate : 1 { false };
     109    AffineTransform m_localTransform; // FIXME: [LBSE] Only needed for legacy SVG engine.
    91110    SVGTextLayoutAttributesBuilder m_layoutAttributesBuilder;
    92111    Vector<SVGTextLayoutAttributes*> m_layoutAttributes;
     112    FloatRect m_objectBoundingBox;
    93113};
    94114
  • trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp

    r291548 r294385  
    4747}
    4848
    49 RenderSVGText& SVGRootInlineBox::renderSVGText()
     49RenderSVGText& SVGRootInlineBox::renderSVGText() const
    5050{
    5151    return downcast<RenderSVGText>(blockFlow());
    5252}
    5353
    54 void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
     54void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
    5555{
    5656    ASSERT(paintInfo.phase == PaintPhase::Foreground || paintInfo.phase == PaintPhase::Selection);
    5757    ASSERT(!paintInfo.context().paintingDisabled());
     58
     59#if ENABLE(LAYER_BASED_SVG_ENGINE)
     60    if (renderer().document().settings().layerBasedSVGEngineEnabled()) {
     61        auto overflowRect(visualOverflowRect(lineTop, lineBottom));
     62        flipForWritingMode(overflowRect);
     63        overflowRect.moveBy(paintOffset);
     64
     65        if (!paintInfo.rect.intersects(overflowRect))
     66            return;
     67    }
     68#else
     69    UNUSED_PARAM(lineTop);
     70    UNUSED_PARAM(lineBottom);
     71#endif
    5872
    5973    bool isPrinting = renderSVGText().document().printing();
    … …  
    6276
    6377    PaintInfo childPaintInfo(paintInfo);
     78    childPaintInfo.updateSubtreePaintRootForChildren(&renderer());
     79
    6480    if (hasSelection && shouldPaintSelectionHighlight) {
    6581        for (auto* child = firstChild(); child; child = child->nextOnLine()) {
    … …  
    7086        }
    7187    }
     88
     89#if ENABLE(LAYER_BASED_SVG_ENGINE)
     90    if (renderer().document().settings().layerBasedSVGEngineEnabled()) {
     91        for (auto* child = firstChild(); child; child = child->nextOnLine()) {
     92            if (child->renderer().isText() || !child->boxModelObject()->hasSelfPaintingLayer())
     93                child->paint(childPaintInfo, paintOffset, lineTop, lineBottom);
     94        }
     95
     96        return;
     97    }
     98#endif
    7299
    73100    SVGRenderingContext renderingContext(renderSVGText(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
    … …  
    171198
    172199    // Finally, assign the root block position, now that all content is laid out.
    173     LayoutRect boundingRect = enclosingLayoutRect(childRect);
    174     parentBlock.setLocation(boundingRect.location());
    175     parentBlock.setSize(boundingRect.size());
     200    parentBlock.updatePositionAndOverflow(childRect);
    176201
    177202    // Position all children relative to the parent block.
    … …  
    188213    setLogicalWidth(childRect.width());
    189214    setLogicalHeight(childRect.height());
     215
     216    auto boundingRect = enclosingLayoutRect(childRect);
    190217    setLineTopBottomPositions(0, boundingRect.height(), 0, boundingRect.height());
    191218}
  • trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.h

    r284315 r294385  
    3636    explicit SVGRootInlineBox(RenderSVGText&);
    3737
    38     RenderSVGText& renderSVGText();
    39 
    4038    float virtualLogicalHeight() const override { return m_logicalHeight; }
    4139    void setLogicalHeight(float height) { m_logicalHeight = height; }
    … …  
    5048
    5149private:
     50    RenderSVGText& renderSVGText() const;
     51
    5252    bool isSVGRootInlineBox() const override { return true; }
    5353    void reorderValueListsToLogicalOrder(Vector<SVGTextLayoutAttributes*>&);
  • trunk/Source/WebCore/svg/SVGElement.cpp

    r294067 r294385  
    532532    using namespace SVGNames;
    533533    MemoryCompactLookupOnlyRobinHoodHashSet<AtomString> set;
    534     for (auto& tag : { gTag.get(), rectTag.get() })
     534    for (auto& tag : { gTag.get(), rectTag.get(), textTag.get() })
    535535        set.add(tag.localName());
    536536    return set;
Note: See TracChangeset for help on using the changeset viewer.