Skip to content
Permalink
Browse files
[LBSE] Begin stub implementation of RenderSVGViewportContainer
https://bugs.webkit.org/show_bug.cgi?id=242701

Reviewed by Rob Buis.

Rename LegacyRenderSVGViewportContainer -> RenderSVGViewportContainer and adapt all call sites.
Introduce layer-aware RenderSVGViewportContainer at the same time as stub implementation.

Follow-up patches will bring support for inner <svg> elements.

* Source/WebCore/Sources.txt:
* Source/WebCore/WebCore.xcodeproj/project.pbxproj:
* Source/WebCore/rendering/RenderObject.h:
(WebCore::RenderObject::isLegacySVGViewportContainer const):
* Source/WebCore/rendering/svg/LegacyRenderSVGContainer.cpp:
(WebCore::LegacyRenderSVGContainer::layout):
(WebCore::LegacyRenderSVGContainer::paint):
(WebCore::LegacyRenderSVGContainer::nodeAtFloatPoint):
* Source/WebCore/rendering/svg/LegacyRenderSVGViewportContainer.cpp: Copied from Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp.
(WebCore::LegacyRenderSVGViewportContainer::LegacyRenderSVGViewportContainer):
(WebCore::LegacyRenderSVGViewportContainer::svgSVGElement const):
(WebCore::LegacyRenderSVGViewportContainer::determineIfLayoutSizeChanged):
(WebCore::LegacyRenderSVGViewportContainer::applyViewportClip):
(WebCore::LegacyRenderSVGViewportContainer::calcViewport):
(WebCore::LegacyRenderSVGViewportContainer::calculateLocalTransform):
(WebCore::LegacyRenderSVGViewportContainer::viewportTransform const):
(WebCore::LegacyRenderSVGViewportContainer::pointIsInsideViewportClip):
(WebCore::LegacyRenderSVGViewportContainer::paint):
* Source/WebCore/rendering/svg/LegacyRenderSVGViewportContainer.h: Copied from Source/WebCore/rendering/svg/RenderSVGViewportContainer.h.
* Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp:
(WebCore::RenderSVGViewportContainer::RenderSVGViewportContainer):
(WebCore::RenderSVGViewportContainer::svgSVGElement const):
(WebCore::RenderSVGViewportContainer::computeViewport const):
(WebCore::RenderSVGViewportContainer::updateLayerTransform):
(WebCore::RenderSVGViewportContainer::applyTransform const):
(WebCore::RenderSVGViewportContainer::determineIfLayoutSizeChanged): Deleted.
(WebCore::RenderSVGViewportContainer::applyViewportClip): Deleted.
(WebCore::RenderSVGViewportContainer::calcViewport): Deleted.
(WebCore::RenderSVGViewportContainer::calculateLocalTransform): Deleted.
(WebCore::RenderSVGViewportContainer::viewportTransform const): Deleted.
(WebCore::RenderSVGViewportContainer::pointIsInsideViewportClip): Deleted.
(WebCore::RenderSVGViewportContainer::paint): Deleted.
* Source/WebCore/rendering/svg/RenderSVGViewportContainer.h:
* Source/WebCore/rendering/svg/SVGRenderSupport.cpp:
(WebCore::layoutSizeOfNearestViewportChanged):
(WebCore::SVGRenderSupport::transformToRootChanged):
* Source/WebCore/svg/SVGLengthContext.cpp:
* Source/WebCore/svg/SVGSVGElement.cpp:
(WebCore::SVGSVGElement::createElementRenderer):
(WebCore::SVGSVGElement::currentViewportSize const):

Canonical link: https://commits.webkit.org/252500@main
  • Loading branch information
