Diff
Modified: trunk/Source/WebCore/rendering/RenderElement.cpp (294384 => 294385)
--- trunk/Source/WebCore/rendering/RenderElement.cpp 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/RenderElement.cpp 2022-05-18 08:47:17 UTC (rev 294385)
@@ -1187,29 +1187,35 @@
if (newBounds == oldBounds && newOutlineBox == oldOutlineBox)
return false;
- LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
- if (deltaLeft > 0)
- repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
- else if (deltaLeft < 0)
- repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
+ if (newBounds.isEmpty() && !oldBounds.isEmpty())
+ repaintUsingContainer(repaintContainer, oldBounds);
+ else if (!newBounds.isEmpty() && oldBounds.isEmpty())
+ repaintUsingContainer(repaintContainer, newBounds);
+ else {
+ LayoutUnit deltaLeft = newBounds.x() - oldBounds.x();
+ if (deltaLeft > 0)
+ repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height()));
+ else if (deltaLeft < 0)
+ repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height()));
- LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
- if (deltaRight > 0)
- repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
- else if (deltaRight < 0)
- repaintUsingContainer(repaintContainer, LayoutRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
+ LayoutUnit deltaRight = newBounds.maxX() - oldBounds.maxX();
+ if (deltaRight > 0)
+ repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.maxX(), newBounds.y(), deltaRight, newBounds.height()));
+ else if (deltaRight < 0)
+ repaintUsingContainer(repaintContainer, LayoutRect(newBounds.maxX(), oldBounds.y(), -deltaRight, oldBounds.height()));
- LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
- if (deltaTop > 0)
- repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
- else if (deltaTop < 0)
- repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
+ LayoutUnit deltaTop = newBounds.y() - oldBounds.y();
+ if (deltaTop > 0)
+ repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop));
+ else if (deltaTop < 0)
+ repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop));
- LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
- if (deltaBottom > 0)
- repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
- else if (deltaBottom < 0)
- repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
+ LayoutUnit deltaBottom = newBounds.maxY() - oldBounds.maxY();
+ if (deltaBottom > 0)
+ repaintUsingContainer(repaintContainer, LayoutRect(newBounds.x(), oldBounds.maxY(), newBounds.width(), deltaBottom));
+ else if (deltaBottom < 0)
+ repaintUsingContainer(repaintContainer, LayoutRect(oldBounds.x(), newBounds.maxY(), oldBounds.width(), -deltaBottom));
+ }
if (newOutlineBox == oldOutlineBox)
return false;
Modified: trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp (294384 => 294385)
--- trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/RenderLayerModelObject.cpp 2022-05-18 08:47:17 UTC (rev 294385)
@@ -29,6 +29,7 @@
#include "RenderLayerBacking.h"
#include "RenderLayerCompositor.h"
#include "RenderLayerScrollableArea.h"
+#include "RenderSVGBlock.h"
#include "RenderSVGModelObject.h"
#include "RenderView.h"
#include "SVGGraphicsElement.h"
@@ -245,10 +246,7 @@
#if ENABLE(LAYER_BASED_SVG_ENGINE)
std::optional<LayoutRect> RenderLayerModelObject::computeVisibleRectInSVGContainer(const LayoutRect& rect, const RenderLayerModelObject* container, RenderObject::VisibleRectContext context) const
{
- // FIXME: [LBSE] Upstream RenderSVGBlock changes
- // ASSERT(is<RenderSVGModelObject>(this) || is<RenderSVGBlock>(this));
- ASSERT(is<RenderSVGModelObject>(this));
-
+ ASSERT(is<RenderSVGModelObject>(this) || is<RenderSVGBlock>(this));
ASSERT(!style().hasInFlowPosition());
ASSERT(!view().frameView().layoutContext().isPaintOffsetCacheEnabled());
Modified: trunk/Source/WebCore/rendering/RenderObject.cpp (294384 => 294385)
--- trunk/Source/WebCore/rendering/RenderObject.cpp 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/RenderObject.cpp 2022-05-18 08:47:17 UTC (rev 294385)
@@ -521,6 +521,11 @@
if (!object->hasNonVisibleOverflow())
return false;
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (object->document().settings().layerBasedSVGEngineEnabled() && object->isSVGLayerAwareRenderer())
+ return false;
+#endif
+
if (object->style().width().isIntrinsicOrAuto() || object->style().height().isIntrinsicOrAuto() || object->style().height().isPercentOrCalculated())
return false;
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGBlock.cpp (294384 => 294385)
--- trunk/Source/WebCore/rendering/svg/RenderSVGBlock.cpp 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGBlock.cpp 2022-05-18 08:47:17 UTC (rev 294385)
@@ -22,6 +22,7 @@
#include "config.h"
#include "RenderSVGBlock.h"
+#include "RenderSVGBlockInlines.h"
#include "RenderSVGResource.h"
#include "SVGGraphicsElement.h"
#include "SVGRenderSupport.h"
@@ -42,6 +43,13 @@
{
RenderBlockFlow::updateFromStyle();
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled()) {
+ updateHasSVGTransformFlags(graphicsElement());
+ return;
+ }
+#endif
+
// RenderSVGlock, used by Render(SVGText|ForeignObject), is not allowed to call setHasNonVisibleOverflow(true).
// RenderBlock assumes a layer to be present when the overflow clip functionality is requested. Both
// Render(SVGText|ForeignObject) return 'false' on 'requiresLayer'. Fine for RenderSVGText.
@@ -57,12 +65,27 @@
setHasNonVisibleOverflow(false);
}
-void RenderSVGBlock::absoluteRects(Vector<IntRect>&, const LayoutPoint&) const
+void RenderSVGBlock::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled()) {
+ rects.append(snappedIntRect(LayoutRect(accumulatedOffset + location(), size())));
+ return;
+ }
+#else
+ UNUSED_PARAM(rects);
+ UNUSED_PARAM(accumulatedOffset);
+#endif
+
// 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::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
+{
+ quads.append(localToAbsoluteQuad(strokeBoundingBox(), UseTransforms, wasFixed));
+}
+
void RenderSVGBlock::willBeDestroyed()
{
SVGResourcesCache::clientDestroyed(*this);
@@ -71,7 +94,11 @@
void RenderSVGBlock::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (diff == StyleDifference::Layout && !document().settings().layerBasedSVGEngineEnabled())
+#else
if (diff == StyleDifference::Layout)
+#endif
setNeedsBoundariesUpdate();
RenderBlockFlow::styleDidChange(diff, oldStyle);
SVGResourcesCache::clientStyleChanged(*this, diff, style());
@@ -81,6 +108,11 @@
{
RenderBlockFlow::computeOverflow(oldClientAfterEdge, recomputeFloats);
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled())
+ return;
+#endif
+
const auto* textShadow = style().textShadow();
if (!textShadow)
return;
@@ -90,13 +122,30 @@
addVisualOverflow(snappedIntRect(borderRect));
}
-LayoutRect RenderSVGBlock::clippedOverflowRect(const RenderLayerModelObject* repaintContainer, VisibleRectContext) const
+LayoutRect RenderSVGBlock::clippedOverflowRect(const RenderLayerModelObject* repaintContainer, VisibleRectContext context) const
{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled()) {
+ if (isInsideEntirelyHiddenLayer())
+ return { };
+
+ ASSERT(!view().frameView().layoutContext().isPaintOffsetCacheEnabled());
+ return computeRect(visualOverflowRect(), repaintContainer, context);
+ }
+#else
+ UNUSED_PARAM(context);
+#endif
+
return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer);
}
std::optional<LayoutRect> RenderSVGBlock::computeVisibleRectInContainer(const LayoutRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const
{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled())
+ return computeVisibleRectInSVGContainer(rect, container, context);
+#endif
+
std::optional<FloatRect> adjustedRect = computeFloatVisibleRectInContainer(rect, container, context);
if (adjustedRect)
return enclosingLayoutRect(*adjustedRect);
@@ -105,6 +154,9 @@
std::optional<FloatRect> RenderSVGBlock::computeFloatVisibleRectInContainer(const FloatRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const
{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ ASSERT(!document().settings().layerBasedSVGEngineEnabled());
+#endif
return SVGRenderSupport::computeFloatVisibleRectInContainer(*this, rect, container, context);
}
@@ -115,13 +167,23 @@
const RenderObject* RenderSVGBlock::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled())
+ return RenderBox::pushMappingToContainer(ancestorToStopAt, geometryMap);
+#endif
+
return SVGRenderSupport::pushMappingToContainer(*this, ancestorToStopAt, geometryMap);
}
-bool RenderSVGBlock::nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation&, const LayoutPoint&, HitTestAction)
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+LayoutSize RenderSVGBlock::offsetFromContainer(RenderElement& container, const LayoutPoint&, bool*) const
{
- ASSERT_NOT_REACHED();
- return false;
+ ASSERT_UNUSED(container, &container == this->container());
+ ASSERT(!isInFlowPositioned());
+ ASSERT(!isAbsolutelyPositioned());
+ ASSERT(!isInline());
+ return LayoutSize();
}
+#endif
}
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGBlock.h (294384 => 294385)
--- trunk/Source/WebCore/rendering/svg/RenderSVGBlock.h 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGBlock.h 2022-05-18 08:47:17 UTC (rev 294385)
@@ -45,7 +45,7 @@
bool isRenderSVGBlock() const final { return true; }
void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const override;
-
+ void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
void styleDidChange(StyleDifference, const RenderStyle* oldStyle) final;
#if ENABLE(LAYER_BASED_SVG_ENGINE)
@@ -59,8 +59,9 @@
void mapLocalToContainer(const RenderLayerModelObject* ancestorContainer, TransformState&, OptionSet<MapCoordinatesMode>, bool* wasFixed) const final;
const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const final;
-
- bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) final;
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ LayoutSize offsetFromContainer(RenderElement&, const LayoutPoint&, bool* offsetDependsOnPoint = nullptr) const override;
+#endif
};
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp (294384 => 294385)
--- trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGText.cpp 2022-05-18 08:47:17 UTC (rev 294385)
@@ -40,6 +40,7 @@
#include "RenderSVGInline.h"
#include "RenderSVGInlineText.h"
#include "RenderSVGResource.h"
+#include "RenderSVGRoot.h"
#include "SVGElementTypeHelpers.h"
#include "SVGLengthList.h"
#include "SVGResourcesCache.h"
@@ -57,10 +58,6 @@
RenderSVGText::RenderSVGText(SVGTextElement& element, RenderStyle&& style)
: RenderSVGBlock(element, WTFMove(style))
- , m_needsReordering(false)
- , m_needsPositioningValuesUpdate(false)
- , m_needsTransformUpdate(true)
- , m_needsTextMetricsUpdate(false)
{
}
@@ -311,15 +308,28 @@
void RenderSVGText::layout()
{
+ auto isLayerBasedSVGEngineEnabled = [&]() {
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ return document().settings().layerBasedSVGEngineEnabled();
+#else
+ return false;
+#endif
+ };
+
StackStats::LayoutCheckPoint layoutCheckPoint;
ASSERT(needsLayout());
- LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(*this));
+ LayoutRepainter repainter(*this, isLayerBasedSVGEngineEnabled() ? checkForRepaintDuringLayout() : SVGRenderSupport::checkForSVGRepaintDuringLayout(*this));
+ // FIXME: [LBSE] Upstream SVGLengthContext changes
+ // textElement().updateLengthContext();
+
bool updateCachedBoundariesInParents = false;
- if (m_needsTransformUpdate) {
- m_localTransform = textElement().animatedLocalTransform();
- m_needsTransformUpdate = false;
- updateCachedBoundariesInParents = true;
+ if (!isLayerBasedSVGEngineEnabled()) {
+ if (m_needsTransformUpdate) {
+ m_localTransform = textElement().animatedLocalTransform();
+ m_needsTransformUpdate = false;
+ updateCachedBoundariesInParents = true;
+ }
}
if (!everHadLayout()) {
@@ -347,8 +357,15 @@
m_needsPositioningValuesUpdate = false;
updateCachedBoundariesInParents = true;
} else {
- LegacyRenderSVGRoot* rootObj = SVGRenderSupport::findTreeRootObject(*this);
- if (m_needsTextMetricsUpdate || (rootObj && rootObj->isLayoutSizeChanged())) {
+ bool isLayoutSizeChanged = false;
+ if (auto* legacyRootObject = lineageOfType<LegacyRenderSVGRoot>(*this).first())
+ isLayoutSizeChanged = legacyRootObject->isLayoutSizeChanged();
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ else if (auto* rootObject = lineageOfType<RenderSVGRoot>(*this).first())
+ isLayoutSizeChanged = rootObject->isLayoutSizeChanged();
+#endif
+
+ if (m_needsTextMetricsUpdate || 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);
@@ -365,33 +382,44 @@
// Reduced version of RenderBlock::layoutBlock(), which only takes care of SVG text.
// All if branches that could cause early exit in RenderBlocks layoutBlock() method are turned into assertions.
ASSERT(!isInline());
- ASSERT(!simplifiedLayout());
ASSERT(!scrollsOverflow());
ASSERT(!hasControlClip());
ASSERT(!multiColumnFlow());
ASSERT(!positionedObjects());
- ASSERT(!m_overflow);
ASSERT(!isAnonymousBlock());
+ if (!isLayerBasedSVGEngineEnabled()) {
+ ASSERT(!simplifiedLayout());
+ ASSERT(!m_overflow);
+ }
- if (!firstChild())
+ // FIXME: We need to find a way to only layout the child boxes, if needed.
+ auto layoutChanged = everHadLayout() && selfNeedsLayout();
+ auto oldBoundaries = objectBoundingBox();
+
+ if (!firstChild()) {
+ updatePositionAndOverflow({ });
setChildrenInline(true);
+ }
- // FIXME: We need to find a way to only layout the child boxes, if needed.
- FloatRect oldBoundaries = objectBoundingBox();
ASSERT(childrenInline());
+
LayoutUnit repaintLogicalTop;
LayoutUnit repaintLogicalBottom;
rebuildFloatingObjectSetFromIntrudingFloats();
layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
+ // updatePositionAndOverflow() is called by SVGRootInlineBox, after forceLayoutInlineChildren() ran, before this point is reached.
if (m_needsReordering)
m_needsReordering = false;
- if (!updateCachedBoundariesInParents)
+ if (isLayerBasedSVGEngineEnabled()) {
+ updateLayerTransform();
+ updateCachedBoundariesInParents = false; // No longer needed for LBSE.
+ } else if (!updateCachedBoundariesInParents)
updateCachedBoundariesInParents = oldBoundaries != objectBoundingBox();
// Invalidate all resources of this client if our layout changed.
- if (everHadLayout() && selfNeedsLayout())
+ if (layoutChanged)
SVGResourcesCache::clientLayoutChanged(*this);
// If our bounds changed, notify the parents.
@@ -404,6 +432,9 @@
bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ ASSERT(!document().settings().layerBasedSVGEngineEnabled());
+#endif
PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, style().effectivePointerEvents());
bool isVisible = (style().visibility() == Visibility::Visible);
if (isVisible || !hitRules.requireVisible) {
@@ -412,7 +443,7 @@
FloatPoint localPoint = valueOrDefault(localToParentTransform().inverse()).mapPoint(pointInParent);
if (!SVGRenderSupport::pointInClippingArea(*this, localPoint))
- return false;
+ return false;
SVGHitTestCycleDetectionScope hitTestScope(*this);
@@ -424,6 +455,33 @@
return false;
}
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+bool RenderSVGText::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction hitTestAction)
+{
+ ASSERT(document().settings().layerBasedSVGEngineEnabled());
+ auto adjustedLocation = accumulatedOffset + location();
+
+ PointerEventsHitRules hitRules(PointerEventsHitRules::SVG_TEXT_HITTESTING, request, style().pointerEvents());
+ bool isVisible = (style().visibility() == Visibility::Visible);
+ if (isVisible || !hitRules.requireVisible) {
+ if ((hitRules.canHitStroke && (style().svgStyle().hasStroke() || !hitRules.requireStroke))
+ || (hitRules.canHitFill && (style().svgStyle().hasFill() || !hitRules.requireFill))) {
+ auto localPoint = locationInContainer.point();
+ auto coordinateSystemOriginTranslation = nominalSVGLayoutLocation() - adjustedLocation;
+ localPoint.move(coordinateSystemOriginTranslation);
+
+ if (!SVGRenderSupport::pointInClippingArea(*this, localPoint))
+ return false;
+
+ SVGHitTestCycleDetectionScope hitTestScope(*this);
+ return RenderBlock::nodeAtPoint(request, result, locationInContainer, accumulatedOffset, hitTestAction);
+ }
+ }
+
+ return false;
+}
+#endif
+
VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInContents, const RenderFragmentContainer* fragment)
{
LegacyRootInlineBox* rootBox = firstRootBox();
@@ -440,19 +498,56 @@
return closestBox->renderer().positionForPoint({ pointInContents.x(), LayoutUnit(closestBox->y()) }, fragment);
}
-void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
+void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
- quads.append(localToAbsoluteQuad(strokeBoundingBox(), UseTransforms, wasFixed));
-}
-
-void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&)
-{
if (paintInfo.context().paintingDisabled())
return;
- if (paintInfo.phase != PaintPhase::Foreground && paintInfo.phase != PaintPhase::Selection)
- return;
+ if (paintInfo.phase != PaintPhase::ClippingMask && paintInfo.phase != PaintPhase::Mask && paintInfo.phase != PaintPhase::Foreground && paintInfo.phase != PaintPhase::Outline && paintInfo.phase != PaintPhase::SelfOutline)
+ return;
+ if (!paintInfo.shouldPaintWithinRoot(*this))
+ return;
+
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled()) {
+ if (style().visibility() == Visibility::Hidden || style().display() == DisplayType::None)
+ return;
+
+ // FIXME: [LBSE] Upstream SVGRenderSupport changes
+ // if (!SVGRenderSupport::shouldPaintHiddenRenderer(*this))
+ // return;
+
+ if (paintInfo.phase == PaintPhase::ClippingMask) {
+ // FIXME: [LBSE] Upstream SVGRenderSupport changes
+ // SVGRenderSupport::paintSVGClippingMask(*this, paintInfo);
+ return;
+ }
+
+ auto adjustedPaintOffset = paintOffset + location();
+ if (paintInfo.phase == PaintPhase::Mask) {
+ // FIXME: [LBSE] Upstream SVGRenderSupport changes
+ // SVGRenderSupport::paintSVGMask(*this, paintInfo, adjustedPaintOffset);
+ return;
+ }
+
+ if (paintInfo.phase == PaintPhase::Outline || paintInfo.phase == PaintPhase::SelfOutline) {
+ RenderBlock::paint(paintInfo, paintOffset);
+ return;
+ }
+
+ GraphicsContextStateSaver stateSaver(paintInfo.context());
+
+ auto coordinateSystemOriginTranslation = adjustedPaintOffset - nominalSVGLayoutLocation();
+ paintInfo.context().translate(coordinateSystemOriginTranslation.width(), coordinateSystemOriginTranslation.height());
+
+ RenderBlock::paint(paintInfo, paintOffset);
+ return;
+ }
+#else
+ UNUSED_PARAM(paintOffset);
+#endif
+
PaintInfo blockInfo(paintInfo);
GraphicsContextStateSaver stateSaver(blockInfo.context());
blockInfo.applyTransform(localToParentTransform());
@@ -479,6 +574,11 @@
FloatRect RenderSVGText::repaintRectInLocalCoordinates() const
{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled())
+ return SVGBoundingBoxComputation::computeRepaintBoundingBox(*this);
+#endif
+
FloatRect repaintRect = strokeBoundingBox();
SVGRenderSupport::intersectRepaintRectWithResources(*this, repaintRect);
@@ -488,4 +588,32 @@
return repaintRect;
}
+void RenderSVGText::updatePositionAndOverflow(const FloatRect& boundaries)
+{
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled()) {
+ clearOverflow();
+
+ m_objectBoundingBox = boundaries;
+
+ auto boundingRect = enclosingLayoutRect(m_objectBoundingBox);
+ setLocation(boundingRect.location());
+ setSize(boundingRect.size());
+
+ auto overflowRect = visualOverflowRectEquivalent();
+ if (const auto* textShadow = style().textShadow())
+ textShadow->adjustRectForShadow(overflowRect);
+
+ addVisualOverflow(overflowRect);
+ return;
+ }
+#endif
+
+ auto boundingRect = enclosingLayoutRect(boundaries);
+ setLocation(boundingRect.location());
+ setSize(boundingRect.size());
+ m_objectBoundingBox = boundingRect;
+ ASSERT(m_objectBoundingBox == frameRect());
}
+
+}
Modified: trunk/Source/WebCore/rendering/svg/RenderSVGText.h (294384 => 294385)
--- trunk/Source/WebCore/rendering/svg/RenderSVGText.h 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/svg/RenderSVGText.h 2022-05-18 08:47:17 UTC (rev 294385)
@@ -23,6 +23,7 @@
#include "AffineTransform.h"
#include "RenderSVGBlock.h"
+#include "SVGBoundingBoxComputation.h"
#include "SVGTextLayoutAttributesBuilder.h"
namespace WebCore {
@@ -42,10 +43,11 @@
bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
void setNeedsPositioningValuesUpdate() { m_needsPositioningValuesUpdate = true; }
- void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
void setNeedsTextMetricsUpdate() { m_needsTextMetricsUpdate = true; }
- FloatRect repaintRectInLocalCoordinates() const override;
+ // FIXME: [LBSE] Only needed for legacy SVG engine.
+ void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
+
static RenderSVGText* locateRenderSVGTextAncestor(RenderObject&);
static const RenderSVGText* locateRenderSVGTextAncestor(const RenderObject&);
@@ -58,9 +60,15 @@
void subtreeStyleDidChange(RenderSVGInlineText*);
void subtreeTextDidChange(RenderSVGInlineText*);
- FloatRect objectBoundingBox() const override { return frameRect(); }
- FloatRect strokeBoundingBox() const override;
+ FloatRect objectBoundingBox() const final { return m_objectBoundingBox; }
+ FloatRect strokeBoundingBox() const final;
+ FloatRect repaintRectInLocalCoordinates() const final;
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ LayoutRect visualOverflowRectEquivalent() const { return SVGBoundingBoxComputation::computeVisualOverflowRect(*this); }
+#endif
+ void updatePositionAndOverflow(const FloatRect&);
+
private:
void graphicsElement() const = delete;
@@ -68,28 +76,40 @@
bool isSVGText() const override { return true; }
void paint(PaintInfo&, const LayoutPoint&) override;
- bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) override;
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
+#endif
VisiblePosition positionForPoint(const LayoutPoint&, const RenderFragmentContainer*) override;
- bool requiresLayer() const override { return false; }
+ bool requiresLayer() const override
+ {
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (document().settings().layerBasedSVGEngineEnabled())
+ return true;
+#endif
+ return false;
+ }
+
void layout() override;
- void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
-
void willBeDestroyed() override;
+ // FIXME: [LBSE] Begin code only needed for legacy SVG engine.
+ bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) override;
const AffineTransform& localToParentTransform() const override { return m_localTransform; }
AffineTransform localTransform() const override { return m_localTransform; }
+ // FIXME: [LBSE] End code only needed for legacy SVG engine.
bool shouldHandleSubtreeMutations() const;
- bool m_needsReordering : 1;
- bool m_needsPositioningValuesUpdate : 1;
- bool m_needsTransformUpdate : 1;
- bool m_needsTextMetricsUpdate : 1;
- AffineTransform m_localTransform;
+ bool m_needsReordering : 1 { false };
+ bool m_needsPositioningValuesUpdate : 1 { false };
+ bool m_needsTransformUpdate : 1 { true }; // FIXME: [LBSE] Only needed for legacy SVG engine.
+ bool m_needsTextMetricsUpdate : 1 { false };
+ AffineTransform m_localTransform; // FIXME: [LBSE] Only needed for legacy SVG engine.
SVGTextLayoutAttributesBuilder m_layoutAttributesBuilder;
Vector<SVGTextLayoutAttributes*> m_layoutAttributes;
+ FloatRect m_objectBoundingBox;
};
} // namespace WebCore
Modified: trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp (294384 => 294385)
--- trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp 2022-05-18 08:47:17 UTC (rev 294385)
@@ -46,21 +46,37 @@
{
}
-RenderSVGText& SVGRootInlineBox::renderSVGText()
+RenderSVGText& SVGRootInlineBox::renderSVGText() const
{
return downcast<RenderSVGText>(blockFlow());
}
-void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
+void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit lineTop, LayoutUnit lineBottom)
{
ASSERT(paintInfo.phase == PaintPhase::Foreground || paintInfo.phase == PaintPhase::Selection);
ASSERT(!paintInfo.context().paintingDisabled());
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (renderer().document().settings().layerBasedSVGEngineEnabled()) {
+ auto overflowRect(visualOverflowRect(lineTop, lineBottom));
+ flipForWritingMode(overflowRect);
+ overflowRect.moveBy(paintOffset);
+
+ if (!paintInfo.rect.intersects(overflowRect))
+ return;
+ }
+#else
+ UNUSED_PARAM(lineTop);
+ UNUSED_PARAM(lineBottom);
+#endif
+
bool isPrinting = renderSVGText().document().printing();
bool hasSelection = !isPrinting && selectionState() != RenderObject::HighlightState::None;
bool shouldPaintSelectionHighlight = !(paintInfo.paintBehavior.contains(PaintBehavior::SkipSelectionHighlight));
PaintInfo childPaintInfo(paintInfo);
+ childPaintInfo.updateSubtreePaintRootForChildren(&renderer());
+
if (hasSelection && shouldPaintSelectionHighlight) {
for (auto* child = firstChild(); child; child = child->nextOnLine()) {
if (is<SVGInlineTextBox>(*child))
@@ -70,6 +86,17 @@
}
}
+#if ENABLE(LAYER_BASED_SVG_ENGINE)
+ if (renderer().document().settings().layerBasedSVGEngineEnabled()) {
+ for (auto* child = firstChild(); child; child = child->nextOnLine()) {
+ if (child->renderer().isText() || !child->boxModelObject()->hasSelfPaintingLayer())
+ child->paint(childPaintInfo, paintOffset, lineTop, lineBottom);
+ }
+
+ return;
+ }
+#endif
+
SVGRenderingContext renderingContext(renderSVGText(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
if (renderingContext.isRenderingPrepared()) {
for (auto* child = firstChild(); child; child = child->nextOnLine())
@@ -170,9 +197,7 @@
RenderSVGText& parentBlock = renderSVGText();
// Finally, assign the root block position, now that all content is laid out.
- LayoutRect boundingRect = enclosingLayoutRect(childRect);
- parentBlock.setLocation(boundingRect.location());
- parentBlock.setSize(boundingRect.size());
+ parentBlock.updatePositionAndOverflow(childRect);
// Position all children relative to the parent block.
for (auto* child = firstChild(); child; child = child->nextOnLine()) {
@@ -187,6 +212,8 @@
setY(0);
setLogicalWidth(childRect.width());
setLogicalHeight(childRect.height());
+
+ auto boundingRect = enclosingLayoutRect(childRect);
setLineTopBottomPositions(0, boundingRect.height(), 0, boundingRect.height());
}
Modified: trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.h (294384 => 294385)
--- trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.h 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/rendering/svg/SVGRootInlineBox.h 2022-05-18 08:47:17 UTC (rev 294385)
@@ -35,8 +35,6 @@
public:
explicit SVGRootInlineBox(RenderSVGText&);
- RenderSVGText& renderSVGText();
-
float virtualLogicalHeight() const override { return m_logicalHeight; }
void setLogicalHeight(float height) { m_logicalHeight = height; }
@@ -49,6 +47,8 @@
bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) final;
private:
+ RenderSVGText& renderSVGText() const;
+
bool isSVGRootInlineBox() const override { return true; }
void reorderValueListsToLogicalOrder(Vector<SVGTextLayoutAttributes*>&);
void layoutCharactersInTextBoxes(LegacyInlineFlowBox*, SVGTextLayoutEngine&);
Modified: trunk/Source/WebCore/svg/SVGElement.cpp (294384 => 294385)
--- trunk/Source/WebCore/svg/SVGElement.cpp 2022-05-18 07:18:55 UTC (rev 294384)
+++ trunk/Source/WebCore/svg/SVGElement.cpp 2022-05-18 08:47:17 UTC (rev 294385)
@@ -531,7 +531,7 @@
// List of all SVG elements whose renderers support the layer aware layout / painting / hit-testing mode ('LBSE-mode').
using namespace SVGNames;
MemoryCompactLookupOnlyRobinHoodHashSet<AtomString> set;
- for (auto& tag : { gTag.get(), rectTag.get() })
+ for (auto& tag : { gTag.get(), rectTag.get(), textTag.get() })
set.add(tag.localName());
return set;
}