nikolaszimmermann committed Jul 15, 2022
1 parent d6d6a06 commit 273d610500568994a594191403c869ffe26098e2
Show file tree
Hide file tree
Showing 11 changed files with 241 additions and 104 deletions.
@@ -2516,15 +2516,16 @@ rendering/style/StyleVisualData.cpp
rendering/style/TextSizeAdjustment.cpp
rendering/style/WillChangeData.cpp
rendering/svg/LegacyRenderSVGContainer.cpp
rendering/svg/LegacyRenderSVGEllipse.cpp
rendering/svg/LegacyRenderSVGModelObject.cpp
rendering/svg/LegacyRenderSVGPath.cpp
rendering/svg/LegacyRenderSVGRect.cpp
rendering/svg/LegacyRenderSVGRoot.cpp
rendering/svg/LegacyRenderSVGShape.cpp
rendering/svg/LegacyRenderSVGTransformableContainer.cpp
rendering/svg/LegacyRenderSVGViewportContainer.cpp
rendering/svg/RenderSVGBlock.cpp
rendering/svg/RenderSVGContainer.cpp
rendering/svg/LegacyRenderSVGEllipse.cpp
rendering/svg/RenderSVGEllipse.cpp
rendering/svg/RenderSVGForeignObject.cpp
rendering/svg/RenderSVGGradientStop.cpp
@@ -1283,6 +1283,7 @@
436708E512D9CA4B00044234 /* LegacyRenderSVGRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708A612D9CA4B00044234 /* LegacyRenderSVGRoot.h */; };
436708E512D9DB4B00044234 /* RenderSVGRoot.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708A612D9DB4B00044234 /* RenderSVGRoot.h */; };
436708E912D9CA4B00044234 /* LegacyRenderSVGTransformableContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708AA12D9CA4B00044234 /* LegacyRenderSVGTransformableContainer.h */; };
436708EB12D9CA3C000A2245 /* LegacyRenderSVGViewportContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708AC12D9CA3C000A2245 /* LegacyRenderSVGViewportContainer.h */; };
436708EB12D9CA4B00044234 /* RenderSVGViewportContainer.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708AC12D9CA4B00044234 /* RenderSVGViewportContainer.h */; };
436708EE12D9CA4B00044234 /* SVGMarkerData.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708AF12D9CA4B00044234 /* SVGMarkerData.h */; };
436708F212D9CA4B00044234 /* SVGRenderSupport.h in Headers */ = {isa = PBXBuildFile; fileRef = 436708B312D9CA4B00044234 /* SVGRenderSupport.h */; settings = {ATTRIBUTES = (Private, ); }; };
@@ -9201,6 +9202,8 @@
436708A612D9DB4B00044234 /* RenderSVGRoot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGRoot.h; sourceTree = "<group>"; };
436708A912D9CA4B00044234 /* LegacyRenderSVGTransformableContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LegacyRenderSVGTransformableContainer.cpp; sourceTree = "<group>"; };
436708AA12D9CA4B00044234 /* LegacyRenderSVGTransformableContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyRenderSVGTransformableContainer.h; sourceTree = "<group>"; };
436708AB12D9CA3C000A2245 /* LegacyRenderSVGViewportContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = LegacyRenderSVGViewportContainer.cpp; sourceTree = "<group>"; };
436708AC12D9CA3C000A2245 /* LegacyRenderSVGViewportContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LegacyRenderSVGViewportContainer.h; sourceTree = "<group>"; };
436708AB12D9CA4B00044234 /* RenderSVGViewportContainer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = RenderSVGViewportContainer.cpp; sourceTree = "<group>"; };
436708AC12D9CA4B00044234 /* RenderSVGViewportContainer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RenderSVGViewportContainer.h; sourceTree = "<group>"; };
436708AF12D9CA4B00044234 /* SVGMarkerData.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SVGMarkerData.h; sourceTree = "<group>"; };
@@ -19303,6 +19306,8 @@
CDF747F6270F86A4008FEEEC /* LegacyRenderSVGShapeInlines.h */,
436708A912D9CA4B00044234 /* LegacyRenderSVGTransformableContainer.cpp */,
436708AA12D9CA4B00044234 /* LegacyRenderSVGTransformableContainer.h */,
436708AB12D9CA3C000A2245 /* LegacyRenderSVGViewportContainer.cpp */,
436708AC12D9CA3C000A2245 /* LegacyRenderSVGViewportContainer.h */,
4367088112D9CA4A00044234 /* RenderSVGBlock.cpp */,
4367088212D9CA4A00044234 /* RenderSVGBlock.h */,
CDF747EA270F6D88008FEEEC /* RenderSVGBlockInlines.h */,
@@ -36649,6 +36654,7 @@
A10BB58B1484E3B300B2E87A /* LegacyRenderSVGShape.h in Headers */,
CDF747F7270F86A4008FEEEC /* LegacyRenderSVGShapeInlines.h in Headers */,
436708E912D9CA4B00044234 /* LegacyRenderSVGTransformableContainer.h in Headers */,
436708EB12D9CA3C000A2245 /* LegacyRenderSVGViewportContainer.h in Headers */,
A8CFF5E10A155A05000A4234 /* LegacyRootInlineBox.h in Headers */,
5162C7F511F77EFB00612EFE /* LegacySchemeRegistry.h in Headers */,
E4C3B1FA0F0E4161009693F6 /* LegacyTileCache.h in Headers */,
@@ -332,6 +332,7 @@ class RenderObject : public CachedImageClient {
virtual bool isSVGTransformableContainer() const { return false; }
virtual bool isLegacySVGTransformableContainer() const { return false; }
virtual bool isSVGViewportContainer() const { return false; }
virtual bool isLegacySVGViewportContainer() const { return false; }
virtual bool isSVGGradientStop() const { return false; }
virtual bool isSVGHiddenContainer() const { return false; }
virtual bool isLegacySVGPath() const { return false; }
@@ -59,13 +59,13 @@ void LegacyRenderSVGContainer::layout()

LayoutRepainter repainter(*this, SVGRenderSupport::checkForSVGRepaintDuringLayout(*this) || selfWillPaint(), RepaintOutlineBounds::No);

// Allow RenderSVGViewportContainer to update its viewport.
// Allow LegacyRenderSVGViewportContainer to update its viewport.
calcViewport();

// Allow LegacyRenderSVGTransformableContainer to update its transform.
bool updatedTransform = calculateLocalTransform();

// RenderSVGViewportContainer needs to set the 'layout size changed' flag.
// LegacyRenderSVGViewportContainer needs to set the 'layout size changed' flag.
determineIfLayoutSizeChanged();

SVGRenderSupport::layoutChildren(*this, selfNeedsLayout() || SVGRenderSupport::filtersForceContainerLayout(*this));
@@ -111,7 +111,7 @@ void LegacyRenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
GraphicsContextStateSaver stateSaver(childPaintInfo.context());

// Let the RenderSVGViewportContainer subclass clip if necessary
// Let the LegacyRenderSVGViewportContainer subclass clip if necessary
applyViewportClip(childPaintInfo);

childPaintInfo.applyTransform(localToParentTransform());
@@ -157,7 +157,7 @@ void LegacyRenderSVGContainer::updateCachedBoundaries()

bool LegacyRenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
{
// Give RenderSVGViewportContainer a chance to apply its viewport clip
// Give LegacyRenderSVGViewportContainer a chance to apply its viewport clip
if (!pointIsInsideViewportClip(pointInParent))
return false;

@@ -0,0 +1,109 @@
/*
* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2007 Rob Buis <buis@kde.org>
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
* Copyright (C) 2009 Google, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#include "config.h"
#include "LegacyRenderSVGViewportContainer.h"

#include "GraphicsContext.h"
#include "RenderView.h"
#include "SVGElementTypeHelpers.h"
#include "SVGSVGElement.h"
#include <wtf/IsoMallocInlines.h>

namespace WebCore {

WTF_MAKE_ISO_ALLOCATED_IMPL(LegacyRenderSVGViewportContainer);

LegacyRenderSVGViewportContainer::LegacyRenderSVGViewportContainer(SVGSVGElement& element, RenderStyle&& style)
: LegacyRenderSVGContainer(element, WTFMove(style))
, m_didTransformToRootUpdate(false)
, m_isLayoutSizeChanged(false)
, m_needsTransformUpdate(true)
{
}

SVGSVGElement& LegacyRenderSVGViewportContainer::svgSVGElement() const
{
return downcast<SVGSVGElement>(LegacyRenderSVGContainer::element());
}

void LegacyRenderSVGViewportContainer::determineIfLayoutSizeChanged()
{
m_isLayoutSizeChanged = svgSVGElement().hasRelativeLengths() && selfNeedsLayout();
}

void LegacyRenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
{
if (SVGRenderSupport::isOverflowHidden(*this))
paintInfo.context().clip(m_viewport);
}

void LegacyRenderSVGViewportContainer::calcViewport()
{
SVGSVGElement& element = svgSVGElement();
SVGLengthContext lengthContext(&element);
FloatRect newViewport(element.x().value(lengthContext), element.y().value(lengthContext), element.width().value(lengthContext), element.height().value(lengthContext));

if (m_viewport == newViewport)
return;

m_viewport = newViewport;

setNeedsBoundariesUpdate();
setNeedsTransformUpdate();
}

bool LegacyRenderSVGViewportContainer::calculateLocalTransform()
{
m_didTransformToRootUpdate = m_needsTransformUpdate || SVGRenderSupport::transformToRootChanged(parent());
if (!m_needsTransformUpdate)
return false;

m_localToParentTransform = AffineTransform::makeTranslation(toFloatSize(m_viewport.location())) * viewportTransform();
m_needsTransformUpdate = false;
return true;
}

AffineTransform LegacyRenderSVGViewportContainer::viewportTransform() const
{
return svgSVGElement().viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
}

bool LegacyRenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent)
{
// Respect the viewport clip (which is in parent coords)
if (!SVGRenderSupport::isOverflowHidden(*this))
return true;

return m_viewport.contains(pointInParent);
}

void LegacyRenderSVGViewportContainer::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// An empty viewBox disables rendering.
if (svgSVGElement().hasEmptyViewBox())
return;

LegacyRenderSVGContainer::paint(paintInfo, paintOffset);
}

}
@@ -0,0 +1,73 @@
/*
* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005, 2007 Rob Buis <buis@kde.org>
* Copyright (C) 2009 Google, Inc.
* Copyright (C) 2009 Apple Inc. All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Library General Public License for more details.
*
* You should have received a copy of the GNU Library General Public License
* along with this library; see the file COPYING.LIB. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
* Boston, MA 02110-1301, USA.
*/

#pragma once

#include "LegacyRenderSVGContainer.h"

namespace WebCore {

// This is used for non-root <svg> elements and <marker> elements, neither of which are SVGTransformable
// thus we inherit from LegacyRenderSVGContainer instead of LegacyRenderSVGTransformableContainer
class LegacyRenderSVGViewportContainer final : public LegacyRenderSVGContainer {
WTF_MAKE_ISO_ALLOCATED(LegacyRenderSVGViewportContainer);
public:
LegacyRenderSVGViewportContainer(SVGSVGElement&, RenderStyle&&);

SVGSVGElement& svgSVGElement() const;

FloatRect viewport() const { return m_viewport; }

bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
bool didTransformToRootUpdate() override { return m_didTransformToRootUpdate; }

void determineIfLayoutSizeChanged() override;
void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }

void paint(PaintInfo&, const LayoutPoint&) override;

private:
void element() const = delete;

bool isLegacySVGViewportContainer() const override { return true; }
ASCIILiteral renderName() const override { return "RenderSVGViewportContainer"_s; }

AffineTransform viewportTransform() const;
const AffineTransform& localToParentTransform() const override { return m_localToParentTransform; }

void calcViewport() override;
bool calculateLocalTransform() override;

void applyViewportClip(PaintInfo&) override;
bool pointIsInsideViewportClip(const FloatPoint& pointInParent) override;

bool m_didTransformToRootUpdate : 1;
bool m_isLayoutSizeChanged : 1;
bool m_needsTransformUpdate : 1;

FloatRect m_viewport;
mutable AffineTransform m_localToParentTransform;
};

} // namespace WebCore

SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(LegacyRenderSVGViewportContainer, isLegacySVGViewportContainer())
@@ -3,6 +3,7 @@
* Copyright (C) 2004, 2005, 2007 Rob Buis <buis@kde.org>
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
* Copyright (C) 2009 Google, Inc.
* Copyright (c) 2020, 2021, 2022 Igalia S.L.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -23,8 +24,11 @@
#include "config.h"
#include "RenderSVGViewportContainer.h"

#include "GraphicsContext.h"
#include "RenderView.h"
#if ENABLE(LAYER_BASED_SVG_ENGINE)
#include "RenderLayer.h"
#include "RenderSVGModelObjectInlines.h"
#include "RenderSVGRoot.h"
#include "SVGContainerLayout.h"
#include "SVGElementTypeHelpers.h"
#include "SVGSVGElement.h"
#include <wtf/IsoMallocInlines.h>
@@ -34,76 +38,33 @@ namespace WebCore {
WTF_MAKE_ISO_ALLOCATED_IMPL(RenderSVGViewportContainer);

RenderSVGViewportContainer::RenderSVGViewportContainer(SVGSVGElement& element, RenderStyle&& style)
: LegacyRenderSVGContainer(element, WTFMove(style))
, m_didTransformToRootUpdate(false)
, m_isLayoutSizeChanged(false)
, m_needsTransformUpdate(true)
: RenderSVGContainer(element, WTFMove(style))
{
}

SVGSVGElement& RenderSVGViewportContainer::svgSVGElement() const
{
return downcast<SVGSVGElement>(LegacyRenderSVGContainer::element());
return downcast<SVGSVGElement>(RenderSVGContainer::element());
}

void RenderSVGViewportContainer::determineIfLayoutSizeChanged()
FloatRect RenderSVGViewportContainer::computeViewport() const
{
m_isLayoutSizeChanged = svgSVGElement().hasRelativeLengths() && selfNeedsLayout();
}

void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
{
if (SVGRenderSupport::isOverflowHidden(*this))
paintInfo.context().clip(m_viewport);
}

void RenderSVGViewportContainer::calcViewport()
{
SVGSVGElement& element = svgSVGElement();
SVGLengthContext lengthContext(&element);
FloatRect newViewport(element.x().value(lengthContext), element.y().value(lengthContext), element.width().value(lengthContext), element.height().value(lengthContext));

if (m_viewport == newViewport)
return;
auto& useSVGSVGElement = svgSVGElement();

m_viewport = newViewport;

setNeedsBoundariesUpdate();
setNeedsTransformUpdate();
SVGLengthContext lengthContext(&useSVGSVGElement);
return { useSVGSVGElement.x().value(lengthContext), useSVGSVGElement.y().value(lengthContext),
useSVGSVGElement.width().value(lengthContext), useSVGSVGElement.height().value(lengthContext) };
}

bool RenderSVGViewportContainer::calculateLocalTransform()
void RenderSVGViewportContainer::updateLayerTransform()
{
m_didTransformToRootUpdate = m_needsTransformUpdate || SVGRenderSupport::transformToRootChanged(parent());
if (!m_needsTransformUpdate)
return false;

m_localToParentTransform = AffineTransform::makeTranslation(toFloatSize(m_viewport.location())) * viewportTransform();
m_needsTransformUpdate = false;
return true;
RenderSVGContainer::updateLayerTransform();
}

AffineTransform RenderSVGViewportContainer::viewportTransform() const
void RenderSVGViewportContainer::applyTransform(TransformationMatrix&, const RenderStyle&, const FloatRect&, OptionSet<RenderStyle::TransformOperationOption>) const
{
return svgSVGElement().viewBoxToViewTransform(m_viewport.width(), m_viewport.height());
}

bool RenderSVGViewportContainer::pointIsInsideViewportClip(const FloatPoint& pointInParent)
{
// Respect the viewport clip (which is in parent coords)
if (!SVGRenderSupport::isOverflowHidden(*this))
return true;

return m_viewport.contains(pointInParent);
}

void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// An empty viewBox disables rendering.
if (svgSVGElement().hasEmptyViewBox())
return;

LegacyRenderSVGContainer::paint(paintInfo, paintOffset);
}

}
#endif // ENABLE(LAYER_BASED_SVG_ENGINE)

0 comments on commit 273d610

Please sign in to comment.