summaryrefslogtreecommitdiff
path: root/Source/WebCore/rendering/svg
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
committerLorry Tar Creator <lorry-tar-importer@lorry>2015-05-20 09:56:07 +0000
commit41386e9cb918eed93b3f13648cbef387e371e451 (patch)
treea97f9d7bd1d9d091833286085f72da9d83fd0606 /Source/WebCore/rendering/svg
parente15dd966d523731101f70ccf768bba12435a0208 (diff)
downloadWebKitGtk-tarball-41386e9cb918eed93b3f13648cbef387e371e451.tar.gz
webkitgtk-2.4.9webkitgtk-2.4.9
Diffstat (limited to 'Source/WebCore/rendering/svg')
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp79
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGBlock.cpp10
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGBlock.h12
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGContainer.cpp19
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGContainer.h12
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGEllipse.cpp56
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGEllipse.h21
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp66
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGForeignObject.h31
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp25
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGGradientStop.h36
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp8
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h4
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGImage.cpp72
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGImage.h32
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInline.cpp51
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInline.h18
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.cpp69
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGInlineText.h20
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGModelObject.cpp22
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGModelObject.h13
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGPath.cpp23
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGPath.h16
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRect.cpp41
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRect.h19
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResource.cpp48
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResource.h19
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp78
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceClipper.h29
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp54
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceContainer.h36
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp63
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilter.h26
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp61
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h14
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp41
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceGradient.h10
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp10
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.h17
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp12
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMarker.h23
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp24
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceMasker.h15
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp63
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourcePattern.h23
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp11
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h17
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp6
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h14
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.cpp170
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGRoot.h20
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGShape.cpp90
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGShape.h23
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTSpan.h10
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGText.cpp118
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGText.h56
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTextPath.cpp16
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTextPath.h8
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp20
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h22
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp79
-rw-r--r--Source/WebCore/rendering/svg/RenderSVGViewportContainer.h28
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp45
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineFlowBox.h7
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.cpp116
-rw-r--r--Source/WebCore/rendering/svg/SVGInlineTextBox.h28
-rw-r--r--Source/WebCore/rendering/svg/SVGMarkerData.h25
-rw-r--r--Source/WebCore/rendering/svg/SVGPathData.cpp61
-rw-r--r--Source/WebCore/rendering/svg/SVGPathData.h2
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderSupport.cpp190
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderSupport.h12
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp167
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderTreeAsText.h14
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderingContext.cpp164
-rw-r--r--Source/WebCore/rendering/svg/SVGRenderingContext.h19
-rw-r--r--Source/WebCore/rendering/svg/SVGResources.cpp88
-rw-r--r--Source/WebCore/rendering/svg/SVGResources.h40
-rw-r--r--Source/WebCore/rendering/svg/SVGResourcesCache.cpp69
-rw-r--r--Source/WebCore/rendering/svg/SVGResourcesCache.h9
-rw-r--r--Source/WebCore/rendering/svg/SVGResourcesCycleSolver.cpp132
-rw-r--r--Source/WebCore/rendering/svg/SVGResourcesCycleSolver.h2
-rw-r--r--Source/WebCore/rendering/svg/SVGRootInlineBox.cpp107
-rw-r--r--Source/WebCore/rendering/svg/SVGRootInlineBox.h15
-rw-r--r--Source/WebCore/rendering/svg/SVGSubpathData.h59
-rw-r--r--Source/WebCore/rendering/svg/SVGTextChunk.cpp201
-rw-r--r--Source/WebCore/rendering/svg/SVGTextChunk.h27
-rw-r--r--Source/WebCore/rendering/svg/SVGTextChunkBuilder.cpp241
-rw-r--r--Source/WebCore/rendering/svg/SVGTextChunkBuilder.h20
-rw-r--r--Source/WebCore/rendering/svg/SVGTextFragment.h2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp4
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutAttributes.h2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp64
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.h11
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp121
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngine.h13
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp40
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.h14
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp20
-rw-r--r--Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.h8
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetrics.cpp44
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetrics.h16
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp74
-rw-r--r--Source/WebCore/rendering/svg/SVGTextMetricsBuilder.h12
-rw-r--r--Source/WebCore/rendering/svg/SVGTextQuery.cpp44
-rw-r--r--Source/WebCore/rendering/svg/SVGTextQuery.h2
-rw-r--r--Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp339
-rw-r--r--Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h16
107 files changed, 2525 insertions, 2330 deletions
diff --git a/Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp b/Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp
deleted file mode 100644
index 327dd87ec..000000000
--- a/Source/WebCore/rendering/svg/RenderSVGAllInOne.cpp
+++ /dev/null
@@ -1,79 +0,0 @@
-/*
- * Copyright (C) 2009, 2010 Apple Inc. All Rights Reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-// This all-in-one cpp file cuts down on template bloat to allow us to build our Windows release build.
-
-#include "RenderSVGBlock.cpp"
-#include "RenderSVGContainer.cpp"
-#include "RenderSVGEllipse.cpp"
-#include "RenderSVGForeignObject.cpp"
-#include "RenderSVGGradientStop.cpp"
-#include "RenderSVGHiddenContainer.cpp"
-#include "RenderSVGImage.cpp"
-#include "RenderSVGInline.cpp"
-#include "RenderSVGInlineText.cpp"
-#include "RenderSVGModelObject.cpp"
-#include "RenderSVGPath.cpp"
-#include "RenderSVGRect.cpp"
-#include "RenderSVGResource.cpp"
-#include "RenderSVGResourceClipper.cpp"
-#include "RenderSVGResourceContainer.cpp"
-#include "RenderSVGResourceFilter.cpp"
-#include "RenderSVGResourceFilterPrimitive.cpp"
-#include "RenderSVGResourceGradient.cpp"
-#include "RenderSVGResourceLinearGradient.cpp"
-#include "RenderSVGResourceMarker.cpp"
-#include "RenderSVGResourceMasker.cpp"
-#include "RenderSVGResourcePattern.cpp"
-#include "RenderSVGResourceRadialGradient.cpp"
-#include "RenderSVGResourceSolidColor.cpp"
-#include "RenderSVGRoot.cpp"
-#include "RenderSVGShape.cpp"
-#include "RenderSVGText.cpp"
-#include "RenderSVGTextPath.cpp"
-#include "RenderSVGTransformableContainer.cpp"
-#include "RenderSVGViewportContainer.cpp"
-#include "SVGInlineFlowBox.cpp"
-#include "SVGInlineTextBox.cpp"
-#include "SVGPathData.cpp"
-#include "SVGRenderSupport.cpp"
-#include "SVGRenderTreeAsText.cpp"
-#include "SVGRenderingContext.cpp"
-#include "SVGResources.cpp"
-#include "SVGResourcesCache.cpp"
-#include "SVGResourcesCycleSolver.cpp"
-#include "SVGRootInlineBox.cpp"
-#include "SVGTextChunk.cpp"
-#include "SVGTextChunkBuilder.cpp"
-#include "SVGTextLayoutAttributes.cpp"
-#include "SVGTextLayoutAttributesBuilder.cpp"
-#include "SVGTextLayoutEngine.cpp"
-#include "SVGTextLayoutEngineBaseline.cpp"
-#include "SVGTextLayoutEngineSpacing.cpp"
-#include "SVGTextRunRenderingContext.cpp"
-#include "SVGTextMetrics.cpp"
-#include "SVGTextMetricsBuilder.cpp"
-#include "SVGTextQuery.cpp"
-
diff --git a/Source/WebCore/rendering/svg/RenderSVGBlock.cpp b/Source/WebCore/rendering/svg/RenderSVGBlock.cpp
index 32f8e3646..953728b01 100644
--- a/Source/WebCore/rendering/svg/RenderSVGBlock.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGBlock.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
@@ -20,6 +20,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGBlock.h"
#include "RenderSVGResource.h"
@@ -28,8 +30,8 @@
namespace WebCore {
-RenderSVGBlock::RenderSVGBlock(SVGGraphicsElement& element, Ref<RenderStyle>&& style)
- : RenderBlockFlow(element, WTF::move(style))
+RenderSVGBlock::RenderSVGBlock(SVGGraphicsElement& element, PassRef<RenderStyle> style)
+ : RenderBlockFlow(element, std::move(style))
{
}
@@ -83,3 +85,5 @@ void RenderSVGBlock::styleDidChange(StyleDifference diff, const RenderStyle* old
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGBlock.h b/Source/WebCore/rendering/svg/RenderSVGBlock.h
index ac8b6ad5e..23efff55d 100644
--- a/Source/WebCore/rendering/svg/RenderSVGBlock.h
+++ b/Source/WebCore/rendering/svg/RenderSVGBlock.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -20,6 +20,7 @@
#ifndef RenderSVGBlock_h
#define RenderSVGBlock_h
+#if ENABLE(SVG)
#include "RenderBlockFlow.h"
#include "SVGGraphicsElement.h"
#include "SVGRenderSupport.h"
@@ -32,10 +33,10 @@ class RenderSVGBlock : public RenderBlockFlow {
public:
virtual LayoutRect visualOverflowRect() const override final;
- SVGGraphicsElement& graphicsElement() const { return downcast<SVGGraphicsElement>(nodeForNonAnonymous()); }
+ SVGGraphicsElement& graphicsElement() const { return toSVGGraphicsElement(nodeForNonAnonymous()); }
protected:
- RenderSVGBlock(SVGGraphicsElement&, Ref<RenderStyle>&&);
+ RenderSVGBlock(SVGGraphicsElement&, PassRef<RenderStyle>);
virtual void willBeDestroyed() override;
private:
@@ -43,12 +44,13 @@ private:
virtual void updateFromStyle() override final;
- virtual bool isRenderSVGBlock() const override final { return true; }
+ virtual bool isRenderSVGBlock() const override final { return true; };
- virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const override;
+ virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override final;
};
}
#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
index 8207df419..71c7bcc00 100644
--- a/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.cpp
@@ -22,10 +22,11 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGContainer.h"
#include "GraphicsContext.h"
-#include "HitTestRequest.h"
#include "LayoutRepainter.h"
#include "RenderIterator.h"
#include "RenderSVGResourceFilter.h"
@@ -37,8 +38,8 @@
namespace WebCore {
-RenderSVGContainer::RenderSVGContainer(SVGElement& element, Ref<RenderStyle>&& style)
- : RenderSVGModelObject(element, WTF::move(style))
+RenderSVGContainer::RenderSVGContainer(SVGElement& element, PassRef<RenderStyle> style)
+ : RenderSVGModelObject(element, std::move(style))
, m_objectBoundingBoxValid(false)
, m_needsBoundariesUpdate(true)
{
@@ -102,7 +103,7 @@ void RenderSVGContainer::removeChild(RenderObject& child)
bool RenderSVGContainer::selfWillPaint()
{
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*this);
return resources && resources->filter();
}
@@ -143,11 +144,11 @@ void RenderSVGContainer::paint(PaintInfo& paintInfo, const LayoutPoint&)
}
// FIXME: This really should be drawn from local coordinates, but currently we hack it
- // to avoid our clip killing our outline rect. Thus we translate our
+ // to avoid our clip killing our outline rect. Thus we translate our
// outline rect into parent coords before drawing.
// FIXME: This means our focus ring won't share our rotation like it should.
// We should instead disable our clip during PaintPhaseOutline
- if (paintInfo.phase == PaintPhaseSelfOutline && style().outlineWidth() && style().visibility() == VISIBLE) {
+ if ((paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline) && style().outlineWidth() && style().visibility() == VISIBLE) {
IntRect paintRectInParent = enclosingIntRect(localToParentTransform().mapRect(repaintRect));
paintOutline(paintInfo, paintRectInParent);
}
@@ -180,14 +181,14 @@ bool RenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTest
for (RenderObject* child = lastChild(); child; child = child->previousSibling()) {
if (child->nodeAtFloatPoint(request, result, localPoint, hitTestAction)) {
- updateHitTestResult(result, LayoutPoint(localPoint));
+ updateHitTestResult(result, roundedLayoutPoint(localPoint));
return true;
}
}
// Accessibility wants to return SVG containers, if appropriate.
if (request.type() & HitTestRequest::AccessibilityHitTest && m_objectBoundingBox.contains(localPoint)) {
- updateHitTestResult(result, LayoutPoint(localPoint));
+ updateHitTestResult(result, roundedLayoutPoint(localPoint));
return true;
}
@@ -197,3 +198,5 @@ bool RenderSVGContainer::nodeAtFloatPoint(const HitTestRequest& request, HitTest
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGContainer.h b/Source/WebCore/rendering/svg/RenderSVGContainer.h
index 113c3438e..78d318e99 100644
--- a/Source/WebCore/rendering/svg/RenderSVGContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGContainer.h
@@ -23,6 +23,8 @@
#ifndef RenderSVGContainer_h
#define RenderSVGContainer_h
+#if ENABLE(SVG)
+
#include "RenderSVGModelObject.h"
namespace WebCore {
@@ -40,8 +42,9 @@ public:
bool isObjectBoundingBoxValid() const { return m_objectBoundingBoxValid; }
protected:
- RenderSVGContainer(SVGElement&, Ref<RenderStyle>&&);
+ RenderSVGContainer(SVGElement&, PassRef<RenderStyle>);
+ virtual bool isSVGContainer() const override final { return true; }
virtual const char* renderName() const override { return "RenderSVGContainer"; }
virtual bool canHaveChildren() const override final { return true; }
@@ -72,8 +75,6 @@ protected:
void updateCachedBoundaries();
private:
- virtual bool isSVGContainer() const override final { return true; }
-
FloatRect m_objectBoundingBox;
bool m_objectBoundingBoxValid;
FloatRect m_strokeBoundingBox;
@@ -81,8 +82,9 @@ private:
bool m_needsBoundariesUpdate : 1;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGContainer, isSVGContainer())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGContainer, isSVGContainer())
+} // namespace WebCore
+#endif // ENABLE(SVG)
#endif // RenderSVGContainer_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp b/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp
index cb6d9c37c..dac2e84ff 100644
--- a/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGEllipse.cpp
@@ -25,6 +25,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGEllipse.h"
#include "SVGCircleElement.h"
@@ -33,8 +35,8 @@
namespace WebCore {
-RenderSVGEllipse::RenderSVGEllipse(SVGGraphicsElement& element, Ref<RenderStyle>&& style)
- : RenderSVGShape(element, WTF::move(style))
+RenderSVGEllipse::RenderSVGEllipse(SVGGraphicsElement& element, PassRef<RenderStyle> style)
+ : RenderSVGShape(element, std::move(style))
, m_usePathFallback(false)
{
}
@@ -52,22 +54,19 @@ void RenderSVGEllipse::updateShapeFromElement()
m_center = FloatPoint();
m_radii = FloatSize();
- calculateRadiiAndCenter();
-
- // Element is invalid if either dimension is negative.
- if (m_radii.width() < 0 || m_radii.height() < 0)
+ // Fallback to RenderSVGShape if shape has a non-scaling stroke.
+ if (hasNonScalingStroke()) {
+ RenderSVGShape::updateShapeFromElement();
+ m_usePathFallback = true;
return;
+ } else
+ m_usePathFallback = false;
+
+ calculateRadiiAndCenter();
// Spec: "A value of zero disables rendering of the element."
- if (!m_radii.isEmpty()) {
- if (hasNonScalingStroke()) {
- // Fallback to RenderSVGShape if shape has a non-scaling stroke.
- RenderSVGShape::updateShapeFromElement();
- m_usePathFallback = true;
- return;
- }
- m_usePathFallback = false;
- }
+ if (m_radii.width() <= 0 || m_radii.height() <= 0)
+ return;
m_fillBoundingBox = FloatRect(m_center.x() - m_radii.width(), m_center.y() - m_radii.height(), 2 * m_radii.width(), 2 * m_radii.height());
m_strokeBoundingBox = m_fillBoundingBox;
@@ -77,20 +76,21 @@ void RenderSVGEllipse::updateShapeFromElement()
void RenderSVGEllipse::calculateRadiiAndCenter()
{
- SVGLengthContext lengthContext(&graphicsElement());
- m_center = FloatPoint(
- lengthContext.valueForLength(style().svgStyle().cx(), LengthModeWidth),
- lengthContext.valueForLength(style().svgStyle().cy(), LengthModeHeight));
- if (is<SVGCircleElement>(graphicsElement())) {
- float radius = lengthContext.valueForLength(style().svgStyle().r());
+ if (isSVGCircleElement(graphicsElement())) {
+ SVGCircleElement& circle = toSVGCircleElement(graphicsElement());
+ SVGLengthContext lengthContext(&circle);
+ float radius = circle.r().value(lengthContext);
m_radii = FloatSize(radius, radius);
+ m_center = FloatPoint(circle.cx().value(lengthContext), circle.cy().value(lengthContext));
return;
}
- ASSERT(is<SVGEllipseElement>(graphicsElement()));
- m_radii = FloatSize(
- lengthContext.valueForLength(style().svgStyle().rx(), LengthModeWidth),
- lengthContext.valueForLength(style().svgStyle().ry(), LengthModeHeight));
+ ASSERT(isSVGEllipseElement(graphicsElement()));
+ SVGEllipseElement& ellipse = toSVGEllipseElement(graphicsElement());
+
+ SVGLengthContext lengthContext(&ellipse);
+ m_radii = FloatSize(ellipse.rx().value(lengthContext), ellipse.ry().value(lengthContext));
+ m_center = FloatPoint(ellipse.cx().value(lengthContext), ellipse.cy().value(lengthContext));
}
void RenderSVGEllipse::fillShape(GraphicsContext* context) const
@@ -152,10 +152,6 @@ bool RenderSVGEllipse::shapeDependentFillContains(const FloatPoint& point, const
return xrX * xrX + yrY * yrY <= 1.0;
}
-bool RenderSVGEllipse::isRenderingDisabled() const
-{
- // A radius of zero disables rendering of the element, and results in an empty bounding box.
- return m_fillBoundingBox.isEmpty();
}
-}
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGEllipse.h b/Source/WebCore/rendering/svg/RenderSVGEllipse.h
index b587d1ab3..4331c1841 100644
--- a/Source/WebCore/rendering/svg/RenderSVGEllipse.h
+++ b/Source/WebCore/rendering/svg/RenderSVGEllipse.h
@@ -27,25 +27,25 @@
#ifndef RenderSVGEllipse_h
#define RenderSVGEllipse_h
+#if ENABLE(SVG)
#include "RenderSVGShape.h"
namespace WebCore {
class RenderSVGEllipse final : public RenderSVGShape {
public:
- RenderSVGEllipse(SVGGraphicsElement&, Ref<RenderStyle>&&);
+ RenderSVGEllipse(SVGGraphicsElement&, PassRef<RenderStyle>);
virtual ~RenderSVGEllipse();
private:
- virtual const char* renderName() const override { return "RenderSVGEllipse"; }
-
- virtual void updateShapeFromElement() override;
- virtual bool isEmpty() const override { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); }
- virtual bool isRenderingDisabled() const override;
- virtual void fillShape(GraphicsContext*) const override;
- virtual void strokeShape(GraphicsContext*) const override;
- virtual bool shapeDependentStrokeContains(const FloatPoint&) override;
- virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const override;
+ virtual const char* renderName() const { return "RenderSVGEllipse"; }
+
+ virtual void updateShapeFromElement();
+ virtual bool isEmpty() const { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); };
+ virtual void fillShape(GraphicsContext*) const;
+ virtual void strokeShape(GraphicsContext*) const;
+ virtual bool shapeDependentStrokeContains(const FloatPoint&);
+ virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
void calculateRadiiAndCenter();
private:
@@ -56,4 +56,5 @@ private:
}
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp b/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp
index 4698907df..4ab82952b 100644
--- a/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGForeignObject.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2009 Google, Inc.
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
@@ -20,6 +20,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGForeignObject.h"
#include "GraphicsContext.h"
@@ -31,13 +33,14 @@
#include "SVGForeignObjectElement.h"
#include "SVGRenderingContext.h"
#include "SVGResourcesCache.h"
+#include "SVGSVGElement.h"
#include "TransformState.h"
#include <wtf/StackStats.h>
namespace WebCore {
-RenderSVGForeignObject::RenderSVGForeignObject(SVGForeignObjectElement& element, Ref<RenderStyle>&& style)
- : RenderSVGBlock(element, WTF::move(style))
+RenderSVGForeignObject::RenderSVGForeignObject(SVGForeignObjectElement& element, PassRef<RenderStyle> style)
+ : RenderSVGBlock(element, std::move(style))
, m_needsTransformUpdate(true)
{
}
@@ -48,15 +51,13 @@ RenderSVGForeignObject::~RenderSVGForeignObject()
SVGForeignObjectElement& RenderSVGForeignObject::foreignObjectElement() const
{
- return downcast<SVGForeignObjectElement>(RenderSVGBlock::graphicsElement());
+ return toSVGForeignObjectElement(RenderSVGBlock::graphicsElement());
}
void RenderSVGForeignObject::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
- if (paintInfo.context->paintingDisabled())
- return;
-
- if (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection)
+ if (paintInfo.context->paintingDisabled()
+ || (paintInfo.phase != PaintPhaseForeground && paintInfo.phase != PaintPhaseSelection))
return;
PaintInfo childPaintInfo(paintInfo);
@@ -67,30 +68,30 @@ void RenderSVGForeignObject::paint(PaintInfo& paintInfo, const LayoutPoint&)
childPaintInfo.context->clip(m_viewport);
SVGRenderingContext renderingContext;
+ bool continueRendering = true;
if (paintInfo.phase == PaintPhaseForeground) {
renderingContext.prepareToRenderSVGContent(*this, childPaintInfo);
- if (!renderingContext.isRenderingPrepared())
- return;
+ continueRendering = renderingContext.isRenderingPrepared();
}
- LayoutPoint childPoint = IntPoint();
- if (paintInfo.phase == PaintPhaseSelection) {
- RenderBlock::paint(childPaintInfo, childPoint);
- return;
+ if (continueRendering) {
+ // Paint all phases of FO elements atomically, as though the FO element established its
+ // own stacking context.
+ bool preservePhase = paintInfo.phase == PaintPhaseSelection || paintInfo.phase == PaintPhaseTextClip;
+ LayoutPoint childPoint = IntPoint();
+ childPaintInfo.phase = preservePhase ? paintInfo.phase : PaintPhaseBlockBackground;
+ RenderBlock::paint(childPaintInfo, IntPoint());
+ if (!preservePhase) {
+ childPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
+ RenderBlock::paint(childPaintInfo, childPoint);
+ childPaintInfo.phase = PaintPhaseFloat;
+ RenderBlock::paint(childPaintInfo, childPoint);
+ childPaintInfo.phase = PaintPhaseForeground;
+ RenderBlock::paint(childPaintInfo, childPoint);
+ childPaintInfo.phase = PaintPhaseOutline;
+ RenderBlock::paint(childPaintInfo, childPoint);
+ }
}
-
- // Paint all phases of FO elements atomically, as though the FO element established its
- // own stacking context.
- childPaintInfo.phase = PaintPhaseBlockBackground;
- RenderBlock::paint(childPaintInfo, childPoint);
- childPaintInfo.phase = PaintPhaseChildBlockBackgrounds;
- RenderBlock::paint(childPaintInfo, childPoint);
- childPaintInfo.phase = PaintPhaseFloat;
- RenderBlock::paint(childPaintInfo, childPoint);
- childPaintInfo.phase = PaintPhaseForeground;
- RenderBlock::paint(childPaintInfo, childPoint);
- childPaintInfo.phase = PaintPhaseOutline;
- RenderBlock::paint(childPaintInfo, childPoint);
}
LayoutRect RenderSVGForeignObject::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
@@ -103,13 +104,6 @@ void RenderSVGForeignObject::computeFloatRectForRepaint(const RenderLayerModelOb
SVGRenderSupport::computeFloatRectForRepaint(*this, repaintContainer, repaintRect, fixed);
}
-void RenderSVGForeignObject::computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect& repaintRect, bool fixed) const
-{
- FloatRect floatRect(repaintRect);
- computeFloatRectForRepaint(repaintContainer, floatRect, fixed);
- repaintRect = enclosingLayoutRect(floatRect);
-}
-
const AffineTransform& RenderSVGForeignObject::localToParentTransform() const
{
m_localToParentTransform = localTransform();
@@ -192,7 +186,7 @@ bool RenderSVGForeignObject::nodeAtFloatPoint(const HitTestRequest& request, Hit
return false;
// FOs establish a stacking context, so we need to hit-test all layers.
- HitTestLocation hitTestLocation(localPoint);
+ HitTestLocation hitTestLocation(roundedLayoutPoint(localPoint));
return RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestForeground)
|| RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestFloat)
|| RenderBlock::nodeAtPoint(request, result, hitTestLocation, LayoutPoint(), HitTestChildBlockBackgrounds);
@@ -215,3 +209,5 @@ const RenderObject* RenderSVGForeignObject::pushMappingToContainer(const RenderL
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGForeignObject.h b/Source/WebCore/rendering/svg/RenderSVGForeignObject.h
index 619c49494..b75c373f9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGForeignObject.h
+++ b/Source/WebCore/rendering/svg/RenderSVGForeignObject.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2009 Google, Inc.
*
* This library is free software; you can redistribute it and/or
@@ -21,6 +21,7 @@
#ifndef RenderSVGForeignObject_h
#define RenderSVGForeignObject_h
+#if ENABLE(SVG)
#include "AffineTransform.h"
#include "FloatPoint.h"
#include "FloatRect.h"
@@ -32,41 +33,40 @@ class SVGForeignObjectElement;
class RenderSVGForeignObject final : public RenderSVGBlock {
public:
- RenderSVGForeignObject(SVGForeignObjectElement&, Ref<RenderStyle>&&);
+ RenderSVGForeignObject(SVGForeignObjectElement&, PassRef<RenderStyle>);
virtual ~RenderSVGForeignObject();
SVGForeignObjectElement& foreignObjectElement() const;
- virtual void paint(PaintInfo&, const LayoutPoint&) override;
+ virtual void paint(PaintInfo&, const LayoutPoint&);
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override;
virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const override;
- virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const override;
- virtual bool requiresLayer() const override { return false; }
- virtual void layout() override;
+ virtual bool requiresLayer() const { return false; }
+ virtual void layout();
- virtual FloatRect objectBoundingBox() const override { return FloatRect(FloatPoint(), m_viewport.size()); }
- virtual FloatRect strokeBoundingBox() const override { return FloatRect(FloatPoint(), m_viewport.size()); }
- virtual FloatRect repaintRectInLocalCoordinates() const override { return FloatRect(FloatPoint(), m_viewport.size()); }
+ virtual FloatRect objectBoundingBox() const { return FloatRect(FloatPoint(), m_viewport.size()); }
+ virtual FloatRect strokeBoundingBox() const { return FloatRect(FloatPoint(), m_viewport.size()); }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(FloatPoint(), m_viewport.size()); }
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) override;
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
+ virtual bool isSVGForeignObject() const { return true; }
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const override;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override;
- virtual void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
private:
- virtual bool isSVGForeignObject() const override { return true; }
void graphicsElement() const = delete;
virtual const char* renderName() const override { return "RenderSVGForeignObject"; }
virtual void updateLogicalWidth() override;
virtual void computeLogicalHeight(LayoutUnit logicalHeight, LayoutUnit logicalTop, LogicalExtentComputedValues&) const override;
- virtual const AffineTransform& localToParentTransform() const override;
- virtual AffineTransform localTransform() const override { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const;
+ virtual AffineTransform localTransform() const { return m_localTransform; }
bool m_needsTransformUpdate : 1;
FloatRect m_viewport;
@@ -77,3 +77,4 @@ private:
}
#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp b/Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp
index 02e6f10d9..6e90d6e01 100644
--- a/Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGGradientStop.cpp
@@ -18,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGGradientStop.h"
#include "RenderSVGResourceContainer.h"
@@ -31,8 +33,8 @@ namespace WebCore {
using namespace SVGNames;
-RenderSVGGradientStop::RenderSVGGradientStop(SVGStopElement& element, Ref<RenderStyle>&& style)
- : RenderElement(element, WTF::move(style), 0)
+RenderSVGGradientStop::RenderSVGGradientStop(SVGStopElement& element, PassRef<RenderStyle> style)
+ : RenderElement(element, std::move(style), 0)
{
}
@@ -48,15 +50,17 @@ void RenderSVGGradientStop::styleDidChange(StyleDifference diff, const RenderSty
// <stop> elements should only be allowed to make renderers under gradient elements
// but I can imagine a few cases we might not be catching, so let's not crash if our parent isn't a gradient.
- const auto* gradient = gradientElement();
+ SVGGradientElement* gradient = gradientElement();
if (!gradient)
return;
- RenderElement* renderer = gradient->renderer();
+ RenderObject* renderer = gradient->renderer();
if (!renderer)
return;
- downcast<RenderSVGResourceContainer>(*renderer).removeAllClientsFromCache();
+ ASSERT(renderer->isSVGResourceContainer());
+ RenderSVGResourceContainer* container = renderer->toRenderSVGResourceContainer();
+ container->removeAllClientsFromCache();
}
void RenderSVGGradientStop::layout()
@@ -65,11 +69,14 @@ void RenderSVGGradientStop::layout()
clearNeedsLayout();
}
-SVGGradientElement* RenderSVGGradientStop::gradientElement()
+SVGGradientElement* RenderSVGGradientStop::gradientElement() const
{
- if (is<SVGGradientElement>(element().parentElement()))
- return downcast<SVGGradientElement>(element().parentElement());
- return nullptr;
+ ContainerNode* parentNode = element()->parentNode();
+ if (parentNode->hasTagName(linearGradientTag) || parentNode->hasTagName(radialGradientTag))
+ return toSVGGradientElement(parentNode);
+ return 0;
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGGradientStop.h b/Source/WebCore/rendering/svg/RenderSVGGradientStop.h
index da953ddd4..9428bb85a 100644
--- a/Source/WebCore/rendering/svg/RenderSVGGradientStop.h
+++ b/Source/WebCore/rendering/svg/RenderSVGGradientStop.h
@@ -1,7 +1,6 @@
/*
* Copyright (C) 2007 Eric Seidel <eric@webkit.org>
* Copyright (C) 2009 Google, Inc.
- * Copyright (C) 2014 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
@@ -22,46 +21,47 @@
#ifndef RenderSVGGradientStop_h
#define RenderSVGGradientStop_h
+#if ENABLE(SVG)
#include "RenderElement.h"
-#include "SVGStopElement.h"
namespace WebCore {
class SVGGradientElement;
+class SVGStopElement;
// This class exists mostly so we can hear about gradient stop style changes
class RenderSVGGradientStop final : public RenderElement {
public:
- RenderSVGGradientStop(SVGStopElement&, Ref<RenderStyle>&&);
+ RenderSVGGradientStop(SVGStopElement&, PassRef<RenderStyle>);
virtual ~RenderSVGGradientStop();
- SVGStopElement& element() const { return downcast<SVGStopElement>(RenderObject::nodeForNonAnonymous()); }
+ virtual bool isSVGGradientStop() const { return true; }
+ virtual const char* renderName() const { return "RenderSVGGradientStop"; }
-private:
- virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
-
- virtual void layout() override;
+ virtual void layout();
- // These overrides are needed to prevent ASSERTs on <svg><stop /></svg>
+ // This overrides are needed to prevent ASSERTs on <svg><stop /></svg>
// RenderObject's default implementations ASSERT_NOT_REACHED()
// https://bugs.webkit.org/show_bug.cgi?id=20400
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject*) const override { return LayoutRect(); }
- virtual FloatRect objectBoundingBox() const override { return FloatRect(); }
- virtual FloatRect strokeBoundingBox() const override { return FloatRect(); }
- virtual FloatRect repaintRectInLocalCoordinates() const override { return FloatRect(); }
+ virtual FloatRect objectBoundingBox() const { return FloatRect(); }
+ virtual FloatRect strokeBoundingBox() const { return FloatRect(); }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return FloatRect(); }
virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint&, HitTestAction) override { return false; }
- virtual bool isSVGGradientStop() const override { return true; }
- virtual const char* renderName() const override { return "RenderSVGGradientStop"; }
+protected:
+ virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle);
+private:
virtual bool canHaveChildren() const override { return false; }
- virtual void paint(PaintInfo&, const LayoutPoint&) override { }
+ virtual void paint(PaintInfo&, const LayoutPoint&) override final { }
- SVGGradientElement* gradientElement();
+ SVGGradientElement* gradientElement() const;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGGradientStop, isSVGGradientStop())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGGradientStop, isSVGGradientStop())
+}
+#endif // ENABLE(SVG)
#endif // RenderSVGGradientStop_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp
index 7721da34c..e874860ca 100644
--- a/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.cpp
@@ -18,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGHiddenContainer.h"
#include "RenderSVGPath.h"
@@ -25,8 +27,8 @@
namespace WebCore {
-RenderSVGHiddenContainer::RenderSVGHiddenContainer(SVGElement& element, Ref<RenderStyle>&& style)
- : RenderSVGContainer(element, WTF::move(style))
+RenderSVGHiddenContainer::RenderSVGHiddenContainer(SVGElement& element, PassRef<RenderStyle> style)
+ : RenderSVGContainer(element, std::move(style))
{
}
@@ -54,3 +56,5 @@ bool RenderSVGHiddenContainer::nodeAtFloatPoint(const HitTestRequest&, HitTestRe
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h b/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h
index f70ac512f..44abca36d 100644
--- a/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGHiddenContainer.h
@@ -20,6 +20,7 @@
#ifndef RenderSVGHiddenContainer_h
#define RenderSVGHiddenContainer_h
+#if ENABLE(SVG)
#include "RenderSVGContainer.h"
namespace WebCore {
@@ -30,7 +31,7 @@ class SVGElement;
// <defs>, <linearGradient>, <radialGradient> are all good examples
class RenderSVGHiddenContainer : public RenderSVGContainer {
public:
- RenderSVGHiddenContainer(SVGElement&, Ref<RenderStyle>&&);
+ RenderSVGHiddenContainer(SVGElement&, PassRef<RenderStyle>);
protected:
virtual void layout() override;
@@ -48,4 +49,5 @@ private:
};
}
+#endif // ENABLE(SVG)
#endif // RenderSVGHiddenContainer_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGImage.cpp b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
index 502167981..58dc14597 100644
--- a/Source/WebCore/rendering/svg/RenderSVGImage.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGImage.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Alexander Kellett <lypanov@kde.org>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2007, 2008, 2009 Rob Buis <buis@kde.org>
* Copyright (C) 2009 Google, Inc.
@@ -24,15 +24,17 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGImage.h"
+#include "Attr.h"
#include "FloatQuad.h"
#include "GraphicsContext.h"
#include "LayoutRepainter.h"
#include "PointerEventsHitRules.h"
#include "RenderImageResource.h"
#include "RenderLayer.h"
-#include "RenderSVGResource.h"
#include "RenderSVGResourceFilter.h"
#include "SVGImageElement.h"
#include "SVGLength.h"
@@ -43,8 +45,8 @@
namespace WebCore {
-RenderSVGImage::RenderSVGImage(SVGImageElement& element, Ref<RenderStyle>&& style)
- : RenderSVGModelObject(element, WTF::move(style))
+RenderSVGImage::RenderSVGImage(SVGImageElement& element, PassRef<RenderStyle> style)
+ : RenderSVGModelObject(element, std::move(style))
, m_needsBoundariesUpdate(true)
, m_needsTransformUpdate(true)
, m_imageResource(std::make_unique<RenderImageResource>())
@@ -59,38 +61,22 @@ RenderSVGImage::~RenderSVGImage()
SVGImageElement& RenderSVGImage::imageElement() const
{
- return downcast<SVGImageElement>(RenderSVGModelObject::element());
+ return toSVGImageElement(RenderSVGModelObject::element());
}
bool RenderSVGImage::updateImageViewport()
{
FloatRect oldBoundaries = m_objectBoundingBox;
- bool updatedViewport = false;
SVGLengthContext lengthContext(&imageElement());
m_objectBoundingBox = FloatRect(imageElement().x().value(lengthContext), imageElement().y().value(lengthContext), imageElement().width().value(lengthContext), imageElement().height().value(lengthContext));
- // Images with preserveAspectRatio=none should force non-uniform scaling. This can be achieved
- // by setting the image's container size to its intrinsic size.
- // See: http://www.w3.org/TR/SVG/single-page.html, 7.8 The ‘preserveAspectRatio’ attribute.
- if (imageElement().preserveAspectRatio().align() == SVGPreserveAspectRatio::SVG_PRESERVEASPECTRATIO_NONE) {
- if (CachedImage* cachedImage = imageResource().cachedImage()) {
- LayoutSize intrinsicSize = cachedImage->imageSizeForRenderer(0, style().effectiveZoom());
- if (intrinsicSize != imageResource().imageSize(style().effectiveZoom())) {
- imageResource().setContainerSizeForRenderer(roundedIntSize(intrinsicSize));
- updatedViewport = true;
- }
- }
- }
-
- if (oldBoundaries != m_objectBoundingBox) {
- if (!updatedViewport)
- imageResource().setContainerSizeForRenderer(enclosingIntRect(m_objectBoundingBox).size());
- updatedViewport = true;
- m_needsBoundariesUpdate = true;
- }
+ if (oldBoundaries == m_objectBoundingBox)
+ return false;
- return updatedViewport;
+ imageResource().setContainerSizeForRenderer(enclosingIntRect(m_objectBoundingBox).size());
+ m_needsBoundariesUpdate = true;
+ return true;
}
void RenderSVGImage::layout()
@@ -131,8 +117,7 @@ void RenderSVGImage::layout()
void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
- if (paintInfo.context->paintingDisabled() || paintInfo.phase != PaintPhaseForeground
- || style().visibility() == HIDDEN || !imageResource().hasImage())
+ if (paintInfo.context->paintingDisabled() || style().visibility() == HIDDEN || !imageResource().hasImage())
return;
FloatRect boundingBox = repaintRectInLocalCoordinates();
@@ -140,22 +125,25 @@ void RenderSVGImage::paint(PaintInfo& paintInfo, const LayoutPoint&)
return;
PaintInfo childPaintInfo(paintInfo);
- GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
- childPaintInfo.applyTransform(m_localTransform);
+ bool drawsOutline = style().outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
+ if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
+ GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
+ childPaintInfo.applyTransform(m_localTransform);
- if (childPaintInfo.phase == PaintPhaseForeground) {
- SVGRenderingContext renderingContext(*this, childPaintInfo);
+ if (childPaintInfo.phase == PaintPhaseForeground) {
+ SVGRenderingContext renderingContext(*this, childPaintInfo);
- if (renderingContext.isRenderingPrepared()) {
- if (style().svgStyle().bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
- return;
+ if (renderingContext.isRenderingPrepared()) {
+ if (style().svgStyle().bufferedRendering() == BR_STATIC && renderingContext.bufferForeground(m_bufferedForeground))
+ return;
- paintForeground(childPaintInfo);
+ paintForeground(childPaintInfo);
+ }
}
- }
- if (style().outlineWidth())
- paintOutline(childPaintInfo, IntRect(boundingBox));
+ if (drawsOutline)
+ paintOutline(childPaintInfo, IntRect(boundingBox));
+ }
}
void RenderSVGImage::paintForeground(PaintInfo& paintInfo)
@@ -190,7 +178,7 @@ bool RenderSVGImage::nodeAtFloatPoint(const HitTestRequest& request, HitTestResu
if (hitRules.canHitFill) {
if (m_objectBoundingBox.contains(localPoint)) {
- updateHitTestResult(result, LayoutPoint(localPoint));
+ updateHitTestResult(result, roundedLayoutPoint(localPoint));
return true;
}
}
@@ -203,7 +191,7 @@ void RenderSVGImage::imageChanged(WrappedImagePtr, const IntRect*)
{
// The image resource defaults to nullImage until the resource arrives.
// This empty image may be cached by SVG resources which must be invalidated.
- if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this))
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*this))
resources->removeClientFromCache(*this);
// Eventually notify parent resources, that we've changed.
@@ -228,3 +216,5 @@ void RenderSVGImage::addFocusRingRects(Vector<IntRect>& rects, const LayoutPoint
}
} // namespace WebCore
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGImage.h b/Source/WebCore/rendering/svg/RenderSVGImage.h
index b36bd218c..bb101cdaa 100644
--- a/Source/WebCore/rendering/svg/RenderSVGImage.h
+++ b/Source/WebCore/rendering/svg/RenderSVGImage.h
@@ -24,6 +24,7 @@
#ifndef RenderSVGImage_h
#define RenderSVGImage_h
+#if ENABLE(SVG)
#include "AffineTransform.h"
#include "FloatRect.h"
#include "RenderSVGModelObject.h"
@@ -36,15 +37,15 @@ class SVGImageElement;
class RenderSVGImage final : public RenderSVGModelObject {
public:
- RenderSVGImage(SVGImageElement&, Ref<RenderStyle>&&);
+ RenderSVGImage(SVGImageElement&, PassRef<RenderStyle>);
virtual ~RenderSVGImage();
SVGImageElement& imageElement() const;
bool updateImageViewport();
- virtual void setNeedsBoundariesUpdate() override { m_needsBoundariesUpdate = true; }
+ virtual void setNeedsBoundariesUpdate() { m_needsBoundariesUpdate = true; }
virtual bool needsBoundariesUpdate() override { return m_needsBoundariesUpdate; }
- virtual void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
RenderImageResource& imageResource() { return *m_imageResource; }
const RenderImageResource& imageResource() const { return *m_imageResource; }
@@ -55,29 +56,29 @@ public:
private:
void element() const = delete;
- virtual const char* renderName() const override { return "RenderSVGImage"; }
+ virtual const char* renderName() const { return "RenderSVGImage"; }
virtual bool isSVGImage() const override { return true; }
virtual bool canHaveChildren() const override { return false; }
- virtual const AffineTransform& localToParentTransform() const override { return m_localTransform; }
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
- virtual FloatRect objectBoundingBox() const override { return m_objectBoundingBox; }
- virtual FloatRect strokeBoundingBox() const override { return m_objectBoundingBox; }
- virtual FloatRect repaintRectInLocalCoordinates() const override { return m_repaintBoundingBox; }
+ virtual FloatRect objectBoundingBox() const { return m_objectBoundingBox; }
+ virtual FloatRect strokeBoundingBox() const { return m_objectBoundingBox; }
+ virtual FloatRect repaintRectInLocalCoordinates() const { return m_repaintBoundingBox; }
virtual FloatRect repaintRectInLocalCoordinatesExcludingSVGShadow() const override { return m_repaintBoundingBoxExcludingShadow; }
virtual void addFocusRingRects(Vector<IntRect>&, const LayoutPoint& additionalOffset, const RenderLayerModelObject* paintContainer = 0) override;
- virtual void imageChanged(WrappedImagePtr, const IntRect* = nullptr) override;
+ virtual void imageChanged(WrappedImagePtr, const IntRect* = 0);
- virtual void layout() override;
- virtual void paint(PaintInfo&, const LayoutPoint&) override;
+ virtual void layout();
+ virtual void paint(PaintInfo&, const LayoutPoint&);
void invalidateBufferedForeground();
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) override;
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
- virtual AffineTransform localTransform() const override { return m_localTransform; }
+ virtual AffineTransform localTransform() const { return m_localTransform; }
void calculateImageViewport();
bool m_needsBoundariesUpdate : 1;
@@ -90,8 +91,9 @@ private:
std::unique_ptr<ImageBuffer> m_bufferedForeground;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGImage, isSVGImage())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGImage, isSVGImage())
+} // namespace WebCore
+#endif // ENABLE(SVG)
#endif // RenderSVGImage_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGInline.cpp b/Source/WebCore/rendering/svg/RenderSVGInline.cpp
index f194702de..f1f384e93 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInline.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInline.cpp
@@ -20,6 +20,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGInline.h"
#include "RenderSVGInlineText.h"
@@ -30,8 +32,8 @@
namespace WebCore {
-RenderSVGInline::RenderSVGInline(SVGGraphicsElement& element, Ref<RenderStyle>&& style)
- : RenderInline(element, WTF::move(style))
+RenderSVGInline::RenderSVGInline(SVGGraphicsElement& element, PassRef<RenderStyle> style)
+ : RenderInline(element, std::move(style))
{
setAlwaysCreateLineBoxes();
}
@@ -40,29 +42,29 @@ std::unique_ptr<InlineFlowBox> RenderSVGInline::createInlineFlowBox()
{
auto box = std::make_unique<SVGInlineFlowBox>(*this);
box->setHasVirtualLogicalHeight();
- return WTF::move(box);
+ return std::move(box);
}
FloatRect RenderSVGInline::objectBoundingBox() const
{
- if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
- return textAncestor->objectBoundingBox();
+ if (const RenderObject* object = RenderSVGText::locateRenderSVGTextAncestor(this))
+ return object->objectBoundingBox();
return FloatRect();
}
FloatRect RenderSVGInline::strokeBoundingBox() const
{
- if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
- return textAncestor->strokeBoundingBox();
+ if (const RenderObject* object = RenderSVGText::locateRenderSVGTextAncestor(this))
+ return object->strokeBoundingBox();
return FloatRect();
}
FloatRect RenderSVGInline::repaintRectInLocalCoordinates() const
{
- if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
- return textAncestor->repaintRectInLocalCoordinates();
+ if (const RenderObject* object = RenderSVGText::locateRenderSVGTextAncestor(this))
+ return object->repaintRectInLocalCoordinates();
return FloatRect();
}
@@ -89,13 +91,13 @@ const RenderObject* RenderSVGInline::pushMappingToContainer(const RenderLayerMod
void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
{
- auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this);
- if (!textAncestor)
+ const RenderObject* object = RenderSVGText::locateRenderSVGTextAncestor(this);
+ if (!object)
return;
- FloatRect textBoundingBox = textAncestor->strokeBoundingBox();
+ FloatRect textBoundingBox = object->strokeBoundingBox();
for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox())
- quads.append(localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x(), textBoundingBox.y() + box->y(), box->logicalWidth(), box->logicalHeight()), UseTransforms, wasFixed));
+ quads.append(localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x(), textBoundingBox.y() + box->y(), box->logicalWidth(), box->logicalHeight()), false, wasFixed));
}
void RenderSVGInline::willBeDestroyed()
@@ -112,37 +114,30 @@ void RenderSVGInline::styleDidChange(StyleDifference diff, const RenderStyle* ol
SVGResourcesCache::clientStyleChanged(*this, diff, style());
}
-void RenderSVGInline::updateFromStyle()
-{
- RenderInline::updateFromStyle();
-
- // SVG text layout code expects us to be an inline-level element.
- setInline(true);
-}
-
void RenderSVGInline::addChild(RenderObject* child, RenderObject* beforeChild)
{
RenderInline::addChild(child, beforeChild);
SVGResourcesCache::clientWasAddedToTree(*child);
- if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
- textAncestor->subtreeChildWasAdded(child);
+ if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
+ textRenderer->subtreeChildWasAdded(child);
}
void RenderSVGInline::removeChild(RenderObject& child)
{
SVGResourcesCache::clientWillBeRemovedFromTree(child);
- auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this);
- if (!textAncestor) {
+ RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this);
+ if (!textRenderer) {
RenderInline::removeChild(child);
return;
}
-
Vector<SVGTextLayoutAttributes*, 2> affectedAttributes;
- textAncestor->subtreeChildWillBeRemoved(&child, affectedAttributes);
+ textRenderer->subtreeChildWillBeRemoved(&child, affectedAttributes);
RenderInline::removeChild(child);
- textAncestor->subtreeChildWasRemoved(affectedAttributes);
+ textRenderer->subtreeChildWasRemoved(affectedAttributes);
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGInline.h b/Source/WebCore/rendering/svg/RenderSVGInline.h
index a001f29ff..f6dee80e9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInline.h
+++ b/Source/WebCore/rendering/svg/RenderSVGInline.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,6 +21,7 @@
#ifndef RenderSVGInline_h
#define RenderSVGInline_h
+#if ENABLE(SVG)
#include "RenderInline.h"
#include "SVGGraphicsElement.h"
@@ -28,9 +29,9 @@ namespace WebCore {
class RenderSVGInline : public RenderInline {
public:
- RenderSVGInline(SVGGraphicsElement&, Ref<RenderStyle>&&);
+ RenderSVGInline(SVGGraphicsElement&, PassRef<RenderStyle>);
- SVGGraphicsElement& graphicsElement() const { return downcast<SVGGraphicsElement>(nodeForNonAnonymous()); }
+ SVGGraphicsElement& graphicsElement() const { return toSVGGraphicsElement(nodeForNonAnonymous()); }
private:
void element() const = delete;
@@ -39,8 +40,6 @@ private:
virtual bool requiresLayer() const override final { return false; }
virtual bool isSVGInline() const override final { return true; }
- virtual void updateFromStyle() override final;
-
// Chapter 10.4 of the SVG Specification say that we should use the
// object bounding box of the parent text element.
// We search for the root text element and take its bounding box.
@@ -52,7 +51,7 @@ private:
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override final;
virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const override final;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override final;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const override final;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override final;
virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override final;
@@ -61,12 +60,11 @@ private:
virtual void willBeDestroyed() override final;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override final;
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = nullptr) override final;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0) override final;
virtual void removeChild(RenderObject&) override final;
};
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGInline, isSVGInline())
+}
+#endif // ENABLE(SVG)
#endif // !RenderSVGTSpan_H
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
index c3c471b49..0667e8479 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer Inc.
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2008 Rob Buis <buis@kde.org>
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
@@ -22,6 +22,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGInlineText.h"
#include "CSSFontSelector.h"
@@ -77,11 +79,11 @@ String RenderSVGInlineText::originalText() const
return textNode().data();
}
-void RenderSVGInlineText::setRenderedText(const String& text)
+void RenderSVGInlineText::setTextInternal(const String& text)
{
- RenderText::setRenderedText(text);
- if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
- textAncestor->subtreeTextDidChange(this);
+ RenderText::setTextInternal(text);
+ if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
+ textRenderer->subtreeTextDidChange(this);
}
void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
@@ -105,35 +107,35 @@ void RenderSVGInlineText::styleDidChange(StyleDifference diff, const RenderStyle
return;
// The text metrics may be influenced by style changes.
- if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
- textAncestor->subtreeStyleDidChange(this);
+ if (RenderSVGText* textRenderer = RenderSVGText::locateRenderSVGTextAncestor(this))
+ textRenderer->subtreeStyleDidChange(this);
}
std::unique_ptr<InlineTextBox> RenderSVGInlineText::createTextBox()
{
auto box = std::make_unique<SVGInlineTextBox>(*this);
box->setHasVirtualLogicalHeight();
- return WTF::move(box);
+ return std::move(box);
}
LayoutRect RenderSVGInlineText::localCaretRect(InlineBox* box, int caretOffset, LayoutUnit*)
{
- if (!is<InlineTextBox>(box))
+ if (!box || !box->isInlineTextBox())
return LayoutRect();
- auto& textBox = downcast<InlineTextBox>(*box);
- if (static_cast<unsigned>(caretOffset) < textBox.start() || static_cast<unsigned>(caretOffset) > textBox.start() + textBox.len())
+ InlineTextBox* textBox = toInlineTextBox(box);
+ if (static_cast<unsigned>(caretOffset) < textBox->start() || static_cast<unsigned>(caretOffset) > textBox->start() + textBox->len())
return LayoutRect();
// Use the edge of the selection rect to determine the caret rect.
- if (static_cast<unsigned>(caretOffset) < textBox.start() + textBox.len()) {
- LayoutRect rect = textBox.localSelectionRect(caretOffset, caretOffset + 1);
- LayoutUnit x = textBox.isLeftToRightDirection() ? rect.x() : rect.maxX();
+ if (static_cast<unsigned>(caretOffset) < textBox->start() + textBox->len()) {
+ LayoutRect rect = textBox->localSelectionRect(caretOffset, caretOffset + 1);
+ LayoutUnit x = box->isLeftToRightDirection() ? rect.x() : rect.maxX();
return LayoutRect(x, rect.y(), caretWidth, rect.height());
}
- LayoutRect rect = textBox.localSelectionRect(caretOffset - 1, caretOffset);
- LayoutUnit x = textBox.isLeftToRightDirection() ? rect.maxX() : rect.x();
+ LayoutRect rect = textBox->localSelectionRect(caretOffset - 1, caretOffset);
+ LayoutUnit x = box->isLeftToRightDirection() ? rect.maxX() : rect.x();
return LayoutRect(x, rect.y(), caretWidth, rect.height());
}
@@ -166,7 +168,7 @@ bool RenderSVGInlineText::characterStartsNewTextChunk(int position) const
return it->value.x != SVGTextLayoutAttributes::emptyValue() || it->value.y != SVGTextLayoutAttributes::emptyValue();
}
-VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point, const RenderRegion*)
+VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point)
{
if (!firstTextBox() || !textLength())
return createVisiblePosition(0, DOWNSTREAM);
@@ -182,16 +184,16 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point,
float closestDistance = std::numeric_limits<float>::max();
float closestDistancePosition = 0;
- const SVGTextFragment* closestDistanceFragment = nullptr;
- SVGInlineTextBox* closestDistanceBox = nullptr;
+ const SVGTextFragment* closestDistanceFragment = 0;
+ SVGInlineTextBox* closestDistanceBox = 0;
AffineTransform fragmentTransform;
for (InlineTextBox* box = firstTextBox(); box; box = box->nextTextBox()) {
- if (!is<SVGInlineTextBox>(*box))
+ if (!box->isSVGInlineTextBox())
continue;
- auto& textBox = downcast<SVGInlineTextBox>(*box);
- Vector<SVGTextFragment>& fragments = textBox.textFragments();
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
+ Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned textFragmentsSize = fragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
@@ -206,7 +208,7 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point,
if (distance < closestDistance) {
closestDistance = distance;
- closestDistanceBox = &textBox;
+ closestDistanceBox = textBox;
closestDistanceFragment = &fragment;
closestDistancePosition = fragmentRect.x();
}
@@ -222,26 +224,31 @@ VisiblePosition RenderSVGInlineText::positionForPoint(const LayoutPoint& point,
void RenderSVGInlineText::updateScaledFont()
{
- computeNewScaledFontForStyle(*this, style(), m_scalingFactor, m_scaledFont);
+ computeNewScaledFontForStyle(this, &style(), m_scalingFactor, m_scaledFont);
}
-void RenderSVGInlineText::computeNewScaledFontForStyle(const RenderObject& renderer, const RenderStyle& style, float& scalingFactor, FontCascade& scaledFont)
+void RenderSVGInlineText::computeNewScaledFontForStyle(RenderObject* renderer, const RenderStyle* style, float& scalingFactor, Font& scaledFont)
{
+ ASSERT(style);
+ ASSERT(renderer);
+
// Alter font-size to the right on-screen value to avoid scaling the glyphs themselves, except when GeometricPrecision is specified
scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer);
- if (!scalingFactor || style.fontDescription().textRenderingMode() == GeometricPrecision) {
+ if (scalingFactor == 1 || !scalingFactor || style->fontDescription().textRenderingMode() == GeometricPrecision) {
scalingFactor = 1;
- scaledFont = style.fontCascade();
+ scaledFont = style->font();
return;
}
- FontDescription fontDescription(style.fontDescription());
+ FontDescription fontDescription(style->fontDescription());
// FIXME: We need to better handle the case when we compute very small fonts below (below 1pt).
- fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSizeForSVGInlineText(fontDescription.computedSize(), fontDescription.isAbsoluteSize(), scalingFactor, renderer.document()));
+ fontDescription.setComputedSize(Style::computedFontSizeFromSpecifiedSizeForSVGInlineText(fontDescription.computedSize(), fontDescription.isAbsoluteSize(), scalingFactor, renderer->document()));
- scaledFont = FontCascade(fontDescription, 0, 0);
- scaledFont.update(&renderer.document().fontSelector());
+ scaledFont = Font(fontDescription, 0, 0);
+ scaledFont.update(renderer->document().ensureStyleResolver().fontSelector());
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGInlineText.h b/Source/WebCore/rendering/svg/RenderSVGInlineText.h
index 7e349978e..c07228e21 100644
--- a/Source/WebCore/rendering/svg/RenderSVGInlineText.h
+++ b/Source/WebCore/rendering/svg/RenderSVGInlineText.h
@@ -22,7 +22,8 @@
#ifndef RenderSVGInlineText_h
#define RenderSVGInlineText_h
-#include "FontCascade.h"
+#if ENABLE(SVG)
+#include "Font.h"
#include "RenderText.h"
#include "SVGTextLayoutAttributes.h"
#include "Text.h"
@@ -35,15 +36,15 @@ class RenderSVGInlineText final : public RenderText {
public:
RenderSVGInlineText(Text&, const String&);
- Text& textNode() const { return downcast<Text>(nodeForNonAnonymous()); }
+ Text& textNode() const { return toText(nodeForNonAnonymous()); }
bool characterStartsNewTextChunk(int position) const;
SVGTextLayoutAttributes* layoutAttributes() { return &m_layoutAttributes; }
float scalingFactor() const { return m_scalingFactor; }
- const FontCascade& scaledFont() const { return m_scaledFont; }
+ const Font& scaledFont() const { return m_scaledFont; }
void updateScaledFont();
- static void computeNewScaledFontForStyle(const RenderObject&, const RenderStyle&, float& scalingFactor, FontCascade& scaledFont);
+ static void computeNewScaledFontForStyle(RenderObject*, const RenderStyle*, float& scalingFactor, Font& scaledFont);
// Preserves floating point precision for the use in DRT. It knows how to round and does a better job than enclosingIntRect.
FloatRect floatLinesBoundingBox() const;
@@ -52,25 +53,26 @@ private:
virtual const char* renderName() const override { return "RenderSVGInlineText"; }
virtual String originalText() const override;
- virtual void setRenderedText(const String&) override;
+ virtual void setTextInternal(const String&) override;
virtual void styleDidChange(StyleDifference, const RenderStyle*) override;
virtual FloatRect objectBoundingBox() const override { return floatLinesBoundingBox(); }
virtual bool isSVGInlineText() const override { return true; }
- virtual VisiblePosition positionForPoint(const LayoutPoint&, const RenderRegion*) override;
+ virtual VisiblePosition positionForPoint(const LayoutPoint&) override;
virtual LayoutRect localCaretRect(InlineBox*, int caretOffset, LayoutUnit* extraWidthToEndOfLine = 0) override;
virtual IntRect linesBoundingBox() const override;
virtual std::unique_ptr<InlineTextBox> createTextBox() override;
float m_scalingFactor;
- FontCascade m_scaledFont;
+ Font m_scaledFont;
SVGTextLayoutAttributes m_layoutAttributes;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGInlineText, isSVGInlineText())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGInlineText, isSVGInlineText())
+}
+#endif // ENABLE(SVG)
#endif // RenderSVGInlineText_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
index 68b20da62..78768eafe 100644
--- a/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.cpp
@@ -29,6 +29,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGModelObject.h"
#include "RenderLayerModelObject.h"
@@ -39,8 +41,8 @@
namespace WebCore {
-RenderSVGModelObject::RenderSVGModelObject(SVGElement& element, Ref<RenderStyle>&& style)
- : RenderElement(element, WTF::move(style), 0)
+RenderSVGModelObject::RenderSVGModelObject(SVGElement& element, PassRef<RenderStyle> style)
+ : RenderElement(element, std::move(style), 0)
, m_hasSVGShadow(false)
{
}
@@ -74,7 +76,7 @@ LayoutRect RenderSVGModelObject::outlineBoundsForRepaint(const RenderLayerModelO
adjustRectForOutlineAndShadow(box);
FloatQuad containerRelativeQuad = localToContainerQuad(FloatRect(box), repaintContainer);
- return LayoutRect(snapRectToDevicePixels(LayoutRect(containerRelativeQuad.boundingBox()), document().deviceScaleFactor()));
+ return containerRelativeQuad.enclosingBoundingBox();
}
void RenderSVGModelObject::absoluteRects(Vector<IntRect>& rects, const LayoutPoint& accumulatedOffset) const
@@ -86,7 +88,7 @@ void RenderSVGModelObject::absoluteRects(Vector<IntRect>& rects, const LayoutPoi
void RenderSVGModelObject::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
{
- quads.append(localToAbsoluteQuad(strokeBoundingBox(), UseTransforms, wasFixed));
+ quads.append(localToAbsoluteQuad(strokeBoundingBox(), 0 /* mode */, wasFixed));
}
void RenderSVGModelObject::willBeDestroyed()
@@ -124,11 +126,11 @@ static void getElementCTM(SVGElement* element, AffineTransform& transform)
Node* current = element;
while (current && current->isSVGElement()) {
- SVGElement& currentElement = downcast<SVGElement>(*current);
- localTransform = currentElement.renderer()->localToParentTransform();
+ SVGElement* currentElement = toSVGElement(current);
+ localTransform = currentElement->renderer()->localToParentTransform();
transform = localTransform.multiply(transform);
// For getCTM() computation, stop at the nearest viewport element
- if (&currentElement == stopAtElement)
+ if (currentElement == stopAtElement)
break;
current = current->parentOrShadowHostNode();
@@ -171,7 +173,7 @@ bool RenderSVGModelObject::checkIntersection(RenderElement* renderer, const Floa
if (!isGraphicsElement(*renderer))
return false;
AffineTransform ctm;
- SVGElement* svgElement = downcast<SVGElement>(renderer->element());
+ SVGElement* svgElement = toSVGElement(renderer->element());
getElementCTM(svgElement, ctm);
ASSERT(svgElement->renderer());
return intersectsAllowingEmpty(rect, ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
@@ -184,10 +186,12 @@ bool RenderSVGModelObject::checkEnclosure(RenderElement* renderer, const FloatRe
if (!isGraphicsElement(*renderer))
return false;
AffineTransform ctm;
- SVGElement* svgElement = downcast<SVGElement>(renderer->element());
+ SVGElement* svgElement = toSVGElement(renderer->element());
getElementCTM(svgElement, ctm);
ASSERT(svgElement->renderer());
return rect.contains(ctm.mapRect(svgElement->renderer()->repaintRectInLocalCoordinates()));
}
} // namespace WebCore
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGModelObject.h b/Source/WebCore/rendering/svg/RenderSVGModelObject.h
index 00d2f69f3..a7cd417aa 100644
--- a/Source/WebCore/rendering/svg/RenderSVGModelObject.h
+++ b/Source/WebCore/rendering/svg/RenderSVGModelObject.h
@@ -31,6 +31,8 @@
#ifndef RenderSVGModelObject_h
#define RenderSVGModelObject_h
+#if ENABLE(SVG)
+
#include "RenderElement.h"
#include "SVGElement.h"
#include "SVGRenderSupport.h"
@@ -53,7 +55,7 @@ public:
virtual void absoluteRects(Vector<IntRect>&, const LayoutPoint& accumulatedOffset) const override final;
virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override final;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const override final;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override final;
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override;
@@ -64,10 +66,10 @@ public:
bool hasSVGShadow() const { return m_hasSVGShadow; }
void setHasSVGShadow(bool hasShadow) { m_hasSVGShadow = hasShadow; }
- SVGElement& element() const { return downcast<SVGElement>(nodeForNonAnonymous()); }
+ SVGElement& element() const { return toSVGElement(nodeForNonAnonymous()); }
protected:
- RenderSVGModelObject(SVGElement&, Ref<RenderStyle>&&);
+ RenderSVGModelObject(SVGElement&, PassRef<RenderStyle>);
virtual void willBeDestroyed() override;
@@ -80,8 +82,9 @@ private:
bool m_hasSVGShadow;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGModelObject, isRenderSVGModelObject());
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGModelObject, isRenderSVGModelObject())
+}
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGPath.cpp b/Source/WebCore/rendering/svg/RenderSVGPath.cpp
index 8e40d8be9..353dd238c 100644
--- a/Source/WebCore/rendering/svg/RenderSVGPath.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGPath.cpp
@@ -26,6 +26,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGPath.h"
#include "SVGPathElement.h"
@@ -33,8 +35,8 @@
namespace WebCore {
-RenderSVGPath::RenderSVGPath(SVGGraphicsElement& element, Ref<RenderStyle>&& style)
- : RenderSVGShape(element, WTF::move(style))
+RenderSVGPath::RenderSVGPath(SVGGraphicsElement& element, PassRef<RenderStyle> style)
+ : RenderSVGShape(element, std::move(style))
{
}
@@ -67,9 +69,9 @@ FloatRect RenderSVGPath::calculateUpdatedStrokeBoundingBox() const
static void useStrokeStyleToFill(GraphicsContext* context)
{
if (Gradient* gradient = context->strokeGradient())
- context->setFillGradient(*gradient);
+ context->setFillGradient(gradient);
else if (Pattern* pattern = context->strokePattern())
- context->setFillPattern(*pattern);
+ context->setFillPattern(pattern);
else
context->setFillColor(context->strokeColor(), context->strokeColorSpace());
}
@@ -131,7 +133,7 @@ bool RenderSVGPath::shouldStrokeZeroLengthSubpath() const
Path* RenderSVGPath::zeroLengthLinecapPath(const FloatPoint& linecapPosition) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(Path, tempPath, ());
+ DEFINE_STATIC_LOCAL(Path, tempPath, ());
tempPath.clear();
if (style().svgStyle().capStyle() == SquareCap)
@@ -155,17 +157,10 @@ void RenderSVGPath::updateZeroLengthSubpaths()
return;
SVGSubpathData subpathData(m_zeroLengthLinecapLocations);
- path().apply([&subpathData](const PathElement& pathElement) {
- SVGSubpathData::updateFromPathElement(subpathData, pathElement);
- });
+ path().apply(&subpathData, SVGSubpathData::updateFromPathElement);
subpathData.pathIsDone();
}
-bool RenderSVGPath::isRenderingDisabled() const
-{
- // For a polygon, polyline or path, rendering is disabled if there is no path data.
- // No path data is possible in the case of a missing or empty 'd' or 'points' attribute.
- return path().isEmpty();
}
-}
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGPath.h b/Source/WebCore/rendering/svg/RenderSVGPath.h
index 08d89119e..5ffd494f4 100644
--- a/Source/WebCore/rendering/svg/RenderSVGPath.h
+++ b/Source/WebCore/rendering/svg/RenderSVGPath.h
@@ -2,7 +2,7 @@
* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
* Copyright (C) 2005 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc
* Copyright (C) 2009 Google, Inc.
* Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
* Copyright (C) 2011 University of Szeged
@@ -26,18 +26,19 @@
#ifndef RenderSVGPath_h
#define RenderSVGPath_h
+#if ENABLE(SVG)
#include "RenderSVGShape.h"
namespace WebCore {
class RenderSVGPath final : public RenderSVGShape {
public:
- RenderSVGPath(SVGGraphicsElement&, Ref<RenderStyle>&&);
+ RenderSVGPath(SVGGraphicsElement&, PassRef<RenderStyle>);
virtual ~RenderSVGPath();
private:
virtual bool isSVGPath() const override { return true; }
- virtual const char* renderName() const override { return "RenderSVGPath"; }
+ virtual const char* renderName() const { return "RenderSVGPath"; }
virtual void updateShapeFromElement() override;
FloatRect calculateUpdatedStrokeBoundingBox() const;
@@ -50,13 +51,12 @@ private:
FloatRect zeroLengthSubpathRect(const FloatPoint&, float) const;
void updateZeroLengthSubpaths();
- virtual bool isRenderingDisabled() const override;
-
Vector<FloatPoint> m_zeroLengthLinecapLocations;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGPath, isSVGPath())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGPath, isSVGPath())
+}
-#endif // RenderSVGPath_h
+#endif // ENABLE(SVG)
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGRect.cpp b/Source/WebCore/rendering/svg/RenderSVGRect.cpp
index 03fbbb9d5..bfda62f5f 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRect.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRect.cpp
@@ -26,14 +26,16 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGRect.h"
#include "SVGNames.h"
namespace WebCore {
-RenderSVGRect::RenderSVGRect(SVGRectElement& element, Ref<RenderStyle>&& style)
- : RenderSVGShape(element, WTF::move(style))
+RenderSVGRect::RenderSVGRect(SVGRectElement& element, PassRef<RenderStyle> style)
+ : RenderSVGShape(element, std::move(style))
, m_usePathFallback(false)
{
}
@@ -44,7 +46,7 @@ RenderSVGRect::~RenderSVGRect()
SVGRectElement& RenderSVGRect::rectElement() const
{
- return downcast<SVGRectElement>(RenderSVGShape::graphicsElement());
+ return toSVGRectElement(RenderSVGShape::graphicsElement());
}
void RenderSVGRect::updateShapeFromElement()
@@ -56,26 +58,19 @@ void RenderSVGRect::updateShapeFromElement()
m_outerStrokeRect = FloatRect();
SVGLengthContext lengthContext(&rectElement());
- FloatSize boundingBoxSize(lengthContext.valueForLength(style().width(), LengthModeWidth), lengthContext.valueForLength(style().height(), LengthModeHeight));
-
- // Element is invalid if either dimension is negative.
- if (boundingBoxSize.width() < 0 || boundingBoxSize.height() < 0)
+ // Fallback to RenderSVGShape if rect has rounded corners or a non-scaling stroke.
+ if (rectElement().rx().value(lengthContext) > 0 || rectElement().ry().value(lengthContext) > 0 || hasNonScalingStroke()) {
+ RenderSVGShape::updateShapeFromElement();
+ m_usePathFallback = true;
return;
-
- // Rendering enabled? Spec: "A value of zero disables rendering of the element."
- if (!boundingBoxSize.isEmpty()) {
- if (rectElement().rx().value(lengthContext) > 0 || rectElement().ry().value(lengthContext) > 0 || hasNonScalingStroke()) {
- // Fall back to RenderSVGShape
- RenderSVGShape::updateShapeFromElement();
- m_usePathFallback = true;
- return;
- }
- m_usePathFallback = false;
}
- m_fillBoundingBox = FloatRect(FloatPoint(lengthContext.valueForLength(style().svgStyle().x(), LengthModeWidth),
- lengthContext.valueForLength(style().svgStyle().y(), LengthModeHeight)),
- boundingBoxSize);
+ m_usePathFallback = false;
+ FloatSize boundingBoxSize(rectElement().width().value(lengthContext), rectElement().height().value(lengthContext));
+ if (boundingBoxSize.isEmpty())
+ return;
+
+ m_fillBoundingBox = FloatRect(FloatPoint(rectElement().x().value(lengthContext), rectElement().y().value(lengthContext)), boundingBoxSize);
// To decide if the stroke contains a point we create two rects which represent the inner and
// the outer stroke borders. A stroke contains the point, if the point is between them.
@@ -153,10 +148,6 @@ bool RenderSVGRect::shapeDependentFillContains(const FloatPoint& point, const Wi
return m_fillBoundingBox.contains(point.x(), point.y());
}
-bool RenderSVGRect::isRenderingDisabled() const
-{
- // A width or height of zero disables rendering for the element, and results in an empty bounding box.
- return m_fillBoundingBox.isEmpty();
}
-}
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGRect.h b/Source/WebCore/rendering/svg/RenderSVGRect.h
index 970301aa7..c305726b8 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRect.h
+++ b/Source/WebCore/rendering/svg/RenderSVGRect.h
@@ -28,6 +28,7 @@
#ifndef RenderSVGRect_h
#define RenderSVGRect_h
+#if ENABLE(SVG)
#include "RenderSVGPath.h"
#include "SVGRectElement.h"
@@ -35,7 +36,7 @@ namespace WebCore {
class RenderSVGRect final : public RenderSVGShape {
public:
- RenderSVGRect(SVGRectElement&, Ref<RenderStyle>&&);
+ RenderSVGRect(SVGRectElement&, PassRef<RenderStyle>);
virtual ~RenderSVGRect();
SVGRectElement& rectElement() const;
@@ -43,15 +44,14 @@ public:
private:
void graphicsElement() const = delete;
- virtual const char* renderName() const override { return "RenderSVGRect"; }
+ virtual const char* renderName() const { return "RenderSVGRect"; }
- virtual void updateShapeFromElement() override;
- virtual bool isEmpty() const override { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); }
- virtual bool isRenderingDisabled() const override;
- virtual void fillShape(GraphicsContext*) const override;
- virtual void strokeShape(GraphicsContext*) const override;
- virtual bool shapeDependentStrokeContains(const FloatPoint&) override;
- virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const override;
+ virtual void updateShapeFromElement();
+ virtual bool isEmpty() const { return m_usePathFallback ? RenderSVGShape::isEmpty() : m_fillBoundingBox.isEmpty(); };
+ virtual void fillShape(GraphicsContext*) const;
+ virtual void strokeShape(GraphicsContext*) const;
+ virtual bool shapeDependentStrokeContains(const FloatPoint&);
+ virtual bool shapeDependentFillContains(const FloatPoint&, const WindRule) const;
private:
FloatRect m_innerStrokeRect;
@@ -61,4 +61,5 @@ private:
}
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResource.cpp b/Source/WebCore/rendering/svg/RenderSVGResource.cpp
index 699e54418..d9e1d835e 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResource.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResource.cpp
@@ -21,6 +21,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResource.h"
#include "Frame.h"
@@ -111,7 +113,7 @@ static inline RenderSVGResource* requestPaintingResource(RenderSVGResourceMode m
}
// If no resources are associated with the given renderer, return the color resource.
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
if (!resources) {
if (paintType == SVGPaint::SVG_PAINTTYPE_URI_NONE || !inheritColorFromParentStyleIfNeeded(renderer, applyToFill, color))
return nullptr;
@@ -154,38 +156,28 @@ RenderSVGResourceSolidColor* RenderSVGResource::sharedSolidPaintingResource()
return s_sharedSolidPaintingResource;
}
-static inline void removeFromCacheAndInvalidateDependencies(RenderElement& renderer, bool needsLayout)
+static inline void removeFromCacheAndInvalidateDependencies(RenderObject& object, bool needsLayout)
{
- if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer)) {
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(object)) {
+#if ENABLE(FILTERS)
if (RenderSVGResourceFilter* filter = resources->filter())
- filter->removeClientFromCache(renderer);
-
+ filter->removeClientFromCache(object);
+#endif
if (RenderSVGResourceMasker* masker = resources->masker())
- masker->removeClientFromCache(renderer);
+ masker->removeClientFromCache(object);
if (RenderSVGResourceClipper* clipper = resources->clipper())
- clipper->removeClientFromCache(renderer);
+ clipper->removeClientFromCache(object);
}
- if (!renderer.element() || !renderer.element()->isSVGElement())
+ if (!object.node() || !object.node()->isSVGElement())
return;
- HashSet<SVGElement*>* dependencies = renderer.document().accessSVGExtensions().setOfElementsReferencingTarget(downcast<SVGElement>(renderer.element()));
+ HashSet<SVGElement*>* dependencies = object.document().accessSVGExtensions()->setOfElementsReferencingTarget(toSVGElement(object.node()));
if (!dependencies)
return;
-
- // We allow cycles in SVGDocumentExtensions reference sets in order to avoid expensive
- // reference graph adjustments on changes, so we need to break possible cycles here.
- static NeverDestroyed<HashSet<SVGElement*>> invalidatingDependencies;
-
- for (auto* element : *dependencies) {
- if (auto* renderer = element->renderer()) {
- if (UNLIKELY(!invalidatingDependencies.get().add(element).isNewEntry)) {
- // Reference cycle: we are in process of invalidating this dependant.
- continue;
- }
+ for (auto element : *dependencies) {
+ if (auto renderer = element->renderer())
RenderSVGResource::markForLayoutAndParentResourceInvalidation(*renderer, needsLayout);
- invalidatingDependencies.get().remove(element);
- }
}
}
@@ -196,17 +188,16 @@ void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject&
if (needsLayout && !object.documentBeingDestroyed())
object.setNeedsLayout();
- if (is<RenderElement>(object))
- removeFromCacheAndInvalidateDependencies(downcast<RenderElement>(object), needsLayout);
+ removeFromCacheAndInvalidateDependencies(object, needsLayout);
// Invalidate resources in ancestor chain, if needed.
- auto current = object.parent();
+ RenderObject* current = object.parent();
while (current) {
removeFromCacheAndInvalidateDependencies(*current, needsLayout);
- if (is<RenderSVGResourceContainer>(*current)) {
+ if (current->isSVGResourceContainer()) {
// This will process the rest of the ancestors.
- downcast<RenderSVGResourceContainer>(*current).removeAllClientsFromCache();
+ current->toRenderSVGResourceContainer()->removeAllClientsFromCache();
break;
}
@@ -215,3 +206,6 @@ void RenderSVGResource::markForLayoutAndParentResourceInvalidation(RenderObject&
}
}
+
+#endif
+
diff --git a/Source/WebCore/rendering/svg/RenderSVGResource.h b/Source/WebCore/rendering/svg/RenderSVGResource.h
index ed7a70f50..2c66ffade 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResource.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResource.h
@@ -20,10 +20,10 @@
#ifndef RenderSVGResource_h
#define RenderSVGResource_h
+#if ENABLE(SVG)
#include "RenderSVGShape.h"
#include "RenderStyleConstants.h"
#include "SVGDocumentExtensions.h"
-#include <wtf/TypeCasts.h>
namespace WebCore {
@@ -60,7 +60,7 @@ public:
virtual ~RenderSVGResource() { }
virtual void removeAllClientsFromCache(bool markForInvalidation = true) = 0;
- virtual void removeClientFromCache(RenderElement&, bool markForInvalidation = true) = 0;
+ virtual void removeClientFromCache(RenderObject&, bool markForInvalidation = true) = 0;
virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, unsigned short resourceMode) = 0;
virtual void postApplyResource(RenderElement&, GraphicsContext*&, unsigned short, const Path*, const RenderSVGShape*) { }
@@ -68,6 +68,15 @@ public:
virtual RenderSVGResourceType resourceType() const = 0;
+ template<class Renderer>
+ Renderer* cast()
+ {
+ if (Renderer::s_resourceType == resourceType())
+ return static_cast<Renderer*>(this);
+
+ return 0;
+ }
+
// Helper utilities used in the render tree to access resources used for painting shapes/text (gradients & patterns & solid colors only)
static RenderSVGResource* fillPaintingResource(RenderElement&, const RenderStyle&, Color& fallbackColor);
static RenderSVGResource* strokePaintingResource(RenderElement&, const RenderStyle&, Color& fallbackColor);
@@ -78,9 +87,5 @@ public:
}
-#define SPECIALIZE_TYPE_TRAITS_RENDER_SVG_RESOURCE(ToValueTypeName, ResourceType) \
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::ToValueTypeName) \
- static bool isType(const WebCore::RenderSVGResource& resource) { return resource.resourceType() == WebCore::ResourceType; } \
-SPECIALIZE_TYPE_TRAITS_END()
-
+#endif
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
index 65a3e3222..5a6af206d 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.cpp
@@ -21,6 +21,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourceClipper.h"
#include "ElementIterator.h"
@@ -40,8 +42,10 @@
namespace WebCore {
-RenderSVGResourceClipper::RenderSVGResourceClipper(SVGClipPathElement& element, Ref<RenderStyle>&& style)
- : RenderSVGResourceContainer(element, WTF::move(style))
+RenderSVGResourceType RenderSVGResourceClipper::s_resourceType = ClipperResourceType;
+
+RenderSVGResourceClipper::RenderSVGResourceClipper(SVGClipPathElement& element, PassRef<RenderStyle> style)
+ : RenderSVGResourceContainer(element, std::move(style))
{
}
@@ -57,7 +61,7 @@ void RenderSVGResourceClipper::removeAllClientsFromCache(bool markForInvalidatio
markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceClipper::removeClientFromCache(RenderElement& client, bool markForInvalidation)
+void RenderSVGResourceClipper::removeClientFromCache(RenderObject& client, bool markForInvalidation)
{
m_clipper.remove(&client);
@@ -92,9 +96,9 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const
// Only shapes or paths are supported for direct clipping. We need to fallback to masking for texts.
if (renderer->isSVGText())
return false;
- if (!childNode->isSVGElement() || !downcast<SVGElement>(*childNode).isSVGGraphicsElement())
+ if (!childNode->isSVGElement() || !toSVGElement(childNode)->isSVGGraphicsElement())
continue;
- SVGGraphicsElement& styled = downcast<SVGGraphicsElement>(*childNode);
+ SVGGraphicsElement* styled = toSVGGraphicsElement(childNode);
const RenderStyle& style = renderer->style();
if (style.display() == NONE || style.visibility() != VISIBLE)
continue;
@@ -104,7 +108,7 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const
return false;
// Fallback to masking, if there is more than one clipping path.
if (clipPath.isEmpty()) {
- styled.toClipPath(clipPath);
+ styled->toClipPath(clipPath);
clipRule = svgStyle.clipRule();
} else
return false;
@@ -130,29 +134,33 @@ bool RenderSVGResourceClipper::pathOnlyClipping(GraphicsContext* context, const
bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, const FloatRect& objectBoundingBox,
const FloatRect& repaintRect, GraphicsContext* context)
{
- ClipperMaskImage& clipperMaskImage = addRendererToClipper(renderer);
- bool shouldCreateClipperMaskImage = !clipperMaskImage;
+ bool missingClipperData = !m_clipper.contains(&renderer);
+ if (missingClipperData)
+ m_clipper.set(&renderer, std::make_unique<ClipperData>());
+ bool shouldCreateClipData = false;
AffineTransform animatedLocalTransform = clipPathElement().animatedLocalTransform();
+ ClipperData* clipperData = m_clipper.get(&renderer);
+ if (!clipperData->clipMaskImage) {
+ if (pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox))
+ return true;
+ shouldCreateClipData = true;
+ }
- if (shouldCreateClipperMaskImage && pathOnlyClipping(context, animatedLocalTransform, objectBoundingBox))
- return true;
-
- AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
+ AffineTransform absoluteTransform;
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(&renderer, absoluteTransform);
- if (shouldCreateClipperMaskImage && !repaintRect.isEmpty()) {
- // FIXME (149469): This image buffer should not be unconditionally unaccelerated. Making it match the context breaks nested clipping, though.
- clipperMaskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, ColorSpaceDeviceRGB, Unaccelerated);
- if (!clipperMaskImage)
+ if (shouldCreateClipData && !repaintRect.isEmpty()) {
+ if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, clipperData->clipMaskImage, ColorSpaceDeviceRGB, Unaccelerated))
return false;
- GraphicsContext* maskContext = clipperMaskImage->context();
+ GraphicsContext* maskContext = clipperData->clipMaskImage->context();
ASSERT(maskContext);
maskContext->concatCTM(animatedLocalTransform);
// clipPath can also be clipped by another clipPath.
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*this);
RenderSVGResourceClipper* clipper;
bool succeeded;
if (resources && (clipper = resources->clipper())) {
@@ -161,27 +169,28 @@ bool RenderSVGResourceClipper::applyClippingToContext(RenderElement& renderer, c
if (!clipper->applyClippingToContext(*this, objectBoundingBox, repaintRect, maskContext))
return false;
- succeeded = drawContentIntoMaskImage(clipperMaskImage, objectBoundingBox);
+ succeeded = drawContentIntoMaskImage(clipperData, objectBoundingBox);
// The context restore applies the clipping on non-CG platforms.
} else
- succeeded = drawContentIntoMaskImage(clipperMaskImage, objectBoundingBox);
+ succeeded = drawContentIntoMaskImage(clipperData, objectBoundingBox);
if (!succeeded)
- clipperMaskImage.reset();
+ clipperData->clipMaskImage.reset();
}
- if (!clipperMaskImage)
+ if (!clipperData->clipMaskImage)
return false;
- SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, repaintRect, clipperMaskImage, shouldCreateClipperMaskImage);
+ SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, repaintRect, clipperData->clipMaskImage, missingClipperData);
return true;
}
-bool RenderSVGResourceClipper::drawContentIntoMaskImage(const ClipperMaskImage& clipperMaskImage, const FloatRect& objectBoundingBox)
+bool RenderSVGResourceClipper::drawContentIntoMaskImage(ClipperData* clipperData, const FloatRect& objectBoundingBox)
{
- ASSERT(clipperMaskImage);
+ ASSERT(clipperData);
+ ASSERT(clipperData->clipMaskImage);
- GraphicsContext* maskContext = clipperMaskImage->context();
+ GraphicsContext* maskContext = clipperData->clipMaskImage->context();
ASSERT(maskContext);
AffineTransform maskContentTransformation;
@@ -215,11 +224,11 @@ bool RenderSVGResourceClipper::drawContentIntoMaskImage(const ClipperMaskImage&
WindRule newClipRule = style.svgStyle().clipRule();
bool isUseElement = child.hasTagName(SVGNames::useTag);
if (isUseElement) {
- SVGUseElement& useElement = downcast<SVGUseElement>(child);
+ SVGUseElement& useElement = toSVGUseElement(child);
renderer = useElement.rendererClipChild();
if (!renderer)
continue;
- if (!useElement.fastHasAttribute(SVGNames::clip_ruleAttr))
+ if (!useElement.hasAttribute(SVGNames::clip_ruleAttr))
newClipRule = renderer->style().svgStyle().clipRule();
}
@@ -232,7 +241,7 @@ bool RenderSVGResourceClipper::drawContentIntoMaskImage(const ClipperMaskImage&
// In the case of a <use> element, we obtained its renderere above, to retrieve its clipRule.
// We have to pass the <use> renderer itself to renderSubtreeToImageBuffer() to apply it's x/y/transform/etc. values when rendering.
// So if isUseElement is true, refetch the childNode->renderer(), as renderer got overriden above.
- SVGRenderingContext::renderSubtreeToImageBuffer(clipperMaskImage.get(), isUseElement ? *child.renderer() : *renderer, maskContentTransformation);
+ SVGRenderingContext::renderSubtreeToImageBuffer(clipperData->clipMaskImage.get(), isUseElement ? *child.renderer() : *renderer, maskContentTransformation);
}
view().frameView().setPaintBehavior(oldBehavior);
@@ -256,11 +265,6 @@ void RenderSVGResourceClipper::calculateClipContentRepaintRect()
m_clipBoundaries = clipPathElement().animatedLocalTransform().mapRect(m_clipBoundaries);
}
-ClipperMaskImage& RenderSVGResourceClipper::addRendererToClipper(const RenderObject& object)
-{
- return m_clipper.add(&object, ClipperMaskImage()).iterator->value;
-}
-
bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundingBox, const FloatPoint& nodeAtPoint)
{
FloatPoint point = nodeAtPoint;
@@ -294,10 +298,8 @@ bool RenderSVGResourceClipper::hitTestClipContent(const FloatRect& objectBoundin
FloatRect RenderSVGResourceClipper::resourceBoundingBox(const RenderObject& object)
{
// Resource was not layouted yet. Give back the boundingBox of the object.
- if (selfNeedsLayout()) {
- addRendererToClipper(object);
+ if (selfNeedsLayout())
return object.objectBoundingBox();
- }
if (m_clipBoundaries.isEmpty())
calculateClipContentRepaintRect();
@@ -314,3 +316,5 @@ FloatRect RenderSVGResourceClipper::resourceBoundingBox(const RenderObject& obje
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h
index 4415b94b1..31c64b8b7 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceClipper.h
@@ -20,6 +20,7 @@
#ifndef RenderSVGResourceClipper_h
#define RenderSVGResourceClipper_h
+#if ENABLE(SVG)
#include "GraphicsContext.h"
#include "ImageBuffer.h"
#include "IntSize.h"
@@ -31,17 +32,21 @@
namespace WebCore {
-typedef std::unique_ptr<ImageBuffer> ClipperMaskImage;
+struct ClipperData {
+ WTF_MAKE_FAST_ALLOCATED;
+public:
+ std::unique_ptr<ImageBuffer> clipMaskImage;
+};
class RenderSVGResourceClipper final : public RenderSVGResourceContainer {
public:
- RenderSVGResourceClipper(SVGClipPathElement&, Ref<RenderStyle>&&);
+ RenderSVGResourceClipper(SVGClipPathElement&, PassRef<RenderStyle>);
virtual ~RenderSVGResourceClipper();
- SVGClipPathElement& clipPathElement() const { return downcast<SVGClipPathElement>(nodeForNonAnonymous()); }
+ SVGClipPathElement& clipPathElement() const { return toSVGClipPathElement(nodeForNonAnonymous()); }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true) override;
- virtual void removeClientFromCache(RenderElement&, bool markForInvalidation = true) override;
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject&, bool markForInvalidation = true);
virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, unsigned short resourceMode) override;
// clipPath can be clipped too, but don't have a boundingBox or repaintRect. So we can't call
@@ -50,31 +55,27 @@ public:
bool applyClippingToContext(RenderElement&, const FloatRect&, const FloatRect&, GraphicsContext*);
virtual FloatRect resourceBoundingBox(const RenderObject&) override;
- virtual RenderSVGResourceType resourceType() const override { return ClipperResourceType; }
+ virtual RenderSVGResourceType resourceType() const { return ClipperResourceType; }
bool hitTestClipContent(const FloatRect&, const FloatPoint&);
SVGUnitTypes::SVGUnitType clipPathUnits() const { return clipPathElement().clipPathUnits(); }
-protected:
- virtual bool selfNeedsClientInvalidation() const override { return (everHadLayout() || m_clipper.size()) && selfNeedsLayout(); }
-
+ static RenderSVGResourceType s_resourceType;
private:
void element() const = delete;
virtual const char* renderName() const override { return "RenderSVGResourceClipper"; }
bool pathOnlyClipping(GraphicsContext*, const AffineTransform&, const FloatRect&);
- bool drawContentIntoMaskImage(const ClipperMaskImage&, const FloatRect& objectBoundingBox);
+ bool drawContentIntoMaskImage(ClipperData*, const FloatRect& objectBoundingBox);
void calculateClipContentRepaintRect();
- ClipperMaskImage& addRendererToClipper(const RenderObject&);
FloatRect m_clipBoundaries;
- HashMap<const RenderObject*, ClipperMaskImage> m_clipper;
+ HashMap<RenderObject*, std::unique_ptr<ClipperData>> m_clipper;
};
}
-SPECIALIZE_TYPE_TRAITS_RENDER_SVG_RESOURCE(RenderSVGResourceClipper, ClipperResourceType)
-
+#endif
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
index eea2ae3f3..2d8a73138 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.cpp
@@ -18,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourceContainer.h"
#include "RenderLayer.h"
@@ -31,11 +33,12 @@ namespace WebCore {
static inline SVGDocumentExtensions& svgExtensionsFromElement(SVGElement& element)
{
- return element.document().accessSVGExtensions();
+ // FIXME: accessSVGExtensions() should return a reference.
+ return *element.document().accessSVGExtensions();
}
-RenderSVGResourceContainer::RenderSVGResourceContainer(SVGElement& element, Ref<RenderStyle>&& style)
- : RenderSVGHiddenContainer(element, WTF::move(style))
+RenderSVGResourceContainer::RenderSVGResourceContainer(SVGElement& element, PassRef<RenderStyle> style)
+ : RenderSVGHiddenContainer(element, std::move(style))
, m_id(element.getIdAttribute())
, m_registered(false)
, m_isInvalidating(false)
@@ -52,7 +55,7 @@ void RenderSVGResourceContainer::layout()
{
StackStats::LayoutCheckPoint layoutCheckPoint;
// Invalidate all resources if our layout changed.
- if (selfNeedsClientInvalidation())
+ if (everHadLayout() && selfNeedsLayout())
RenderSVGRoot::addResourceForClientInvalidation(this);
RenderSVGHiddenContainer::layout();
@@ -95,9 +98,9 @@ void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode
bool needsLayout = mode == LayoutAndBoundariesInvalidation;
bool markForInvalidation = mode != ParentOnlyInvalidation;
- for (auto* client : m_clients) {
- if (is<RenderSVGResourceContainer>(*client)) {
- downcast<RenderSVGResourceContainer>(*client).removeAllClientsFromCache(markForInvalidation);
+ for (auto client : m_clients) {
+ if (client->isSVGResourceContainer()) {
+ client->toRenderSVGResourceContainer()->removeAllClientsFromCache(markForInvalidation);
continue;
}
@@ -114,8 +117,10 @@ void RenderSVGResourceContainer::markAllClientsForInvalidation(InvalidationMode
void RenderSVGResourceContainer::markAllClientLayersForInvalidation()
{
- for (auto* clientLayer : m_clientLayers)
+#if ENABLE(CSS_FILTERS)
+ for (auto clientLayer : m_clientLayers)
clientLayer->filterNeedsRepaint();
+#endif
}
void RenderSVGResourceContainer::markClientForInvalidation(RenderObject& client, InvalidationMode mode)
@@ -136,15 +141,17 @@ void RenderSVGResourceContainer::markClientForInvalidation(RenderObject& client,
}
}
-void RenderSVGResourceContainer::addClient(RenderElement& client)
+void RenderSVGResourceContainer::addClient(RenderObject* client)
{
- m_clients.add(&client);
+ ASSERT(client);
+ m_clients.add(client);
}
-void RenderSVGResourceContainer::removeClient(RenderElement& client)
+void RenderSVGResourceContainer::removeClient(RenderObject* client)
{
- removeClientFromCache(client, false);
- m_clients.remove(&client);
+ ASSERT(client);
+ removeClientFromCache(*client, false);
+ m_clients.remove(client);
}
void RenderSVGResourceContainer::addClientRenderLayer(RenderLayer* client)
@@ -173,10 +180,11 @@ void RenderSVGResourceContainer::registerResource()
extensions.addResource(m_id, this);
// Update cached resources of pending clients.
- for (auto* client : *clients) {
- ASSERT(client->hasPendingResources());
- extensions.clearHasPendingResourcesIfPossible(client);
- auto* renderer = client->renderer();
+ auto end = clients->end();
+ for (auto it = clients->begin(); it != end; ++it) {
+ ASSERT((*it)->hasPendingResources());
+ extensions.clearHasPendingResourcesIfPossible(*it);
+ auto renderer = (*it)->renderer();
if (!renderer)
continue;
SVGResourcesCache::clientStyleChanged(*renderer, StyleDifferenceLayout, renderer->style());
@@ -184,20 +192,20 @@ void RenderSVGResourceContainer::registerResource()
}
}
-bool RenderSVGResourceContainer::shouldTransformOnTextPainting(const RenderElement& renderer, AffineTransform& resourceTransform)
+bool RenderSVGResourceContainer::shouldTransformOnTextPainting(RenderObject* object, AffineTransform& resourceTransform)
{
+ ASSERT_UNUSED(object, object);
#if USE(CG)
- UNUSED_PARAM(renderer);
UNUSED_PARAM(resourceTransform);
return false;
#else
// This method should only be called for RenderObjects that deal with text rendering. Cmp. RenderObject.h's is*() methods.
- ASSERT(renderer.isSVGText() || renderer.isSVGTextPath() || renderer.isSVGInline());
+ ASSERT(object->isSVGText() || object->isSVGTextPath() || object->isSVGInline());
// In text drawing, the scaling part of the graphics context CTM is removed, compare SVGInlineTextBox::paintTextWithShadows.
// So, we use that scaling factor here, too, and then push it down to pattern or gradient space
// in order to keep the pattern or gradient correctly scaled.
- float scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(renderer);
+ float scalingFactor = SVGRenderingContext::calculateScreenFontSizeScalingFactor(object);
if (scalingFactor == 1)
return false;
resourceTransform.scale(scalingFactor);
@@ -211,10 +219,12 @@ AffineTransform RenderSVGResourceContainer::transformOnNonScalingStroke(RenderOb
if (!object->isSVGShape())
return resourceTransform;
- SVGGraphicsElement* element = downcast<SVGGraphicsElement>(object->node());
+ SVGGraphicsElement* element = toSVGGraphicsElement(object->node());
AffineTransform transform = element->getScreenCTM(SVGLocatable::DisallowStyleUpdate);
transform *= resourceTransform;
return transform;
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
index a03706e36..b4045cabe 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceContainer.h
@@ -20,6 +20,7 @@
#ifndef RenderSVGResourceContainer_h
#define RenderSVGResourceContainer_h
+#if ENABLE(SVG)
#include "RenderSVGHiddenContainer.h"
#include "RenderSVGResource.h"
@@ -36,8 +37,9 @@ public:
virtual void styleDidChange(StyleDifference, const RenderStyle* oldStyle) override final;
virtual bool isSVGResourceContainer() const override final { return true; }
+ virtual RenderSVGResourceContainer* toRenderSVGResourceContainer() override final { return this; }
- static bool shouldTransformOnTextPainting(const RenderElement&, AffineTransform&);
+ static bool shouldTransformOnTextPainting(RenderObject*, AffineTransform&);
static AffineTransform transformOnNonScalingStroke(RenderObject*, const AffineTransform& resourceTransform);
void idChanged();
@@ -45,7 +47,7 @@ public:
void removeClientRenderLayer(RenderLayer*);
protected:
- RenderSVGResourceContainer(SVGElement&, Ref<RenderStyle>&&);
+ RenderSVGResourceContainer(SVGElement&, PassRef<RenderStyle>);
enum InvalidationMode {
LayoutAndBoundariesInvalidation,
@@ -55,16 +57,14 @@ protected:
};
// Used from the invalidateClient/invalidateClients methods from classes, inheriting from us.
- virtual bool selfNeedsClientInvalidation() const { return everHadLayout() && selfNeedsLayout(); }
-
void markAllClientsForInvalidation(InvalidationMode);
void markAllClientLayersForInvalidation();
void markClientForInvalidation(RenderObject&, InvalidationMode);
private:
friend class SVGResourcesCache;
- void addClient(RenderElement&);
- void removeClient(RenderElement&);
+ void addClient(RenderObject*);
+ void removeClient(RenderObject*);
private:
virtual void willBeDestroyed() override final;
@@ -73,35 +73,31 @@ private:
AtomicString m_id;
bool m_registered : 1;
bool m_isInvalidating : 1;
- HashSet<RenderElement*> m_clients;
+ HashSet<RenderObject*> m_clients;
HashSet<RenderLayer*> m_clientLayers;
};
inline RenderSVGResourceContainer* getRenderSVGResourceContainerById(Document& document, const AtomicString& id)
{
if (id.isEmpty())
- return nullptr;
+ return 0;
- if (RenderSVGResourceContainer* renderResource = document.accessSVGExtensions().resourceById(id))
+ if (RenderSVGResourceContainer* renderResource = document.accessSVGExtensions()->resourceById(id))
return renderResource;
- return nullptr;
+ return 0;
}
template<typename Renderer>
Renderer* getRenderSVGResourceById(Document& document, const AtomicString& id)
{
- // Using the RenderSVGResource type here avoids ambiguous casts for types that
- // descend from both RenderObject and RenderSVGResourceContainer.
- RenderSVGResource* container = getRenderSVGResourceContainerById(document, id);
- if (is<Renderer>(container))
- return downcast<Renderer>(container);
+ if (RenderSVGResourceContainer* container = getRenderSVGResourceContainerById(document, id))
+ return container->cast<Renderer>();
- return nullptr;
+ return 0;
}
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGResourceContainer, isSVGResourceContainer())
+}
-#endif // RenderSVGResourceContainer_h
+#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
index e31865d80..9dd85d6d8 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.cpp
@@ -22,6 +22,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG) && ENABLE(FILTERS)
#include "RenderSVGResourceFilter.h"
#include "ElementChildIterator.h"
@@ -39,12 +41,15 @@
#include "SVGNames.h"
#include "SVGRenderingContext.h"
#include "Settings.h"
+#include "SourceAlpha.h"
#include "SourceGraphic.h"
namespace WebCore {
-RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement& element, Ref<RenderStyle>&& style)
- : RenderSVGResourceContainer(element, WTF::move(style))
+RenderSVGResourceType RenderSVGResourceFilter::s_resourceType = FilterResourceType;
+
+RenderSVGResourceFilter::RenderSVGResourceFilter(SVGFilterElement& element, PassRef<RenderStyle> style)
+ : RenderSVGResourceContainer(element, std::move(style))
{
}
@@ -59,7 +64,7 @@ void RenderSVGResourceFilter::removeAllClientsFromCache(bool markForInvalidation
markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceFilter::removeClientFromCache(RenderElement& client, bool markForInvalidation)
+void RenderSVGResourceFilter::removeClientFromCache(RenderObject& client, bool markForInvalidation)
{
if (FilterData* filterData = m_filter.get(&client)) {
if (filterData->savedContext)
@@ -71,16 +76,16 @@ void RenderSVGResourceFilter::removeClientFromCache(RenderElement& client, bool
markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}
-std::unique_ptr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter& filter) const
+std::unique_ptr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFilter* filter)
{
static const unsigned maxCountChildNodes = 200;
- if (filterElement().countChildNodes() > maxCountChildNodes)
+ if (filterElement().childNodeCount() > maxCountChildNodes)
return nullptr;
- FloatRect targetBoundingBox = filter.targetBoundingBox();
+ FloatRect targetBoundingBox = filter->targetBoundingBox();
// Add effects to the builder
- auto builder = std::make_unique<SVGFilterBuilder>(SourceGraphic::create(filter));
+ auto builder = std::make_unique<SVGFilterBuilder>(SourceGraphic::create(filter), SourceAlpha::create(filter));
for (auto& element : childrenOfType<SVGFilterPrimitiveStandardAttributes>(filterElement())) {
RefPtr<FilterEffect> effect = element.build(builder.get(), filter);
if (!effect) {
@@ -96,6 +101,21 @@ std::unique_ptr<SVGFilterBuilder> RenderSVGResourceFilter::buildPrimitives(SVGFi
return builder;
}
+bool RenderSVGResourceFilter::fitsInMaximumImageSize(const FloatSize& size, FloatSize& scale)
+{
+ bool matchesFilterSize = true;
+ if (size.width() > kMaxFilterSize) {
+ scale.setWidth(scale.width() * kMaxFilterSize / size.width());
+ matchesFilterSize = false;
+ }
+ if (size.height() > kMaxFilterSize) {
+ scale.setHeight(scale.height() * kMaxFilterSize / size.height());
+ matchesFilterSize = false;
+ }
+
+ return matchesFilterSize;
+}
+
bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const RenderStyle&, GraphicsContext*& context, unsigned short resourceMode)
{
ASSERT(context);
@@ -116,7 +136,8 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
return false;
// Determine absolute transformation matrix for filter.
- AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
+ AffineTransform absoluteTransform;
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(&renderer, absoluteTransform);
if (!absoluteTransform.isInvertible())
return false;
@@ -134,7 +155,7 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
filterData->filter = SVGFilter::create(filterData->shearFreeAbsoluteTransform, absoluteDrawingRegion, targetBoundingBox, filterData->boundaries, primitiveBoundingBoxMode);
// Create all relevant filter primitives.
- filterData->builder = buildPrimitives(*filterData->filter);
+ filterData->builder = buildPrimitives(filterData->filter.get());
if (!filterData->builder)
return false;
@@ -151,8 +172,8 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
// Determine scale factor for filter. The size of intermediate ImageBuffers shouldn't be bigger than kMaxFilterSize.
FloatRect tempSourceRect = absoluteDrawingRegion;
- ImageBuffer::sizeNeedsClamping(tempSourceRect.size(), scale);
tempSourceRect.scale(scale.width(), scale.height());
+ fitsInMaximumImageSize(tempSourceRect.size(), scale);
// Set the scale level in SVGFilter.
filterData->filter->setFilterResolution(scale);
@@ -162,13 +183,13 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
if (!lastEffect || lastEffect->totalNumberOfEffectInputs() > maxTotalOfEffectInputs)
return false;
- RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(*lastEffect);
+ RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
FloatRect subRegion = lastEffect->maxEffectRect();
// At least one FilterEffect has a too big image size,
// recalculate the effect sizes with new scale factors.
- if (ImageBuffer::sizeNeedsClamping(subRegion.size(), scale)) {
+ if (!fitsInMaximumImageSize(subRegion.size(), scale)) {
filterData->filter->setFilterResolution(scale);
- RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(*lastEffect);
+ RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(lastEffect);
}
// If the drawingRegion is empty, we have something like <g filter=".."/>.
@@ -176,7 +197,7 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
if (filterData->drawingRegion.isEmpty()) {
ASSERT(!m_filter.contains(&renderer));
filterData->savedContext = context;
- m_filter.set(&renderer, WTF::move(filterData));
+ m_filter.set(&renderer, std::move(filterData));
return false;
}
@@ -185,13 +206,12 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
effectiveTransform.scale(scale.width(), scale.height());
effectiveTransform.multiply(filterData->shearFreeAbsoluteTransform);
+ std::unique_ptr<ImageBuffer> sourceGraphic;
RenderingMode renderingMode = renderer.frame().settings().acceleratedFiltersEnabled() ? Accelerated : Unaccelerated;
-
- auto sourceGraphic = SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, ColorSpaceLinearRGB, renderingMode);
- if (!sourceGraphic) {
+ if (!SVGRenderingContext::createImageBuffer(filterData->drawingRegion, effectiveTransform, sourceGraphic, ColorSpaceLinearRGB, renderingMode)) {
ASSERT(!m_filter.contains(&renderer));
filterData->savedContext = context;
- m_filter.set(&renderer, WTF::move(filterData));
+ m_filter.set(&renderer, std::move(filterData));
return false;
}
@@ -201,13 +221,13 @@ bool RenderSVGResourceFilter::applyResource(RenderElement& renderer, const Rende
GraphicsContext* sourceGraphicContext = sourceGraphic->context();
ASSERT(sourceGraphicContext);
- filterData->sourceGraphicBuffer = WTF::move(sourceGraphic);
+ filterData->sourceGraphicBuffer = std::move(sourceGraphic);
filterData->savedContext = context;
context = sourceGraphicContext;
ASSERT(!m_filter.contains(&renderer));
- m_filter.set(&renderer, WTF::move(filterData));
+ m_filter.set(&renderer, std::move(filterData));
return true;
}
@@ -255,7 +275,7 @@ void RenderSVGResourceFilter::postApplyResource(RenderElement& renderer, Graphic
// initial filtering process. We just take the stored filter result on a
// second drawing.
if (filterData->state != FilterData::Built)
- filterData->filter->setSourceImage(WTF::move(filterData->sourceGraphicBuffer));
+ filterData->filter->setSourceImage(std::move(filterData->sourceGraphicBuffer));
// Always true if filterData is just built (filterData->state == FilterData::Built).
if (!lastEffect->hasResult()) {
@@ -317,3 +337,4 @@ FloatRect RenderSVGResourceFilter::drawingRegion(RenderObject* object) const
}
}
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
index d6ccfbf86..97e6fdbf9 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilter.h
@@ -24,6 +24,7 @@
#ifndef RenderSVGResourceFilter_h
#define RenderSVGResourceFilter_h
+#if ENABLE(SVG) && ENABLE(FILTERS)
#include "ImageBuffer.h"
#include "RenderSVGResourceContainer.h"
#include "SVGFilter.h"
@@ -62,27 +63,28 @@ class GraphicsContext;
class RenderSVGResourceFilter final : public RenderSVGResourceContainer {
public:
- RenderSVGResourceFilter(SVGFilterElement&, Ref<RenderStyle>&&);
+ RenderSVGResourceFilter(SVGFilterElement&, PassRef<RenderStyle>);
virtual ~RenderSVGResourceFilter();
- SVGFilterElement& filterElement() const { return downcast<SVGFilterElement>(RenderSVGResourceContainer::element()); }
+ SVGFilterElement& filterElement() const { return toSVGFilterElement(RenderSVGResourceContainer::element()); }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true) override;
- virtual void removeClientFromCache(RenderElement&, bool markForInvalidation = true) override;
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject&, bool markForInvalidation = true);
virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, unsigned short resourceMode) override;
virtual void postApplyResource(RenderElement&, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*) override;
virtual FloatRect resourceBoundingBox(const RenderObject&) override;
- std::unique_ptr<SVGFilterBuilder> buildPrimitives(SVGFilter&) const;
+ std::unique_ptr<SVGFilterBuilder> buildPrimitives(SVGFilter*);
SVGUnitTypes::SVGUnitType filterUnits() const { return filterElement().filterUnits(); }
SVGUnitTypes::SVGUnitType primitiveUnits() const { return filterElement().primitiveUnits(); }
void primitiveAttributeChanged(RenderObject*, const QualifiedName&);
- virtual RenderSVGResourceType resourceType() const override { return FilterResourceType; }
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
FloatRect drawingRegion(RenderObject*) const;
private:
@@ -91,14 +93,14 @@ private:
virtual const char* renderName() const override { return "RenderSVGResourceFilter"; }
virtual bool isSVGResourceFilter() const override { return true; }
+ bool fitsInMaximumImageSize(const FloatSize&, FloatSize&);
+
HashMap<RenderObject*, std::unique_ptr<FilterData>> m_filter;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGResourceFilter, isSVGResourceFilter())
-SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::RenderSVGResourceFilter)
- static bool isType(const WebCore::RenderObject& renderer) { return renderer.isSVGResourceFilter(); }
- static bool isType(const WebCore::RenderSVGResource& resource) { return resource.resourceType() == WebCore::FilterResourceType; }
-SPECIALIZE_TYPE_TRAITS_END()
+}
-#endif // RenderSVGResourceFilter_h
+#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
index 473645288..24887b702 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.cpp
@@ -26,19 +26,18 @@
*/
#include "config.h"
+
+#if ENABLE(SVG) && ENABLE(FILTERS)
#include "RenderSVGResourceFilterPrimitive.h"
-#include "SVGFEDiffuseLightingElement.h"
-#include "SVGFEFloodElement.h"
#include "SVGFEImage.h"
-#include "SVGFESpecularLightingElement.h"
#include "SVGFilterPrimitiveStandardAttributes.h"
#include "SVGNames.h"
namespace WebCore {
-RenderSVGResourceFilterPrimitive::RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes& filterPrimitiveElement, Ref<RenderStyle>&& style)
- : RenderSVGHiddenContainer(filterPrimitiveElement, WTF::move(style))
+RenderSVGResourceFilterPrimitive::RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes& filterPrimitiveElement, PassRef<RenderStyle> style)
+ : RenderSVGHiddenContainer(filterPrimitiveElement, std::move(style))
{
}
@@ -51,65 +50,69 @@ void RenderSVGResourceFilterPrimitive::styleDidChange(StyleDifference diff, cons
{
RenderSVGHiddenContainer::styleDidChange(diff, oldStyle);
- auto* filter = parent();
+ RenderObject* filter = parent();
if (!filter)
return;
+ ASSERT(filter->isSVGResourceFilter());
if (diff == StyleDifferenceEqual || !oldStyle)
return;
const SVGRenderStyle& newStyle = style().svgStyle();
- if (is<SVGFEFloodElement>(filterPrimitiveElement())) {
+ if (filterPrimitiveElement().hasTagName(SVGNames::feFloodTag)) {
if (newStyle.floodColor() != oldStyle->svgStyle().floodColor())
- downcast<RenderSVGResourceFilter>(*filter).primitiveAttributeChanged(this, SVGNames::flood_colorAttr);
+ toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_colorAttr);
if (newStyle.floodOpacity() != oldStyle->svgStyle().floodOpacity())
- downcast<RenderSVGResourceFilter>(*filter).primitiveAttributeChanged(this, SVGNames::flood_opacityAttr);
- } else if (is<SVGFEDiffuseLightingElement>(filterPrimitiveElement()) || is<SVGFESpecularLightingElement>(filterPrimitiveElement())) {
+ toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::flood_opacityAttr);
+ } else if (filterPrimitiveElement().hasTagName(SVGNames::feDiffuseLightingTag) || filterPrimitiveElement().hasTagName(SVGNames::feSpecularLightingTag)) {
if (newStyle.lightingColor() != oldStyle->svgStyle().lightingColor())
- downcast<RenderSVGResourceFilter>(*filter).primitiveAttributeChanged(this, SVGNames::lighting_colorAttr);
+ toRenderSVGResourceFilter(filter)->primitiveAttributeChanged(this, SVGNames::lighting_colorAttr);
}
}
-FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect& effect)
+FloatRect RenderSVGResourceFilterPrimitive::determineFilterPrimitiveSubregion(FilterEffect* effect)
{
- auto& filter = downcast<SVGFilter>(effect.filter());
+ SVGFilter* filter = toSVGFilter(effect->filter());
+ ASSERT(filter);
// FETile, FETurbulence, FEFlood don't have input effects, take the filter region as unite rect.
FloatRect subregion;
- if (unsigned numberOfInputEffects = effect.inputEffects().size()) {
- subregion = determineFilterPrimitiveSubregion(*effect.inputEffect(0));
+ if (unsigned numberOfInputEffects = effect->inputEffects().size()) {
+ subregion = determineFilterPrimitiveSubregion(effect->inputEffect(0));
for (unsigned i = 1; i < numberOfInputEffects; ++i)
- subregion.unite(determineFilterPrimitiveSubregion(*effect.inputEffect(i)));
+ subregion.unite(determineFilterPrimitiveSubregion(effect->inputEffect(i)));
} else
- subregion = filter.filterRegionInUserSpace();
+ subregion = filter->filterRegionInUserSpace();
// After calling determineFilterPrimitiveSubregion on the target effect, reset the subregion again for <feTile>.
- if (effect.filterEffectType() == FilterEffectTypeTile)
- subregion = filter.filterRegionInUserSpace();
+ if (effect->filterEffectType() == FilterEffectTypeTile)
+ subregion = filter->filterRegionInUserSpace();
- FloatRect effectBoundaries = effect.effectBoundaries();
- if (effect.hasX())
+ FloatRect effectBoundaries = effect->effectBoundaries();
+ if (effect->hasX())
subregion.setX(effectBoundaries.x());
- if (effect.hasY())
+ if (effect->hasY())
subregion.setY(effectBoundaries.y());
- if (effect.hasWidth())
+ if (effect->hasWidth())
subregion.setWidth(effectBoundaries.width());
- if (effect.hasHeight())
+ if (effect->hasHeight())
subregion.setHeight(effectBoundaries.height());
- effect.setFilterPrimitiveSubregion(subregion);
+ effect->setFilterPrimitiveSubregion(subregion);
- FloatRect absoluteSubregion = filter.absoluteTransform().mapRect(subregion);
- FloatSize filterResolution = filter.filterResolution();
+ FloatRect absoluteSubregion = filter->absoluteTransform().mapRect(subregion);
+ FloatSize filterResolution = filter->filterResolution();
absoluteSubregion.scale(filterResolution.width(), filterResolution.height());
// Clip every filter effect to the filter region.
- FloatRect absoluteScaledFilterRegion = filter.filterRegion();
+ FloatRect absoluteScaledFilterRegion = filter->filterRegion();
absoluteScaledFilterRegion.scale(filterResolution.width(), filterResolution.height());
absoluteSubregion.intersect(absoluteScaledFilterRegion);
- effect.setMaxEffectRect(absoluteSubregion);
+ effect->setMaxEffectRect(absoluteSubregion);
return subregion;
}
} // namespace WebCore
+
+#endif // ENABLE(SVG) && ENABLE(FILTERS)
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
index ede92bc0d..f67d61a0f 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceFilterPrimitive.h
@@ -27,6 +27,8 @@
#ifndef RenderSVGResourceFilterPrimitive_h
#define RenderSVGResourceFilterPrimitive_h
+#if ENABLE(SVG) && ENABLE(FILTERS)
+
#include "RenderSVGResourceFilter.h"
namespace WebCore {
@@ -36,15 +38,16 @@ class SVGFilterPrimitiveStandardAttributes;
class RenderSVGResourceFilterPrimitive final : public RenderSVGHiddenContainer {
public:
- RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes&, Ref<RenderStyle>&&);
+ RenderSVGResourceFilterPrimitive(SVGFilterPrimitiveStandardAttributes&, PassRef<RenderStyle>);
SVGFilterPrimitiveStandardAttributes& filterPrimitiveElement() const;
- virtual void styleDidChange(StyleDifference, const RenderStyle*) override;
+ virtual void styleDidChange(StyleDifference, const RenderStyle*);
- virtual const char* renderName() const override { return "RenderSVGResourceFilterPrimitive"; }
+ virtual const char* renderName() const { return "RenderSVGResourceFilterPrimitive"; }
+ virtual bool isSVGResourceFilterPrimitive() const { return true; }
// They depend on the RenderObject argument of RenderSVGResourceFilter::applyResource.
- static FloatRect determineFilterPrimitiveSubregion(FilterEffect&);
+ static FloatRect determineFilterPrimitiveSubregion(FilterEffect*);
inline void primitiveAttributeChanged(const QualifiedName& attribute)
{
@@ -54,10 +57,11 @@ public:
static_cast<RenderSVGResourceFilter*>(filter)->primitiveAttributeChanged(this, attribute);
}
private:
- virtual bool isSVGResourceFilterPrimitive() const override { return true; }
void element() const = delete;
};
} // namespace WebCore
+#endif // ENABLE(SVG) && ENABLE(FILTERS)
+
#endif // RenderSVGResourceFilterPrimitive_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
index 7517e24a2..496a7be59 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.cpp
@@ -21,6 +21,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourceGradient.h"
#include "GradientAttributes.h"
@@ -30,8 +32,8 @@
namespace WebCore {
-RenderSVGResourceGradient::RenderSVGResourceGradient(SVGGradientElement& node, Ref<RenderStyle>&& style)
- : RenderSVGResourceContainer(node, WTF::move(style))
+RenderSVGResourceGradient::RenderSVGResourceGradient(SVGGradientElement& node, PassRef<RenderStyle> style)
+ : RenderSVGResourceContainer(node, std::move(style))
, m_shouldCollectGradientAttributes(true)
#if USE(CG)
, m_savedContext(0)
@@ -46,7 +48,7 @@ void RenderSVGResourceGradient::removeAllClientsFromCache(bool markForInvalidati
markAllClientsForInvalidation(markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceGradient::removeClientFromCache(RenderElement& client, bool markForInvalidation)
+void RenderSVGResourceGradient::removeClientFromCache(RenderObject& client, bool markForInvalidation)
{
m_gradientMap.remove(&client);
markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
@@ -55,14 +57,15 @@ void RenderSVGResourceGradient::removeClientFromCache(RenderElement& client, boo
#if USE(CG)
static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& context, GraphicsContext*& savedContext, std::unique_ptr<ImageBuffer>& imageBuffer, RenderObject* object)
{
- auto* textRootBlock = RenderSVGText::locateRenderSVGTextAncestor(*object);
+ RenderObject* textRootBlock = RenderSVGText::locateRenderSVGTextAncestor(object);
ASSERT(textRootBlock);
- AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*textRootBlock);
- FloatRect repaintRect = textRootBlock->repaintRectInLocalCoordinates();
+ AffineTransform absoluteTransform;
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(textRootBlock, absoluteTransform);
- auto maskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, ColorSpaceDeviceRGB, context->renderingMode());
- if (!maskImage)
+ FloatRect repaintRect = textRootBlock->repaintRectInLocalCoordinates();
+ std::unique_ptr<ImageBuffer> maskImage;
+ if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskImage, ColorSpaceDeviceRGB, Unaccelerated))
return false;
GraphicsContext* maskImageContext = maskImage->context();
@@ -70,19 +73,19 @@ static inline bool createMaskAndSwapContextForTextGradient(GraphicsContext*& con
ASSERT(maskImage);
savedContext = context;
context = maskImageContext;
- imageBuffer = WTF::move(maskImage);
+ imageBuffer = std::move(maskImage);
return true;
}
static inline AffineTransform clipToTextMask(GraphicsContext* context, std::unique_ptr<ImageBuffer>& imageBuffer, FloatRect& targetRect, RenderObject* object, bool boundingBoxMode, const AffineTransform& gradientTransform)
{
- auto* textRootBlock = RenderSVGText::locateRenderSVGTextAncestor(*object);
+ RenderObject* textRootBlock = RenderSVGText::locateRenderSVGTextAncestor(object);
ASSERT(textRootBlock);
- AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(*textRootBlock);
+ AffineTransform absoluteTransform;
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(textRootBlock, absoluteTransform);
targetRect = textRootBlock->repaintRectInLocalCoordinates();
-
SVGRenderingContext::clipToImageBuffer(context, absoluteTransform, targetRect, imageBuffer, false);
AffineTransform matrix;
@@ -119,9 +122,9 @@ bool RenderSVGResourceGradient::applyResource(RenderElement& renderer, const Ren
if (gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
return false;
- auto& gradientData = m_gradientMap.add(&renderer, nullptr).iterator->value;
+ OwnPtr<GradientData>& gradientData = m_gradientMap.add(&renderer, nullptr).iterator->value;
if (!gradientData)
- gradientData = std::make_unique<GradientData>();
+ gradientData = adoptPtr(new GradientData);
bool isPaintingText = resourceMode & ApplyToTextMode;
@@ -149,7 +152,7 @@ bool RenderSVGResourceGradient::applyResource(RenderElement& renderer, const Ren
// Depending on font scaling factor, we may need to rescale the gradient here since
// text painting removes the scale factor from the context.
AffineTransform additionalTextTransform;
- if (shouldTransformOnTextPainting(renderer, additionalTextTransform))
+ if (shouldTransformOnTextPainting(&renderer, additionalTextTransform))
gradientData->userspaceTransform *= additionalTextTransform;
}
gradientData->gradient->setGradientSpaceTransform(gradientData->userspaceTransform);
@@ -176,13 +179,13 @@ bool RenderSVGResourceGradient::applyResource(RenderElement& renderer, const Ren
if (resourceMode & ApplyToFillMode) {
context->setAlpha(svgStyle.fillOpacity());
- context->setFillGradient(*gradientData->gradient);
+ context->setFillGradient(gradientData->gradient);
context->setFillRule(svgStyle.fillRule());
} else if (resourceMode & ApplyToStrokeMode) {
if (svgStyle.vectorEffect() == VE_NON_SCALING_STROKE)
gradientData->gradient->setGradientSpaceTransform(transformOnNonScalingStroke(&renderer, gradientData->userspaceTransform));
context->setAlpha(svgStyle.strokeOpacity());
- context->setStrokeGradient(*gradientData->gradient);
+ context->setStrokeGradient(gradientData->gradient);
SVGRenderSupport::applyStrokeStyleToContext(context, style, renderer);
}
@@ -208,7 +211,7 @@ void RenderSVGResourceGradient::postApplyResource(RenderElement& renderer, Graph
FloatRect targetRect;
gradientData->gradient->setGradientSpaceTransform(clipToTextMask(context, m_imageBuffer, targetRect, &renderer, gradientUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX, gradientTransform));
- context->setFillGradient(*gradientData->gradient);
+ context->setFillGradient(gradientData->gradient);
context->fillRect(targetRect);
m_imageBuffer.reset();
@@ -260,3 +263,5 @@ GradientSpreadMethod RenderSVGResourceGradient::platformSpreadMethodFromSVGType(
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h
index 78da73adc..c37fc7a5c 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceGradient.h
@@ -22,11 +22,12 @@
#ifndef RenderSVGResourceGradient_h
#define RenderSVGResourceGradient_h
+#if ENABLE(SVG)
#include "Gradient.h"
#include "ImageBuffer.h"
#include "RenderSVGResourceContainer.h"
#include "SVGGradientElement.h"
-#include <memory>
+
#include <wtf/HashMap.h>
namespace WebCore {
@@ -45,14 +46,14 @@ public:
SVGGradientElement& gradientElement() const { return static_cast<SVGGradientElement&>(RenderSVGResourceContainer::element()); }
virtual void removeAllClientsFromCache(bool markForInvalidation = true) override final;
- virtual void removeClientFromCache(RenderElement&, bool markForInvalidation = true) override final;
+ virtual void removeClientFromCache(RenderObject&, bool markForInvalidation = true) override final;
virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, unsigned short resourceMode) override final;
virtual void postApplyResource(RenderElement&, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*) override final;
virtual FloatRect resourceBoundingBox(const RenderObject&) override final { return FloatRect(); }
protected:
- RenderSVGResourceGradient(SVGGradientElement&, Ref<RenderStyle>&&);
+ RenderSVGResourceGradient(SVGGradientElement&, PassRef<RenderStyle>);
void element() const = delete;
@@ -67,7 +68,7 @@ protected:
private:
bool m_shouldCollectGradientAttributes : 1;
- HashMap<RenderObject*, std::unique_ptr<GradientData>> m_gradientMap;
+ HashMap<RenderObject*, OwnPtr<GradientData>> m_gradientMap;
#if USE(CG)
GraphicsContext* m_savedContext;
@@ -78,3 +79,4 @@ private:
}
#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp
index 7d57c3fff..c928e5b86 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.cpp
@@ -19,13 +19,17 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourceLinearGradient.h"
namespace WebCore {
-RenderSVGResourceLinearGradient::RenderSVGResourceLinearGradient(SVGLinearGradientElement& element, Ref<RenderStyle>&& style)
- : RenderSVGResourceGradient(element, WTF::move(style))
+RenderSVGResourceType RenderSVGResourceLinearGradient::s_resourceType = LinearGradientResourceType;
+
+RenderSVGResourceLinearGradient::RenderSVGResourceLinearGradient(SVGLinearGradientElement& element, PassRef<RenderStyle> style)
+ : RenderSVGResourceGradient(element, std::move(style))
{
}
@@ -57,3 +61,5 @@ void RenderSVGResourceLinearGradient::buildGradient(GradientData* gradientData)
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.h b/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.h
index 96348283f..eaec65974 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceLinearGradient.h
@@ -21,6 +21,7 @@
#ifndef RenderSVGResourceLinearGradient_h
#define RenderSVGResourceLinearGradient_h
+#if ENABLE(SVG)
#include "LinearGradientAttributes.h"
#include "RenderSVGResourceGradient.h"
#include "SVGLinearGradientElement.h"
@@ -29,17 +30,18 @@ namespace WebCore {
class RenderSVGResourceLinearGradient final : public RenderSVGResourceGradient {
public:
- RenderSVGResourceLinearGradient(SVGLinearGradientElement&, Ref<RenderStyle>&&);
+ RenderSVGResourceLinearGradient(SVGLinearGradientElement&, PassRef<RenderStyle>);
virtual ~RenderSVGResourceLinearGradient();
- SVGLinearGradientElement& linearGradientElement() const { return downcast<SVGLinearGradientElement>(RenderSVGResourceGradient::gradientElement()); }
+ SVGLinearGradientElement& linearGradientElement() const { return toSVGLinearGradientElement(RenderSVGResourceGradient::gradientElement()); }
- virtual RenderSVGResourceType resourceType() const override { return LinearGradientResourceType; }
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
- virtual SVGUnitTypes::SVGUnitType gradientUnits() const override { return m_attributes.gradientUnits(); }
- virtual void calculateGradientTransform(AffineTransform& transform) override { transform = m_attributes.gradientTransform(); }
+ virtual SVGUnitTypes::SVGUnitType gradientUnits() const { return m_attributes.gradientUnits(); }
+ virtual void calculateGradientTransform(AffineTransform& transform) { transform = m_attributes.gradientTransform(); }
virtual bool collectGradientAttributes() override;
- virtual void buildGradient(GradientData*) const override;
+ virtual void buildGradient(GradientData*) const;
FloatPoint startPoint(const LinearGradientAttributes&) const;
FloatPoint endPoint(const LinearGradientAttributes&) const;
@@ -54,6 +56,5 @@ private:
}
-SPECIALIZE_TYPE_TRAITS_RENDER_SVG_RESOURCE(RenderSVGResourceLinearGradient, LinearGradientResourceType)
-
+#endif
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
index 8c3bdb347..3ea195056 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.cpp
@@ -20,6 +20,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourceMarker.h"
#include "GraphicsContext.h"
@@ -28,8 +30,10 @@
namespace WebCore {
-RenderSVGResourceMarker::RenderSVGResourceMarker(SVGMarkerElement& element, Ref<RenderStyle>&& style)
- : RenderSVGResourceContainer(element, WTF::move(style))
+RenderSVGResourceType RenderSVGResourceMarker::s_resourceType = MarkerResourceType;
+
+RenderSVGResourceMarker::RenderSVGResourceMarker(SVGMarkerElement& element, PassRef<RenderStyle> style)
+ : RenderSVGResourceContainer(element, std::move(style))
{
}
@@ -55,7 +59,7 @@ void RenderSVGResourceMarker::removeAllClientsFromCache(bool markForInvalidation
markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceMarker::removeClientFromCache(RenderElement& client, bool markForInvalidation)
+void RenderSVGResourceMarker::removeClientFromCache(RenderObject& client, bool markForInvalidation)
{
markClientForInvalidation(client, markForInvalidation ? BoundariesInvalidation : ParentOnlyInvalidation);
}
@@ -153,3 +157,5 @@ void RenderSVGResourceMarker::calcViewport()
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.h b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.h
index 8b8468f78..442cc60d7 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMarker.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMarker.h
@@ -20,6 +20,7 @@
#ifndef RenderSVGResourceMarker_h
#define RenderSVGResourceMarker_h
+#if ENABLE(SVG)
#include "RenderSVGResourceContainer.h"
#include "SVGMarkerElement.h"
@@ -32,24 +33,24 @@ class RenderObject;
class RenderSVGResourceMarker final : public RenderSVGResourceContainer {
public:
- RenderSVGResourceMarker(SVGMarkerElement&, Ref<RenderStyle>&&);
+ RenderSVGResourceMarker(SVGMarkerElement&, PassRef<RenderStyle>);
virtual ~RenderSVGResourceMarker();
- SVGMarkerElement& markerElement() const { return downcast<SVGMarkerElement>(RenderSVGResourceContainer::element()); }
+ SVGMarkerElement& markerElement() const { return toSVGMarkerElement(RenderSVGResourceContainer::element()); }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true) override;
- virtual void removeClientFromCache(RenderElement&, bool markForInvalidation = true) override;
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject&, bool markForInvalidation = true);
void draw(PaintInfo&, const AffineTransform&);
// Calculates marker boundaries, mapped to the target element's coordinate space
FloatRect markerBoundaries(const AffineTransform& markerTransformation) const;
- virtual void applyViewportClip(PaintInfo&) override;
- virtual void layout() override;
- virtual void calcViewport() override;
+ virtual void applyViewportClip(PaintInfo&);
+ virtual void layout();
+ virtual void calcViewport();
- virtual const AffineTransform& localToParentTransform() const override;
+ virtual const AffineTransform& localToParentTransform() const;
AffineTransform markerTransformation(const FloatPoint& origin, float angle, float strokeWidth) const;
virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, unsigned short) override { return false; }
@@ -59,7 +60,8 @@ public:
float angle() const;
SVGMarkerUnitsType markerUnits() const { return markerElement().markerUnits(); }
- virtual RenderSVGResourceType resourceType() const override { return MarkerResourceType; }
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
private:
void element() const = delete;
@@ -77,7 +79,6 @@ private:
};
}
-
-SPECIALIZE_TYPE_TRAITS_RENDER_SVG_RESOURCE(RenderSVGResourceMarker, MarkerResourceType)
+#endif
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
index 0032e051a..e02fab47b 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMasker.cpp
@@ -18,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourceMasker.h"
#include "Element.h"
@@ -29,8 +31,10 @@
namespace WebCore {
-RenderSVGResourceMasker::RenderSVGResourceMasker(SVGMaskElement& element, Ref<RenderStyle>&& style)
- : RenderSVGResourceContainer(element, WTF::move(style))
+RenderSVGResourceType RenderSVGResourceMasker::s_resourceType = MaskerResourceType;
+
+RenderSVGResourceMasker::RenderSVGResourceMasker(SVGMaskElement& element, PassRef<RenderStyle> style)
+ : RenderSVGResourceContainer(element, std::move(style))
{
}
@@ -46,7 +50,7 @@ void RenderSVGResourceMasker::removeAllClientsFromCache(bool markForInvalidation
markAllClientsForInvalidation(markForInvalidation ? LayoutAndBoundariesInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourceMasker::removeClientFromCache(RenderElement& client, bool markForInvalidation)
+void RenderSVGResourceMasker::removeClientFromCache(RenderObject& client, bool markForInvalidation)
{
m_masker.remove(&client);
@@ -63,19 +67,21 @@ bool RenderSVGResourceMasker::applyResource(RenderElement& renderer, const Rende
m_masker.set(&renderer, std::make_unique<MaskerData>());
MaskerData* maskerData = m_masker.get(&renderer);
- AffineTransform absoluteTransform = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
+
+ AffineTransform absoluteTransform;
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(&renderer, absoluteTransform);
+
FloatRect repaintRect = renderer.repaintRectInLocalCoordinates();
if (!maskerData->maskImage && !repaintRect.isEmpty()) {
const SVGRenderStyle& svgStyle = style().svgStyle();
ColorSpace colorSpace = svgStyle.colorInterpolation() == CI_LINEARRGB ? ColorSpaceLinearRGB : ColorSpaceDeviceRGB;
- // FIXME (149470): This image buffer should not be unconditionally unaccelerated. Making it match the context breaks alpha masking, though.
- maskerData->maskImage = SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, colorSpace, Unaccelerated);
- if (!maskerData->maskImage)
+ if (!SVGRenderingContext::createImageBuffer(repaintRect, absoluteTransform, maskerData->maskImage, colorSpace, Unaccelerated))
return false;
- if (!drawContentIntoMaskImage(maskerData, colorSpace, &renderer))
+ if (!drawContentIntoMaskImage(maskerData, colorSpace, &renderer)) {
maskerData->maskImage.reset();
+ }
}
if (!maskerData->maskImage)
@@ -163,3 +169,5 @@ FloatRect RenderSVGResourceMasker::resourceBoundingBox(const RenderObject& objec
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceMasker.h b/Source/WebCore/rendering/svg/RenderSVGResourceMasker.h
index bef2985c3..ecae4332e 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceMasker.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceMasker.h
@@ -20,6 +20,7 @@
#ifndef RenderSVGResourceMasker_h
#define RenderSVGResourceMasker_h
+#if ENABLE(SVG)
#include "GraphicsContext.h"
#include "ImageBuffer.h"
#include "IntSize.h"
@@ -37,20 +38,21 @@ struct MaskerData {
class RenderSVGResourceMasker final : public RenderSVGResourceContainer {
public:
- RenderSVGResourceMasker(SVGMaskElement&, Ref<RenderStyle>&&);
+ RenderSVGResourceMasker(SVGMaskElement&, PassRef<RenderStyle>);
virtual ~RenderSVGResourceMasker();
- SVGMaskElement& maskElement() const { return downcast<SVGMaskElement>(RenderSVGResourceContainer::element()); }
+ SVGMaskElement& maskElement() const { return toSVGMaskElement(RenderSVGResourceContainer::element()); }
- virtual void removeAllClientsFromCache(bool markForInvalidation = true) override;
- virtual void removeClientFromCache(RenderElement&, bool markForInvalidation = true) override;
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject&, bool markForInvalidation = true);
virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, unsigned short resourceMode) override;
virtual FloatRect resourceBoundingBox(const RenderObject&) override;
SVGUnitTypes::SVGUnitType maskUnits() const { return maskElement().maskUnits(); }
SVGUnitTypes::SVGUnitType maskContentUnits() const { return maskElement().maskContentUnits(); }
- virtual RenderSVGResourceType resourceType() const override { return MaskerResourceType; }
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
private:
void element() const = delete;
@@ -66,6 +68,5 @@ private:
}
-SPECIALIZE_TYPE_TRAITS_RENDER_SVG_RESOURCE(RenderSVGResourceMasker, MaskerResourceType)
-
+#endif
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
index 60dc18d0a..4ed8e6a98 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.cpp
@@ -19,6 +19,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourcePattern.h"
#include "ElementIterator.h"
@@ -30,15 +32,17 @@
namespace WebCore {
-RenderSVGResourcePattern::RenderSVGResourcePattern(SVGPatternElement& element, Ref<RenderStyle>&& style)
- : RenderSVGResourceContainer(element, WTF::move(style))
+RenderSVGResourceType RenderSVGResourcePattern::s_resourceType = PatternResourceType;
+
+RenderSVGResourcePattern::RenderSVGResourcePattern(SVGPatternElement& element, PassRef<RenderStyle> style)
+ : RenderSVGResourceContainer(element, std::move(style))
, m_shouldCollectPatternAttributes(true)
{
}
SVGPatternElement& RenderSVGResourcePattern::patternElement() const
{
- return downcast<SVGPatternElement>(RenderSVGResourceContainer::element());
+ return toSVGPatternElement(RenderSVGResourceContainer::element());
}
void RenderSVGResourcePattern::removeAllClientsFromCache(bool markForInvalidation)
@@ -48,15 +52,15 @@ void RenderSVGResourcePattern::removeAllClientsFromCache(bool markForInvalidatio
markAllClientsForInvalidation(markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
}
-void RenderSVGResourcePattern::removeClientFromCache(RenderElement& client, bool markForInvalidation)
+void RenderSVGResourcePattern::removeClientFromCache(RenderObject& client, bool markForInvalidation)
{
m_patternMap.remove(&client);
markClientForInvalidation(client, markForInvalidation ? RepaintInvalidation : ParentOnlyInvalidation);
}
-PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, unsigned short resourceMode, GraphicsContext& context)
+PatternData* RenderSVGResourcePattern::buildPattern(RenderObject* object, unsigned short resourceMode)
{
- PatternData* currentData = m_patternMap.get(&renderer);
+ PatternData* currentData = m_patternMap.get(object);
if (currentData && currentData->pattern)
return currentData;
@@ -70,19 +74,20 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, uns
// If we couldn't determine the pattern content element root, stop here.
if (!m_attributes.patternContentElement())
- return nullptr;
+ return 0;
// An empty viewBox disables rendering.
if (m_attributes.hasViewBox() && m_attributes.viewBox().isEmpty())
- return nullptr;
+ return 0;
// Compute all necessary transformations to build the tile image & the pattern.
FloatRect tileBoundaries;
AffineTransform tileImageTransform;
- if (!buildTileImageTransform(renderer, m_attributes, patternElement(), tileBoundaries, tileImageTransform))
- return nullptr;
+ if (!buildTileImageTransform(object, m_attributes, patternElement(), tileBoundaries, tileImageTransform))
+ return 0;
- AffineTransform absoluteTransformIgnoringRotation = SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(renderer);
+ AffineTransform absoluteTransformIgnoringRotation;
+ SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(object, absoluteTransformIgnoringRotation);
// Ignore 2D rotation, as it doesn't affect the size of the tile.
SVGRenderingContext::clear2DRotation(absoluteTransformIgnoringRotation);
@@ -94,16 +99,16 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, uns
static_cast<float>(m_attributes.patternTransform().yScale()));
// Build tile image.
- auto tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries, context.renderingMode());
+ std::unique_ptr<ImageBuffer> tileImage = createTileImage(m_attributes, tileBoundaries, absoluteTileBoundaries, tileImageTransform, clampedAbsoluteTileBoundaries);
if (!tileImage)
- return nullptr;
+ return 0;
RefPtr<Image> copiedImage = tileImage->copyImage(CopyBackingStore);
if (!copiedImage)
- return nullptr;
+ return 0;
// Build pattern.
- auto patternData = std::make_unique<PatternData>();
+ OwnPtr<PatternData> patternData = adoptPtr(new PatternData);
patternData->pattern = Pattern::create(copiedImage, true, true);
// Compute pattern space transformation.
@@ -118,7 +123,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, uns
// Account for text drawing resetting the context to non-scaled, see SVGInlineTextBox::paintTextWithShadows.
if (resourceMode & ApplyToTextMode) {
AffineTransform additionalTextTransformation;
- if (shouldTransformOnTextPainting(renderer, additionalTextTransformation))
+ if (shouldTransformOnTextPainting(object, additionalTextTransformation))
patternData->transform *= additionalTextTransformation;
}
patternData->pattern->setPatternSpaceTransform(patternData->transform);
@@ -126,7 +131,7 @@ PatternData* RenderSVGResourcePattern::buildPattern(RenderElement& renderer, uns
// Various calls above may trigger invalidations in some fringe cases (ImageBuffer allocation
// failures in the SVG image cache for example). To avoid having our PatternData deleted by
// removeAllClientsFromCache(), we only make it visible in the cache at the very end.
- return m_patternMap.set(&renderer, WTF::move(patternData)).iterator->value.get();
+ return m_patternMap.set(object, patternData.release()).iterator->value.get();
}
bool RenderSVGResourcePattern::applyResource(RenderElement& renderer, const RenderStyle& style, GraphicsContext*& context, unsigned short resourceMode)
@@ -140,7 +145,7 @@ bool RenderSVGResourcePattern::applyResource(RenderElement& renderer, const Rend
if (m_attributes.patternUnits() == SVGUnitTypes::SVG_UNIT_TYPE_OBJECTBOUNDINGBOX && objectBoundingBox.isEmpty())
return false;
- PatternData* patternData = buildPattern(renderer, resourceMode, *context);
+ PatternData* patternData = buildPattern(&renderer, resourceMode);
if (!patternData)
return false;
@@ -151,13 +156,13 @@ bool RenderSVGResourcePattern::applyResource(RenderElement& renderer, const Rend
if (resourceMode & ApplyToFillMode) {
context->setAlpha(svgStyle.fillOpacity());
- context->setFillPattern(*patternData->pattern);
+ context->setFillPattern(patternData->pattern);
context->setFillRule(svgStyle.fillRule());
} else if (resourceMode & ApplyToStrokeMode) {
if (svgStyle.vectorEffect() == VE_NON_SCALING_STROKE)
patternData->pattern->setPatternSpaceTransform(transformOnNonScalingStroke(&renderer, patternData->transform));
context->setAlpha(svgStyle.strokeOpacity());
- context->setStrokePattern(*patternData->pattern);
+ context->setStrokePattern(patternData->pattern);
SVGRenderSupport::applyStrokeStyleToContext(context, style, renderer);
}
@@ -208,13 +213,15 @@ static inline FloatRect calculatePatternBoundaries(const PatternAttributes& attr
return SVGLengthContext::resolveRectangle(&patternElement, attributes.patternUnits(), objectBoundingBox, attributes.x(), attributes.y(), attributes.width(), attributes.height());
}
-bool RenderSVGResourcePattern::buildTileImageTransform(RenderElement& renderer,
+bool RenderSVGResourcePattern::buildTileImageTransform(RenderObject* renderer,
const PatternAttributes& attributes,
const SVGPatternElement& patternElement,
FloatRect& patternBoundaries,
AffineTransform& tileImageTransform) const
{
- FloatRect objectBoundingBox = renderer.objectBoundingBox();
+ ASSERT(renderer);
+
+ FloatRect objectBoundingBox = renderer->objectBoundingBox();
patternBoundaries = calculatePatternBoundaries(attributes, objectBoundingBox, patternElement);
if (patternBoundaries.width() <= 0 || patternBoundaries.height() <= 0)
return false;
@@ -230,11 +237,13 @@ bool RenderSVGResourcePattern::buildTileImageTransform(RenderElement& renderer,
return true;
}
-std::unique_ptr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries, RenderingMode renderingMode) const
+std::unique_ptr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const PatternAttributes& attributes, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries) const
{
- clampedAbsoluteTileBoundaries = ImageBuffer::clampedRect(absoluteTileBoundaries);
- auto tileImage = SVGRenderingContext::createImageBuffer(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, ColorSpaceDeviceRGB, renderingMode);
- if (!tileImage)
+ clampedAbsoluteTileBoundaries = SVGRenderingContext::clampedAbsoluteTargetRect(absoluteTileBoundaries);
+
+ std::unique_ptr<ImageBuffer> tileImage;
+
+ if (!SVGRenderingContext::createImageBufferForPattern(absoluteTileBoundaries, clampedAbsoluteTileBoundaries, tileImage, ColorSpaceDeviceRGB, Unaccelerated))
return nullptr;
GraphicsContext* tileImageContext = tileImage->context();
@@ -265,3 +274,5 @@ std::unique_ptr<ImageBuffer> RenderSVGResourcePattern::createTileImage(const Pat
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h
index f0cac4652..9eebeefa4 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourcePattern.h
@@ -21,13 +21,14 @@
#ifndef RenderSVGResourcePattern_h
#define RenderSVGResourcePattern_h
+#if ENABLE(SVG)
#include "ImageBuffer.h"
#include "Pattern.h"
#include "PatternAttributes.h"
#include "RenderSVGResourceContainer.h"
#include "SVGPatternElement.h"
#include "SVGUnitTypes.h"
-#include <memory>
+
#include <wtf/HashMap.h>
namespace WebCore {
@@ -41,35 +42,35 @@ public:
class RenderSVGResourcePattern final : public RenderSVGResourceContainer {
public:
- RenderSVGResourcePattern(SVGPatternElement&, Ref<RenderStyle>&&);
+ RenderSVGResourcePattern(SVGPatternElement&, PassRef<RenderStyle>);
SVGPatternElement& patternElement() const;
- virtual void removeAllClientsFromCache(bool markForInvalidation = true) override;
- virtual void removeClientFromCache(RenderElement&, bool markForInvalidation = true) override;
+ virtual void removeAllClientsFromCache(bool markForInvalidation = true);
+ virtual void removeClientFromCache(RenderObject&, bool markForInvalidation = true);
virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, unsigned short resourceMode) override;
virtual void postApplyResource(RenderElement&, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*) override;
virtual FloatRect resourceBoundingBox(const RenderObject&) override { return FloatRect(); }
- virtual RenderSVGResourceType resourceType() const override { return PatternResourceType; }
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
private:
void element() const = delete;
virtual const char* renderName() const override { return "RenderSVGResourcePattern"; }
- bool buildTileImageTransform(RenderElement&, const PatternAttributes&, const SVGPatternElement&, FloatRect& patternBoundaries, AffineTransform& tileImageTransform) const;
+ bool buildTileImageTransform(RenderObject*, const PatternAttributes&, const SVGPatternElement&, FloatRect& patternBoundaries, AffineTransform& tileImageTransform) const;
- std::unique_ptr<ImageBuffer> createTileImage(const PatternAttributes&, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries, RenderingMode) const;
+ std::unique_ptr<ImageBuffer> createTileImage(const PatternAttributes&, const FloatRect& tileBoundaries, const FloatRect& absoluteTileBoundaries, const AffineTransform& tileImageTransform, FloatRect& clampedAbsoluteTileBoundaries) const;
- PatternData* buildPattern(RenderElement&, unsigned short resourceMode, GraphicsContext&);
+ PatternData* buildPattern(RenderObject*, unsigned short resourceMode);
bool m_shouldCollectPatternAttributes : 1;
PatternAttributes m_attributes;
- HashMap<RenderElement*, std::unique_ptr<PatternData>> m_patternMap;
+ HashMap<RenderObject*, OwnPtr<PatternData>> m_patternMap;
};
}
-SPECIALIZE_TYPE_TRAITS_RENDER_SVG_RESOURCE(RenderSVGResourcePattern, PatternResourceType)
-
+#endif
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp
index 946f0edc2..1f5b8d163 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.cpp
@@ -20,12 +20,17 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourceRadialGradient.h"
+
namespace WebCore {
-RenderSVGResourceRadialGradient::RenderSVGResourceRadialGradient(SVGRadialGradientElement& element, Ref<RenderStyle>&& style)
- : RenderSVGResourceGradient(element, WTF::move(style))
+RenderSVGResourceType RenderSVGResourceRadialGradient::s_resourceType = RadialGradientResourceType;
+
+RenderSVGResourceRadialGradient::RenderSVGResourceRadialGradient(SVGRadialGradientElement& element, PassRef<RenderStyle> style)
+ : RenderSVGResourceGradient(element, std::move(style))
{
}
@@ -72,3 +77,5 @@ void RenderSVGResourceRadialGradient::buildGradient(GradientData* gradientData)
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h b/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h
index d1aa57c4f..f1e61a4ee 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceRadialGradient.h
@@ -21,6 +21,7 @@
#ifndef RenderSVGResourceRadialGradient_h
#define RenderSVGResourceRadialGradient_h
+#if ENABLE(SVG)
#include "RadialGradientAttributes.h"
#include "RenderSVGResourceGradient.h"
#include "SVGRadialGradientElement.h"
@@ -31,16 +32,17 @@ class SVGRadialGradientElement;
class RenderSVGResourceRadialGradient final : public RenderSVGResourceGradient {
public:
- RenderSVGResourceRadialGradient(SVGRadialGradientElement&, Ref<RenderStyle>&&);
+ RenderSVGResourceRadialGradient(SVGRadialGradientElement&, PassRef<RenderStyle>);
virtual ~RenderSVGResourceRadialGradient();
- SVGRadialGradientElement& radialGradientElement() const { return downcast<SVGRadialGradientElement>(RenderSVGResourceGradient::gradientElement()); }
+ SVGRadialGradientElement& radialGradientElement() const { return toSVGRadialGradientElement(RenderSVGResourceGradient::gradientElement()); }
- virtual RenderSVGResourceType resourceType() const override { return RadialGradientResourceType; }
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
- virtual SVGUnitTypes::SVGUnitType gradientUnits() const override { return m_attributes.gradientUnits(); }
- virtual void calculateGradientTransform(AffineTransform& transform) override { transform = m_attributes.gradientTransform(); }
- virtual void buildGradient(GradientData*) const override;
+ virtual SVGUnitTypes::SVGUnitType gradientUnits() const { return m_attributes.gradientUnits(); }
+ virtual void calculateGradientTransform(AffineTransform& transform) { transform = m_attributes.gradientTransform(); }
+ virtual void buildGradient(GradientData*) const;
FloatPoint centerPoint(const RadialGradientAttributes&) const;
FloatPoint focalPoint(const RadialGradientAttributes&) const;
@@ -58,6 +60,5 @@ private:
}
-SPECIALIZE_TYPE_TRAITS_RENDER_SVG_RESOURCE(RenderSVGResourceRadialGradient, RadialGradientResourceType)
-
+#endif
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp b/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
index f501abf44..1d9ada519 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.cpp
@@ -18,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGResourceSolidColor.h"
#include "Frame.h"
@@ -28,6 +30,8 @@
namespace WebCore {
+RenderSVGResourceType RenderSVGResourceSolidColor::s_resourceType = SolidColorResourceType;
+
RenderSVGResourceSolidColor::RenderSVGResourceSolidColor()
{
}
@@ -92,3 +96,5 @@ void RenderSVGResourceSolidColor::postApplyResource(RenderElement&, GraphicsCont
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h b/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h
index 4bad5b522..80eb45df6 100644
--- a/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h
+++ b/Source/WebCore/rendering/svg/RenderSVGResourceSolidColor.h
@@ -20,25 +20,26 @@
#ifndef RenderSVGResourceSolidColor_h
#define RenderSVGResourceSolidColor_h
+#if ENABLE(SVG)
#include "Color.h"
#include "RenderSVGResource.h"
namespace WebCore {
-class RenderSVGResourceSolidColor final : public RenderSVGResource {
- WTF_MAKE_FAST_ALLOCATED;
+class RenderSVGResourceSolidColor : public RenderSVGResource {
public:
RenderSVGResourceSolidColor();
virtual ~RenderSVGResourceSolidColor();
- virtual void removeAllClientsFromCache(bool = true) override { }
- virtual void removeClientFromCache(RenderElement&, bool = true) override { }
+ virtual void removeAllClientsFromCache(bool = true) { }
+ virtual void removeClientFromCache(RenderObject&, bool = true) { }
virtual bool applyResource(RenderElement&, const RenderStyle&, GraphicsContext*&, unsigned short resourceMode) override;
virtual void postApplyResource(RenderElement&, GraphicsContext*&, unsigned short resourceMode, const Path*, const RenderSVGShape*) override;
virtual FloatRect resourceBoundingBox(const RenderObject&) override { return FloatRect(); }
- virtual RenderSVGResourceType resourceType() const override { return SolidColorResourceType; }
+ virtual RenderSVGResourceType resourceType() const { return s_resourceType; }
+ static RenderSVGResourceType s_resourceType;
const Color& color() const { return m_color; }
void setColor(const Color& color) { m_color = color; }
@@ -49,6 +50,5 @@ private:
}
-SPECIALIZE_TYPE_TRAITS_RENDER_SVG_RESOURCE(RenderSVGResourceSolidColor, SolidColorResourceType)
-
+#endif
#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
index 64bea0473..6de3aa3c6 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.cpp
@@ -22,6 +22,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGRoot.h"
#include "Chrome.h"
@@ -32,11 +34,6 @@
#include "LayoutRepainter.h"
#include "Page.h"
#include "RenderIterator.h"
-#include "RenderLayer.h"
-#include "RenderNamedFlowFragment.h"
-#include "RenderSVGResource.h"
-#include "RenderSVGResourceContainer.h"
-#include "RenderSVGResourceFilter.h"
#include "RenderView.h"
#include "SVGImage.h"
#include "SVGLength.h"
@@ -48,15 +45,18 @@
#include "TransformState.h"
#include <wtf/StackStats.h>
+#if ENABLE(FILTERS)
+#include "RenderSVGResourceFilter.h"
+#endif
+
namespace WebCore {
-RenderSVGRoot::RenderSVGRoot(SVGSVGElement& element, Ref<RenderStyle>&& style)
- : RenderReplaced(element, WTF::move(style))
+RenderSVGRoot::RenderSVGRoot(SVGSVGElement& element, PassRef<RenderStyle> style)
+ : RenderReplaced(element, std::move(style))
, m_objectBoundingBoxValid(false)
, m_isLayoutSizeChanged(false)
, m_needsBoundariesOrTransformUpdate(true)
, m_hasSVGShadow(false)
- , m_hasBoxDecorations(false)
{
}
@@ -66,13 +66,20 @@ RenderSVGRoot::~RenderSVGRoot()
SVGSVGElement& RenderSVGRoot::svgSVGElement() const
{
- return downcast<SVGSVGElement>(nodeForNonAnonymous());
+ return toSVGSVGElement(nodeForNonAnonymous());
}
-void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const
+void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const
{
// Spec: http://www.w3.org/TR/SVG/coords.html#IntrinsicSizing
// SVG needs to specify how to calculate some intrinsic sizing properties to enable inclusion within other languages.
+ // The intrinsic width and height of the viewport of SVG content must be determined from the ‘width’ and ‘height’ attributes.
+ // If either of these are not specified, a value of '100%' must be assumed. Note: the ‘width’ and ‘height’ attributes are not
+ // the same as the CSS width and height properties. Specifically, percentage values do not provide an intrinsic width or height,
+ // and do not indicate a percentage of the containing block. Rather, once the viewport is established, they indicate the portion
+ // of the viewport that is actually covered by image data.
+ Length intrinsicWidthAttribute = svgSVGElement().intrinsicWidth(SVGSVGElement::IgnoreCSSProperties);
+ Length intrinsicHeightAttribute = svgSVGElement().intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);
// The intrinsic aspect ratio of the viewport of SVG content is necessary for example, when including SVG from an ‘object’
// element in HTML styled with CSS. It is possible (indeed, common) for an SVG graphic to have an intrinsic aspect ratio but
@@ -81,22 +88,33 @@ void RenderSVGRoot::computeIntrinsicRatioInformation(FloatSize& intrinsicSize, d
// - If the ‘width’ and ‘height’ of the rootmost ‘svg’ element are both specified with unit identifiers (in, mm, cm, pt, pc,
// px, em, ex) or in user units, then the aspect ratio is calculated from the ‘width’ and ‘height’ attributes after
// resolving both values to user units.
- intrinsicSize.setWidth(floatValueForLength(svgSVGElement().intrinsicWidth(), 0));
- intrinsicSize.setHeight(floatValueForLength(svgSVGElement().intrinsicHeight(), 0));
-
+ if (intrinsicWidthAttribute.isFixed() || intrinsicHeightAttribute.isFixed()) {
+ if (intrinsicWidthAttribute.isFixed())
+ intrinsicSize.setWidth(floatValueForLength(intrinsicWidthAttribute, 0));
+ if (intrinsicHeightAttribute.isFixed())
+ intrinsicSize.setHeight(floatValueForLength(intrinsicHeightAttribute, 0));
+ if (!intrinsicSize.isEmpty())
+ intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height());
+ return;
+ }
- if (!intrinsicSize.isEmpty())
+ // - If either/both of the ‘width’ and ‘height’ of the rootmost ‘svg’ element are in percentage units (or omitted), the
+ // aspect ratio is calculated from the width and height values of the ‘viewBox’ specified for the current SVG document
+ // fragment. If the ‘viewBox’ is not correctly specified, or set to 'none', the intrinsic aspect ratio cannot be
+ // calculated and is considered unspecified.
+ intrinsicSize = svgSVGElement().viewBox().size();
+ if (!intrinsicSize.isEmpty()) {
+ // The viewBox can only yield an intrinsic ratio, not an intrinsic size.
intrinsicRatio = intrinsicSize.width() / static_cast<double>(intrinsicSize.height());
- else {
- // - If either/both of the ‘width’ and ‘height’ of the rootmost ‘svg’ element are in percentage units (or omitted), the
- // aspect ratio is calculated from the width and height values of the ‘viewBox’ specified for the current SVG document
- // fragment. If the ‘viewBox’ is not correctly specified, or set to 'none', the intrinsic aspect ratio cannot be
- // calculated and is considered unspecified.
- FloatSize viewBoxSize = svgSVGElement().viewBox().size();
- if (!viewBoxSize.isEmpty()) {
- // The viewBox can only yield an intrinsic ratio, not an intrinsic size.
- intrinsicRatio = viewBoxSize.width() / static_cast<double>(viewBoxSize.height());
- }
+ intrinsicSize = FloatSize();
+ return;
+ }
+
+ // If our intrinsic size is in percentage units, return those to the caller through the intrinsicSize. Notify the caller
+ // about the special situation, by setting isPercentageIntrinsicSize=true, so it knows how to interpret the return values.
+ if (intrinsicWidthAttribute.isPercent() && intrinsicHeightAttribute.isPercent()) {
+ isPercentageIntrinsicSize = true;
+ intrinsicSize = FloatSize(intrinsicWidthAttribute.percent(), intrinsicHeightAttribute.percent());
}
}
@@ -114,9 +132,9 @@ bool RenderSVGRoot::isEmbeddedThroughFrameContainingSVGDocument() const
return frame().document()->isSVGDocument();
}
-static inline LayoutUnit resolveLengthAttributeForSVG(const Length& length, float scale, float maxSize)
+static inline LayoutUnit resolveLengthAttributeForSVG(const Length& length, float scale, float maxSize, RenderView* renderView)
{
- return valueForLength(length, maxSize) * (length.isFixed() ? scale : 1);
+ return static_cast<LayoutUnit>(valueForLength(length, maxSize, renderView) * (length.isFixed() ? scale : 1));
}
LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred shouldComputePreferred) const
@@ -125,14 +143,15 @@ LayoutUnit RenderSVGRoot::computeReplacedLogicalWidth(ShouldComputePreferred sho
if (!m_containerSize.isEmpty())
return m_containerSize.width();
- if (isEmbeddedThroughFrameContainingSVGDocument())
- return containingBlock()->availableLogicalWidth();
-
if (style().logicalWidth().isSpecified() || style().logicalMaxWidth().isSpecified())
return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred);
- if (svgSVGElement().hasIntrinsicWidth())
- return resolveLengthAttributeForSVG(svgSVGElement().intrinsicWidth(), style().effectiveZoom(), containingBlock()->availableLogicalWidth());
+ if (svgSVGElement().widthAttributeEstablishesViewport())
+ return resolveLengthAttributeForSVG(svgSVGElement().intrinsicWidth(SVGSVGElement::IgnoreCSSProperties), style().effectiveZoom(), containingBlock()->availableLogicalWidth(), &view());
+
+ // SVG embedded through object/embed/iframe.
+ if (isEmbeddedThroughFrameContainingSVGDocument())
+ return frame().ownerRenderer()->availableLogicalWidth();
// SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
return RenderReplaced::computeReplacedLogicalWidth(shouldComputePreferred);
@@ -144,14 +163,27 @@ LayoutUnit RenderSVGRoot::computeReplacedLogicalHeight() const
if (!m_containerSize.isEmpty())
return m_containerSize.height();
- if (isEmbeddedThroughFrameContainingSVGDocument())
- return containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding);
-
if (style().logicalHeight().isSpecified() || style().logicalMaxHeight().isSpecified())
return RenderReplaced::computeReplacedLogicalHeight();
- if (svgSVGElement().hasIntrinsicHeight())
- return resolveLengthAttributeForSVG(svgSVGElement().intrinsicHeight(), style().effectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding).toFloat());
+ if (svgSVGElement().heightAttributeEstablishesViewport()) {
+ Length height = svgSVGElement().intrinsicHeight(SVGSVGElement::IgnoreCSSProperties);
+ if (height.isPercent()) {
+ RenderBlock* cb = containingBlock();
+ ASSERT(cb);
+ while (cb->isAnonymous() && !cb->isRenderView()) {
+ cb = cb->containingBlock();
+ cb->addPercentHeightDescendant(const_cast<RenderSVGRoot&>(*this));
+ }
+ } else
+ RenderBlock::removePercentHeightDescendant(const_cast<RenderSVGRoot&>(*this));
+
+ return resolveLengthAttributeForSVG(height, style().effectiveZoom(), containingBlock()->availableLogicalHeight(IncludeMarginBorderPadding), &view());
+ }
+
+ // SVG embedded through object/embed/iframe.
+ if (isEmbeddedThroughFrameContainingSVGDocument())
+ return frame().ownerRenderer()->availableLogicalHeight(IncludeMarginBorderPadding);
// SVG embedded via SVGImage (background-image/border-image/etc) / Inline SVG.
return RenderReplaced::computeReplacedLogicalHeight();
@@ -165,7 +197,7 @@ void RenderSVGRoot::layout()
m_resourcesNeedingToInvalidateClients.clear();
// Arbitrary affine transforms are incompatible with LayoutState.
- LayoutStateDisabler layoutStateDisabler(view());
+ LayoutStateDisabler layoutStateDisabler(&view());
bool needsLayout = selfNeedsLayout();
LayoutRepainter repainter(*this, checkForRepaintDuringLayout() && needsLayout);
@@ -195,32 +227,13 @@ void RenderSVGRoot::layout()
m_needsBoundariesOrTransformUpdate = false;
}
- if (!shouldApplyViewportClip()) {
- FloatRect contentRepaintRect = repaintRectInLocalCoordinates();
- contentRepaintRect = m_localToBorderBoxTransform.mapRect(contentRepaintRect);
- addVisualOverflow(enclosingLayoutRect(contentRepaintRect));
- }
-
updateLayerTransform();
- m_hasBoxDecorations = isRoot() ? hasBoxDecorationStyle() : hasBoxDecorations();
- invalidateBackgroundObscurationStatus();
repainter.repaintAfterLayout();
clearNeedsLayout();
}
-bool RenderSVGRoot::shouldApplyViewportClip() const
-{
- // the outermost svg is clipped if auto, and svg document roots are always clipped
- // When the svg is stand-alone (isDocumentElement() == true) the viewport clipping should always
- // be applied, noting that the window scrollbars should be hidden if overflow=hidden.
- return style().overflowX() == OHIDDEN
- || style().overflowX() == OAUTO
- || style().overflowX() == OSCROLL
- || this->isRoot();
-}
-
void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paintOffset)
{
// An empty viewport disables rendering.
@@ -231,10 +244,6 @@ void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint
if (paintInfo.context->paintingDisabled())
return;
- // SVG outlines are painted during PaintPhaseForeground.
- if (paintInfo.phase == PaintPhaseOutline || paintInfo.phase == PaintPhaseSelfOutline)
- return;
-
// An empty viewBox also disables rendering.
// (http://www.w3.org/TR/SVG/coords.html#ViewBoxAttribute)
if (svgSVGElement().hasEmptyViewBox())
@@ -244,7 +253,7 @@ void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint
// Don't paint if we don't have kids, except if we have filters we should paint those.
if (!firstChild()) {
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*this);
if (!resources || !resources->filter()) {
if (page && paintInfo.phase == PaintPhaseForeground)
page->addRelevantUnpaintedObject(this, visualOverflowRect());
@@ -259,9 +268,8 @@ void RenderSVGRoot::paintReplaced(PaintInfo& paintInfo, const LayoutPoint& paint
PaintInfo childPaintInfo(paintInfo);
childPaintInfo.context->save();
- // Apply initial viewport clip
- if (shouldApplyViewportClip())
- childPaintInfo.context->clip(snappedIntRect(overflowClipRect(paintOffset, currentRenderNamedFlowFragment())));
+ // Apply initial viewport clip - not affected by overflow handling
+ childPaintInfo.context->clip(pixelSnappedIntRect(overflowClipRect(paintOffset, paintInfo.renderRegion)));
// Convert from container offsets (html renderers) to a relative transform (svg renderers).
// Transform from our paint container's coordinate system to our local coords.
@@ -355,16 +363,8 @@ void RenderSVGRoot::computeFloatRectForRepaint(const RenderLayerModelObject* rep
if (const ShadowData* shadow = svgStyle.shadow())
shadow->adjustRectForShadow(repaintRect);
- // Apply initial viewport clip
- if (shouldApplyViewportClip())
- repaintRect.intersect(pixelSnappedBorderBoxRect());
-
- if (m_hasBoxDecorations || hasRenderOverflow()) {
- // The selectionRect can project outside of the overflowRect, so take their union
- // for repainting to avoid selection painting glitches.
- LayoutRect decoratedRepaintRect = unionRect(localSelectionRect(false), visualOverflowRect());
- repaintRect.unite(decoratedRepaintRect);
- }
+ // Apply initial viewport clip - not affected by overflow settings
+ repaintRect.intersect(pixelSnappedBorderBoxRect());
LayoutRect rect = enclosingIntRect(repaintRect);
RenderReplaced::computeRectForRepaint(repaintContainer, rect, fixed);
@@ -391,7 +391,7 @@ void RenderSVGRoot::updateCachedBoundaries()
{
SVGRenderSupport::computeContainerBoundingBoxes(*this, m_objectBoundingBox, m_objectBoundingBoxValid, m_strokeBoundingBox, m_repaintBoundingBoxExcludingShadow);
SVGRenderSupport::intersectRepaintRectWithResources(*this, m_repaintBoundingBoxExcludingShadow);
- m_repaintBoundingBoxExcludingShadow.inflate(horizontalBorderAndPaddingExtent());
+ m_repaintBoundingBoxExcludingShadow.inflate(borderAndPaddingWidth());
m_repaintBoundingBox = m_repaintBoundingBoxExcludingShadow;
SVGRenderSupport::intersectRepaintRectWithShadows(*this, m_repaintBoundingBox);
@@ -436,17 +436,29 @@ bool RenderSVGRoot::nodeAtPoint(const HitTestRequest& request, HitTestResult& re
bool RenderSVGRoot::hasRelativeDimensions() const
{
- return svgSVGElement().intrinsicHeight().isPercentOrCalculated() || svgSVGElement().intrinsicWidth().isPercentOrCalculated();
+ return svgSVGElement().intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent() || svgSVGElement().intrinsicWidth(SVGSVGElement::IgnoreCSSProperties).isPercent();
+}
+
+bool RenderSVGRoot::hasRelativeIntrinsicLogicalWidth() const
+{
+ return svgSVGElement().intrinsicWidth(SVGSVGElement::IgnoreCSSProperties).isPercent();
+}
+
+bool RenderSVGRoot::hasRelativeLogicalHeight() const
+{
+ return svgSVGElement().intrinsicHeight(SVGSVGElement::IgnoreCSSProperties).isPercent();
}
void RenderSVGRoot::addResourceForClientInvalidation(RenderSVGResourceContainer* resource)
{
- RenderElement* svgRoot = resource->parent();
- while (svgRoot && !is<RenderSVGRoot>(*svgRoot))
+ RenderObject* svgRoot = resource->parent();
+ while (svgRoot && !svgRoot->isSVGRoot())
svgRoot = svgRoot->parent();
if (!svgRoot)
return;
- downcast<RenderSVGRoot>(*svgRoot).m_resourcesNeedingToInvalidateClients.add(resource);
+ toRenderSVGRoot(svgRoot)->m_resourcesNeedingToInvalidateClients.add(resource);
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGRoot.h b/Source/WebCore/rendering/svg/RenderSVGRoot.h
index 49782eaa4..edebf1cf8 100644
--- a/Source/WebCore/rendering/svg/RenderSVGRoot.h
+++ b/Source/WebCore/rendering/svg/RenderSVGRoot.h
@@ -23,6 +23,7 @@
#ifndef RenderSVGRoot_h
#define RenderSVGRoot_h
+#if ENABLE(SVG)
#include "FloatRect.h"
#include "RenderReplaced.h"
@@ -31,12 +32,11 @@
namespace WebCore {
class AffineTransform;
-class RenderSVGResourceContainer;
class SVGSVGElement;
class RenderSVGRoot final : public RenderReplaced {
public:
- RenderSVGRoot(SVGSVGElement&, Ref<RenderStyle>&&);
+ RenderSVGRoot(SVGSVGElement&, PassRef<RenderStyle>);
virtual ~RenderSVGRoot();
SVGSVGElement& svgSVGElement() const;
@@ -44,7 +44,7 @@ public:
bool isEmbeddedThroughSVGImage() const;
bool isEmbeddedThroughFrameContainingSVGDocument() const;
- virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio) const override;
+ virtual void computeIntrinsicRatioInformation(FloatSize& intrinsicSize, double& intrinsicRatio, bool& isPercentageIntrinsicSize) const override;
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
virtual void setNeedsBoundariesUpdate() override { m_needsBoundariesOrTransformUpdate = true; }
@@ -55,6 +55,8 @@ public:
void setContainerSize(const IntSize& containerSize) { m_containerSize = containerSize; }
virtual bool hasRelativeDimensions() const override;
+ virtual bool hasRelativeIntrinsicLogicalWidth() const override;
+ virtual bool hasRelativeLogicalHeight() const override;
// localToBorderBoxTransform maps local SVG viewport coordinates to local CSS box coordinates.
const AffineTransform& localToBorderBoxTransform() const { return m_localToBorderBoxTransform; }
@@ -90,20 +92,19 @@ private:
virtual FloatRect objectBoundingBox() const override { return m_objectBoundingBox; }
virtual FloatRect strokeBoundingBox() const override { return m_strokeBoundingBox; }
virtual FloatRect repaintRectInLocalCoordinates() const override { return m_repaintBoundingBox; }
- FloatRect repaintRectInLocalCoordinatesExcludingSVGShadow() const { return m_repaintBoundingBoxExcludingShadow; }
+ virtual FloatRect repaintRectInLocalCoordinatesExcludingSVGShadow() const { return m_repaintBoundingBoxExcludingShadow; }
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override;
virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect& repaintRect, bool fixed) const override;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const override;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override;
virtual bool canBeSelectionLeaf() const override { return false; }
virtual bool canHaveChildren() const override { return true; }
- bool shouldApplyViewportClip() const;
void updateCachedBoundaries();
void buildLocalToBorderBoxTransform();
@@ -119,11 +120,12 @@ private:
bool m_isLayoutSizeChanged : 1;
bool m_needsBoundariesOrTransformUpdate : 1;
bool m_hasSVGShadow : 1;
- bool m_hasBoxDecorations : 1;
};
-} // namespace WebCore
+template<> inline bool isRendererOfType<const RenderSVGRoot>(const RenderObject& renderer) { return renderer.isSVGRoot(); }
+RENDER_OBJECT_TYPE_CASTS(RenderSVGRoot, isSVGRoot())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGRoot, isSVGRoot())
+} // namespace WebCore
+#endif // ENABLE(SVG)
#endif // RenderSVGRoot_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.cpp b/Source/WebCore/rendering/svg/RenderSVGShape.cpp
index a19cdbb6c..b93a028b5 100644
--- a/Source/WebCore/rendering/svg/RenderSVGShape.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGShape.cpp
@@ -26,6 +26,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGShape.h"
#include "FloatPoint.h"
@@ -63,8 +65,8 @@ private:
const RenderSVGShape& m_renderer;
};
-RenderSVGShape::RenderSVGShape(SVGGraphicsElement& element, Ref<RenderStyle>&& style)
- : RenderSVGModelObject(element, WTF::move(style))
+RenderSVGShape::RenderSVGShape(SVGGraphicsElement& element, PassRef<RenderStyle> style)
+ : RenderSVGModelObject(element, std::move(style))
, m_needsBoundariesUpdate(false) // Default is false, the cached rects are empty from the beginning.
, m_needsShapeUpdate(true) // Default is true, so we grab a Path object once from SVGGraphicsElement.
, m_needsTransformUpdate(true) // Default is true, so we grab a AffineTransform object once from SVGGraphicsElement.
@@ -77,7 +79,8 @@ RenderSVGShape::~RenderSVGShape()
void RenderSVGShape::updateShapeFromElement()
{
- m_path = std::make_unique<Path>();
+ m_path.clear();
+ m_path = adoptPtr(new Path);
ASSERT(RenderSVGShape::isEmpty());
updatePathFromGraphicsElement(&graphicsElement(), path());
@@ -187,7 +190,7 @@ void RenderSVGShape::layout()
Path* RenderSVGShape::nonScalingStrokePath(const Path* path, const AffineTransform& strokeTransform) const
{
- DEPRECATED_DEFINE_STATIC_LOCAL(Path, tempPath, ());
+ DEFINE_STATIC_LOCAL(Path, tempPath, ());
tempPath = *path;
tempPath.transform(strokeTransform);
@@ -218,7 +221,7 @@ bool RenderSVGShape::shouldGenerateMarkerPositions() const
if (!graphicsElement().supportsMarkers())
return false;
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*this);
if (!resources)
return false;
@@ -255,66 +258,55 @@ void RenderSVGShape::strokeShape(const RenderStyle& style, GraphicsContext* cont
}
}
-void RenderSVGShape::strokeShape(GraphicsContext* context)
+void RenderSVGShape::fillAndStrokeShape(GraphicsContext* context)
{
+ fillShape(style(), context);
+
if (!style().svgStyle().hasVisibleStroke())
return;
GraphicsContextStateSaver stateSaver(*context, false);
+
if (hasNonScalingStroke()) {
AffineTransform nonScalingTransform = nonScalingStrokeTransform();
if (!setupNonScalingStrokeContext(nonScalingTransform, stateSaver))
return;
}
- strokeShape(style(), context);
-}
-void RenderSVGShape::fillStrokeMarkers(PaintInfo& childPaintInfo)
-{
- auto paintOrder = style().svgStyle().paintTypesForPaintOrder();
- for (unsigned i = 0; i < paintOrder.size(); ++i) {
- switch (paintOrder.at(i)) {
- case PaintTypeFill:
- fillShape(style(), childPaintInfo.context);
- break;
- case PaintTypeStroke:
- strokeShape(childPaintInfo.context);
- break;
- case PaintTypeMarkers:
- if (!m_markerPositions.isEmpty())
- drawMarkers(childPaintInfo);
- break;
- }
- }
+ strokeShape(style(), context);
}
void RenderSVGShape::paint(PaintInfo& paintInfo, const LayoutPoint&)
{
- if (paintInfo.context->paintingDisabled() || paintInfo.phase != PaintPhaseForeground
- || style().visibility() == HIDDEN || isEmpty())
+ if (paintInfo.context->paintingDisabled() || style().visibility() == HIDDEN || isEmpty())
return;
FloatRect boundingBox = repaintRectInLocalCoordinates();
if (!SVGRenderSupport::paintInfoIntersectsRepaintRect(boundingBox, m_localTransform, paintInfo))
return;
PaintInfo childPaintInfo(paintInfo);
- GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
- childPaintInfo.applyTransform(m_localTransform);
-
- if (childPaintInfo.phase == PaintPhaseForeground) {
- SVGRenderingContext renderingContext(*this, childPaintInfo);
-
- if (renderingContext.isRenderingPrepared()) {
- const SVGRenderStyle& svgStyle = style().svgStyle();
- if (svgStyle.shapeRendering() == SR_CRISPEDGES)
- childPaintInfo.context->setShouldAntialias(false);
-
- fillStrokeMarkers(childPaintInfo);
+ bool drawsOutline = style().outlineWidth() && (childPaintInfo.phase == PaintPhaseOutline || childPaintInfo.phase == PaintPhaseSelfOutline);
+ if (drawsOutline || childPaintInfo.phase == PaintPhaseForeground) {
+ GraphicsContextStateSaver stateSaver(*childPaintInfo.context);
+ childPaintInfo.applyTransform(m_localTransform);
+
+ if (childPaintInfo.phase == PaintPhaseForeground) {
+ SVGRenderingContext renderingContext(*this, childPaintInfo);
+
+ if (renderingContext.isRenderingPrepared()) {
+ const SVGRenderStyle& svgStyle = style().svgStyle();
+ if (svgStyle.shapeRendering() == SR_CRISPEDGES)
+ childPaintInfo.context->setShouldAntialias(false);
+
+ fillAndStrokeShape(childPaintInfo.context);
+ if (!m_markerPositions.isEmpty())
+ drawMarkers(childPaintInfo);
+ }
}
- }
- if (style().outlineWidth())
- paintOutline(childPaintInfo, IntRect(boundingBox));
+ if (drawsOutline)
+ paintOutline(childPaintInfo, IntRect(boundingBox));
+ }
}
// This method is called from inside paintOutline() since we call paintOutline()
@@ -346,7 +338,7 @@ bool RenderSVGShape::nodeAtFloatPoint(const HitTestRequest& request, HitTestResu
fillRule = svgStyle.clipRule();
if ((hitRules.canHitStroke && (svgStyle.hasStroke() || !hitRules.requireStroke) && strokeContains(localPoint, hitRules.requireStroke))
|| (hitRules.canHitFill && (svgStyle.hasFill() || !hitRules.requireFill) && fillContains(localPoint, hitRules.requireFill, fillRule))) {
- updateHitTestResult(result, LayoutPoint(localPoint));
+ updateHitTestResult(result, roundedLayoutPoint(localPoint));
return true;
}
}
@@ -372,7 +364,7 @@ FloatRect RenderSVGShape::markerRect(float strokeWidth) const
{
ASSERT(!m_markerPositions.isEmpty());
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*this);
ASSERT(resources);
RenderSVGResourceMarker* markerStart = resources->markerStart();
@@ -432,7 +424,7 @@ void RenderSVGShape::updateRepaintBoundingBox()
float RenderSVGShape::strokeWidth() const
{
SVGLengthContext lengthContext(&graphicsElement());
- return lengthContext.valueForLength(style().svgStyle().strokeWidth());
+ return style().svgStyle().strokeWidth().value(lengthContext);
}
bool RenderSVGShape::hasSmoothStroke() const
@@ -448,7 +440,7 @@ void RenderSVGShape::drawMarkers(PaintInfo& paintInfo)
{
ASSERT(!m_markerPositions.isEmpty());
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*this);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*this);
if (!resources)
return;
@@ -476,10 +468,10 @@ void RenderSVGShape::processMarkerPositions()
ASSERT(m_path);
SVGMarkerData markerData(m_markerPositions);
- m_path->apply([&markerData](const PathElement& pathElement) {
- SVGMarkerData::updateFromPathElement(markerData, pathElement);
- });
+ m_path->apply(&markerData, SVGMarkerData::updateFromPathElement);
markerData.pathIsDone();
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGShape.h b/Source/WebCore/rendering/svg/RenderSVGShape.h
index 611bfd14b..e27b4b42f 100644
--- a/Source/WebCore/rendering/svg/RenderSVGShape.h
+++ b/Source/WebCore/rendering/svg/RenderSVGShape.h
@@ -2,7 +2,7 @@
* Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
* Copyright (C) 2005 Eric Seidel <eric@webkit.org>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc
* Copyright (C) 2009 Google, Inc.
* Copyright (C) 2011 Renata Hodovan <reni@webkit.org>
* Copyright (C) 2011 University of Szeged
@@ -26,12 +26,13 @@
#ifndef RenderSVGShape_h
#define RenderSVGShape_h
+#if ENABLE(SVG)
#include "AffineTransform.h"
#include "FloatRect.h"
#include "RenderSVGModelObject.h"
#include "SVGGraphicsElement.h"
#include "SVGMarkerData.h"
-#include <memory>
+#include <wtf/OwnPtr.h>
#include <wtf/Vector.h>
namespace WebCore {
@@ -45,10 +46,11 @@ class SVGGraphicsElement;
class RenderSVGShape : public RenderSVGModelObject {
public:
- RenderSVGShape(SVGGraphicsElement&, Ref<RenderStyle>&&);
+ RenderSVGShape(SVGGraphicsElement&, PassRef<RenderStyle>);
+ RenderSVGShape(SVGGraphicsElement&, PassRef<RenderStyle>, Path*, bool);
virtual ~RenderSVGShape();
- SVGGraphicsElement& graphicsElement() const { return downcast<SVGGraphicsElement>(RenderSVGModelObject::element()); }
+ SVGGraphicsElement& graphicsElement() const { return toSVGGraphicsElement(RenderSVGModelObject::element()); }
void setNeedsShapeUpdate() { m_needsShapeUpdate = true; }
virtual void setNeedsBoundariesUpdate() override final { m_needsBoundariesUpdate = true; }
@@ -56,7 +58,6 @@ public:
virtual void setNeedsTransformUpdate() override final { m_needsTransformUpdate = true; }
virtual void fillShape(GraphicsContext*) const;
virtual void strokeShape(GraphicsContext*) const;
- virtual bool isRenderingDisabled() const = 0;
bool hasPath() const { return m_path.get(); }
Path& path() const
@@ -116,15 +117,14 @@ private:
void fillShape(const RenderStyle&, GraphicsContext*);
void strokeShape(const RenderStyle&, GraphicsContext*);
- void strokeShape(GraphicsContext*);
- void fillStrokeMarkers(PaintInfo&);
+ void fillAndStrokeShape(GraphicsContext*);
void drawMarkers(PaintInfo&);
private:
FloatRect m_repaintBoundingBox;
FloatRect m_repaintBoundingBoxExcludingShadow;
AffineTransform m_localTransform;
- std::unique_ptr<Path> m_path;
+ OwnPtr<Path> m_path;
Vector<MarkerPosition> m_markerPositions;
bool m_needsBoundariesUpdate : 1;
@@ -132,8 +132,9 @@ private:
bool m_needsTransformUpdate : 1;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGShape, isSVGShape())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGShape, isSVGShape())
+}
-#endif // RenderSVGShape_h
+#endif // ENABLE(SVG)
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGTSpan.h b/Source/WebCore/rendering/svg/RenderSVGTSpan.h
index b7a788307..bdd33bbb0 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTSpan.h
+++ b/Source/WebCore/rendering/svg/RenderSVGTSpan.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer Inc.
* Copyright (C) 2009 Google Inc.
*
* This library is free software; you can redistribute it and/or
@@ -22,14 +22,15 @@
#ifndef RenderSVGTSpan_h
#define RenderSVGTSpan_h
+#if ENABLE(SVG)
#include "RenderSVGInline.h"
#include "SVGTextPositioningElement.h"
namespace WebCore {
class RenderSVGTSpan final : public RenderSVGInline {
public:
- explicit RenderSVGTSpan(SVGTextPositioningElement& element, Ref<RenderStyle>&& style)
- : RenderSVGInline(element, WTF::move(style))
+ explicit RenderSVGTSpan(SVGTextPositioningElement& element, PassRef<RenderStyle> style)
+ : RenderSVGInline(element, std::move(style))
{
}
@@ -37,8 +38,9 @@ public:
private:
void graphicsElement() const = delete;
- virtual const char* renderName() const override { return "RenderSVGTSpan"; }
+ virtual const char* renderName() const { return "RenderSVGTSpan"; }
};
}
+#endif // ENABLE(SVG)
#endif // !RenderSVGTSpan_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.cpp b/Source/WebCore/rendering/svg/RenderSVGText.cpp
index 4e08f3f9a..22c1cdaab 100644
--- a/Source/WebCore/rendering/svg/RenderSVGText.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGText.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, 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 "Font.h"
+#include "FontCache.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"
@@ -46,14 +46,15 @@
#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, Ref<RenderStyle>&& style)
- : RenderSVGBlock(element, WTF::move(style))
+RenderSVGText::RenderSVGText(SVGTextElement& element, PassRef<RenderStyle> style)
+ : RenderSVGBlock(element, std::move(style))
, m_needsReordering(false)
, m_needsPositioningValuesUpdate(false)
, m_needsTransformUpdate(true)
@@ -68,7 +69,7 @@ RenderSVGText::~RenderSVGText()
SVGTextElement& RenderSVGText::textElement() const
{
- return downcast<SVGTextElement>(RenderSVGBlock::graphicsElement());
+ return toSVGTextElement(RenderSVGBlock::graphicsElement());
}
bool RenderSVGText::isChildAllowed(const RenderObject& child, const RenderStyle&) const
@@ -76,14 +77,24 @@ bool RenderSVGText::isChildAllowed(const RenderObject& child, const RenderStyle&
return child.isInline();
}
-RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(RenderObject& start)
+RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(RenderObject* start)
{
- return lineageOfType<RenderSVGText>(start).first();
+ ASSERT(start);
+ while (start && !start->isSVGText())
+ start = start->parent();
+ if (!start || !start->isSVGText())
+ return 0;
+ return toRenderSVGText(start);
}
-const RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(const RenderObject& start)
+const RenderSVGText* RenderSVGText::locateRenderSVGTextAncestor(const RenderObject* start)
{
- return lineageOfType<RenderSVGText>(start).first();
+ ASSERT(start);
+ while (start && !start->isSVGText())
+ start = start->parent();
+ if (!start || !start->isSVGText())
+ return 0;
+ return toRenderSVGText(start);
}
LayoutRect RenderSVGText::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
@@ -116,8 +127,8 @@ 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 (is<RenderSVGInlineText>(*descendant))
- attributes.append(downcast<RenderSVGInlineText>(*descendant).layoutAttributes());
+ if (descendant->isSVGInlineText())
+ attributes.append(toRenderSVGInlineText(descendant)->layoutAttributes());
}
}
@@ -127,15 +138,15 @@ static inline bool findPreviousAndNextAttributes(RenderElement* start, RenderSVG
ASSERT(locateElement);
// FIXME: Make this iterative.
for (RenderObject* child = start->firstChild(); child; child = child->nextSibling()) {
- if (is<RenderSVGInlineText>(*child)) {
- RenderSVGInlineText& text = downcast<RenderSVGInlineText>(*child);
- if (locateElement != &text) {
+ if (child->isSVGInlineText()) {
+ RenderSVGInlineText* text = toRenderSVGInlineText(child);
+ if (locateElement != text) {
if (stopAfterNext) {
- next = text.layoutAttributes();
+ next = text->layoutAttributes();
return true;
}
- previous = text.layoutAttributes();
+ previous = text->layoutAttributes();
continue;
}
@@ -143,10 +154,10 @@ static inline bool findPreviousAndNextAttributes(RenderElement* start, RenderSVG
continue;
}
- if (!is<RenderSVGInline>(*child))
+ if (!child->isSVGInline())
continue;
- if (findPreviousAndNextAttributes(downcast<RenderElement>(child), locateElement, stopAfterNext, previous, next))
+ if (findPreviousAndNextAttributes(toRenderElement(child), locateElement, stopAfterNext, previous, next))
return true;
}
@@ -169,6 +180,9 @@ void RenderSVGText::subtreeChildWasAdded(RenderObject* child)
if (!shouldHandleSubtreeMutations() || documentBeingDestroyed())
return;
+ // Always protect the cache before clearing text positioning elements when the cache will subsequently be rebuilt.
+ FontCachePurgePreventer fontCachePurgePreventer;
+
// The positioning elements cache doesn't include the new 'child' yet. Clear the
// cache, as the next buildLayoutAttributesForTextRenderer() call rebuilds it.
m_layoutAttributesBuilder.clearTextPositioningElements();
@@ -250,20 +264,21 @@ void RenderSVGText::subtreeChildWillBeRemoved(RenderObject* child, Vector<SVGTex
return;
// This logic requires that the 'text' child is still inserted in the tree.
- auto& text = downcast<RenderSVGInlineText>(*child);
+ RenderSVGInlineText* text = toRenderSVGInlineText(child);
bool stopAfterNext = false;
- SVGTextLayoutAttributes* previous = nullptr;
- SVGTextLayoutAttributes* next = nullptr;
+ SVGTextLayoutAttributes* previous = 0;
+ SVGTextLayoutAttributes* next = 0;
if (!documentBeingDestroyed())
- findPreviousAndNextAttributes(this, &text, stopAfterNext, previous, next);
+ findPreviousAndNextAttributes(this, text, stopAfterNext, previous, next);
if (previous)
affectedAttributes.append(previous);
if (next)
affectedAttributes.append(next);
- bool removed = m_layoutAttributes.removeFirst(text.layoutAttributes());
- ASSERT_UNUSED(removed, removed);
+ size_t position = m_layoutAttributes.find(text->layoutAttributes());
+ ASSERT(position != notFound);
+ m_layoutAttributes.remove(position);
}
void RenderSVGText::subtreeChildWasRemoved(const Vector<SVGTextLayoutAttributes*, 2>& affectedAttributes)
@@ -290,9 +305,10 @@ void RenderSVGText::subtreeStyleDidChange(RenderSVGInlineText* text)
// 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 (is<RenderSVGInlineText>(*descendant))
- m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(downcast<RenderSVGInlineText>(*descendant));
+ if (descendant->isSVGInlineText())
+ m_layoutAttributesBuilder.rebuildMetricsForTextRenderer(toRenderSVGInlineText(descendant));
}
}
@@ -311,26 +327,29 @@ 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 (is<RenderSVGInlineText>(*descendant))
- m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(downcast<RenderSVGInlineText>(*descendant));
+ if (descendant->isSVGInlineText())
+ m_layoutAttributesBuilder.buildLayoutAttributesForTextRenderer(toRenderSVGInlineText(*descendant));
}
}
-static inline void updateFontInAllDescendants(RenderObject* start, SVGTextLayoutAttributesBuilder* builder = nullptr)
+static inline void updateFontInAllDescendants(RenderObject* start, SVGTextLayoutAttributesBuilder* builder = 0)
{
for (RenderObject* descendant = start; descendant; descendant = descendant->nextInPreOrder(start)) {
- if (!is<RenderSVGInlineText>(*descendant))
+ if (!descendant->isSVGInlineText())
continue;
- auto& text = downcast<RenderSVGInlineText>(*descendant);
+ RenderSVGInlineText& text = toRenderSVGInlineText(*descendant);
text.updateScaledFont();
if (builder)
- builder->rebuildMetricsForTextRenderer(text);
+ builder->rebuildMetricsForTextRenderer(&text);
}
}
@@ -353,7 +372,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;
@@ -367,7 +386,7 @@ void RenderSVGText::layout()
m_needsTextMetricsUpdate = false;
}
- m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(*this);
+ m_layoutAttributesBuilder.buildLayoutAttributesForForSubtree(this);
m_needsReordering = true;
m_needsPositioningValuesUpdate = false;
updateCachedBoundariesInParents = true;
@@ -390,7 +409,7 @@ void RenderSVGText::layout()
ASSERT(!simplifiedLayout());
ASSERT(!scrollsOverflow());
ASSERT(!hasControlClip());
- ASSERT(!multiColumnFlowThread());
+ ASSERT(!hasColumns());
ASSERT(!positionedObjects());
ASSERT(!m_overflow);
ASSERT(!isAnonymousBlock());
@@ -403,7 +422,7 @@ void RenderSVGText::layout()
ASSERT(childrenInline());
LayoutUnit repaintLogicalTop = 0;
LayoutUnit repaintLogicalBottom = 0;
- rebuildFloatingObjectSetFromIntrudingFloats();
+ clearFloats();
layoutInlineChildren(true, repaintLogicalTop, repaintLogicalBottom);
if (m_needsReordering)
@@ -428,7 +447,7 @@ std::unique_ptr<RootInlineBox> RenderSVGText::createRootInlineBox()
{
auto box = std::make_unique<SVGRootInlineBox>(*this);
box->setHasVirtualLogicalHeight();
- return WTF::move(box);
+ return std::move(box);
}
bool RenderSVGText::nodeAtFloatPoint(const HitTestRequest& request, HitTestResult& result, const FloatPoint& pointInParent, HitTestAction hitTestAction)
@@ -457,25 +476,26 @@ bool RenderSVGText::nodeAtPoint(const HitTestRequest&, HitTestResult&, const Hit
return false;
}
-VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInContents, const RenderRegion* region)
+VisiblePosition RenderSVGText::positionForPoint(const LayoutPoint& pointInContents)
{
RootInlineBox* rootBox = firstRootBox();
if (!rootBox)
return createVisiblePosition(0, DOWNSTREAM);
+ ASSERT_WITH_SECURITY_IMPLICATION(rootBox->isSVGRootInlineBox());
ASSERT(!rootBox->nextRootBox());
ASSERT(childrenInline());
- InlineBox* closestBox = downcast<SVGRootInlineBox>(*rootBox).closestLeafChildForPosition(pointInContents);
+ InlineBox* closestBox = toSVGRootInlineBox(rootBox)->closestLeafChildForPosition(pointInContents);
if (!closestBox)
return createVisiblePosition(0, DOWNSTREAM);
- return closestBox->renderer().positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()), region);
+ return closestBox->renderer().positionForPoint(LayoutPoint(pointInContents.x(), closestBox->y()));
}
void RenderSVGText::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
{
- quads.append(localToAbsoluteQuad(strokeBoundingBox(), UseTransforms, wasFixed));
+ quads.append(localToAbsoluteQuad(strokeBoundingBox(), 0 /* mode */, wasFixed));
}
void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&)
@@ -484,6 +504,7 @@ void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&)
return;
if (paintInfo.phase != PaintPhaseForeground
+ && paintInfo.phase != PaintPhaseSelfOutline
&& paintInfo.phase != PaintPhaseSelection)
return;
@@ -491,12 +512,6 @@ void RenderSVGText::paint(PaintInfo& paintInfo, const LayoutPoint&)
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
@@ -507,7 +522,7 @@ FloatRect RenderSVGText::strokeBoundingBox() const
return strokeBoundaries;
SVGLengthContext lengthContext(&textElement());
- strokeBoundaries.inflate(lengthContext.valueForLength(svgStyle.strokeWidth()));
+ strokeBoundaries.inflate(svgStyle.strokeWidth().value(lengthContext));
return strokeBoundaries;
}
@@ -535,6 +550,7 @@ void RenderSVGText::removeChild(RenderObject& child)
SVGResourcesCache::clientWillBeRemovedFromTree(child);
Vector<SVGTextLayoutAttributes*, 2> affectedAttributes;
+ FontCachePurgePreventer fontCachePurgePreventer;
subtreeChildWillBeRemoved(&child, affectedAttributes);
RenderSVGBlock::removeChild(child);
subtreeChildWasRemoved(affectedAttributes);
@@ -554,3 +570,5 @@ void RenderSVGText::updateFirstLetter()
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGText.h b/Source/WebCore/rendering/svg/RenderSVGText.h
index 462773d21..93ac44246 100644
--- a/Source/WebCore/rendering/svg/RenderSVGText.h
+++ b/Source/WebCore/rendering/svg/RenderSVGText.h
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer, Inc.
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) Research In Motion Limited 2010-2012. All rights reserved.
*
@@ -22,6 +22,7 @@
#ifndef RenderSVGText_h
#define RenderSVGText_h
+#if ENABLE(SVG)
#include "AffineTransform.h"
#include "RenderSVGBlock.h"
#include "SVGTextLayoutAttributesBuilder.h"
@@ -34,20 +35,20 @@ class RenderSVGInlineText;
class RenderSVGText final : public RenderSVGBlock {
public:
- RenderSVGText(SVGTextElement&, Ref<RenderStyle>&&);
+ RenderSVGText(SVGTextElement&, PassRef<RenderStyle>);
virtual ~RenderSVGText();
SVGTextElement& textElement() const;
- virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const override;
+ virtual bool isChildAllowed(const RenderObject&, const RenderStyle&) const;
void setNeedsPositioningValuesUpdate() { m_needsPositioningValuesUpdate = true; }
- virtual void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
void setNeedsTextMetricsUpdate() { m_needsTextMetricsUpdate = true; }
- virtual FloatRect repaintRectInLocalCoordinates() const override;
+ virtual FloatRect repaintRectInLocalCoordinates() const;
- static RenderSVGText* locateRenderSVGTextAncestor(RenderObject&);
- static const RenderSVGText* locateRenderSVGTextAncestor(const RenderObject&);
+ static RenderSVGText* locateRenderSVGTextAncestor(RenderObject*);
+ static const RenderSVGText* locateRenderSVGTextAncestor(const RenderObject*);
bool needsReordering() const { return m_needsReordering; }
Vector<SVGTextLayoutAttributes*>& layoutAttributes() { return m_layoutAttributes; }
@@ -58,41 +59,41 @@ public:
void subtreeStyleDidChange(RenderSVGInlineText*);
void subtreeTextDidChange(RenderSVGInlineText*);
- virtual FloatRect objectBoundingBox() const override { return frameRect(); }
- virtual FloatRect strokeBoundingBox() const override;
-
private:
void graphicsElement() const = delete;
- virtual const char* renderName() const override { return "RenderSVGText"; }
- virtual bool isSVGText() const override { return true; }
+ virtual const char* renderName() const { return "RenderSVGText"; }
+ virtual bool isSVGText() const { return true; }
- virtual void paint(PaintInfo&, const LayoutPoint&) override;
+ virtual void paint(PaintInfo&, const LayoutPoint&);
virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, HitTestAction) override;
- virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction) override;
- virtual VisiblePosition positionForPoint(const LayoutPoint&, const RenderRegion*) override;
+ virtual bool nodeAtFloatPoint(const HitTestRequest&, HitTestResult&, const FloatPoint& pointInParent, HitTestAction);
+ virtual VisiblePosition positionForPoint(const LayoutPoint&);
- virtual bool requiresLayer() const override { return false; }
- virtual void layout() override;
+ virtual bool requiresLayer() const { return false; }
+ virtual void layout();
- virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const override;
+ virtual void absoluteQuads(Vector<FloatQuad>&, bool* wasFixed) const;
virtual LayoutRect clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const override;
virtual void computeRectForRepaint(const RenderLayerModelObject* repaintContainer, LayoutRect&, bool fixed = false) const override;
virtual void computeFloatRectForRepaint(const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed = false) const override;
- virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags, bool* wasFixed) const override;
+ virtual void mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState&, MapCoordinatesFlags = ApplyContainerFlip, bool* wasFixed = 0) const override;
virtual const RenderObject* pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&) const override;
- virtual void addChild(RenderObject* child, RenderObject* beforeChild = nullptr) override;
+ virtual void addChild(RenderObject* child, RenderObject* beforeChild = 0);
virtual void removeChild(RenderObject&) override;
virtual void willBeDestroyed() override;
- virtual const AffineTransform& localToParentTransform() const override { return m_localTransform; }
- virtual AffineTransform localTransform() const override { return m_localTransform; }
+ virtual FloatRect objectBoundingBox() const { return frameRect(); }
+ virtual FloatRect strokeBoundingBox() const;
+
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
+ virtual AffineTransform localTransform() const { return m_localTransform; }
virtual std::unique_ptr<RootInlineBox> createRootInlineBox() override;
- virtual RenderBlock* firstLineBlock() const override;
- virtual void updateFirstLetter() override;
+ virtual RenderBlock* firstLineBlock() const;
+ virtual void updateFirstLetter();
bool shouldHandleSubtreeMutations() const;
@@ -105,8 +106,9 @@ private:
Vector<SVGTextLayoutAttributes*> m_layoutAttributes;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGText, isSVGText())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGText, isSVGText())
+}
-#endif // RenderSVGText_h
+#endif // ENABLE(SVG)
+#endif
diff --git a/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp b/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
index 9671c9b34..12cb6d361 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGTextPath.cpp
@@ -18,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGTextPath.h"
#include "FloatQuad.h"
@@ -32,14 +34,14 @@
namespace WebCore {
-RenderSVGTextPath::RenderSVGTextPath(SVGTextPathElement& element, Ref<RenderStyle>&& style)
- : RenderSVGInline(element, WTF::move(style))
+RenderSVGTextPath::RenderSVGTextPath(SVGTextPathElement& element, PassRef<RenderStyle> style)
+ : RenderSVGInline(element, std::move(style))
{
}
SVGTextPathElement& RenderSVGTextPath::textPathElement() const
{
- return downcast<SVGTextPathElement>(RenderSVGInline::graphicsElement());
+ return toSVGTextPathElement(RenderSVGInline::graphicsElement());
}
Path RenderSVGTextPath::layoutPath() const
@@ -48,17 +50,17 @@ Path RenderSVGTextPath::layoutPath() const
if (!targetElement || !targetElement->hasTagName(SVGNames::pathTag))
return Path();
- SVGPathElement& pathElement = downcast<SVGPathElement>(*targetElement);
+ SVGPathElement* pathElement = toSVGPathElement(targetElement);
Path pathData;
- updatePathFromGraphicsElement(&pathElement, pathData);
+ updatePathFromGraphicsElement(pathElement, pathData);
// Spec: The transform attribute on the referenced 'path' element represents a
// supplemental transformation relative to the current user coordinate system for
// the current 'text' element, including any adjustments to the current user coordinate
// system due to a possible transform attribute on the current 'text' element.
// http://www.w3.org/TR/SVG/text.html#TextPathElement
- pathData.transform(pathElement.animatedLocalTransform());
+ pathData.transform(pathElement->animatedLocalTransform());
return pathData;
}
@@ -78,3 +80,5 @@ bool RenderSVGTextPath::stretchMethod() const
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGTextPath.h b/Source/WebCore/rendering/svg/RenderSVGTextPath.h
index 021555f25..e7e11ad98 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTextPath.h
+++ b/Source/WebCore/rendering/svg/RenderSVGTextPath.h
@@ -21,13 +21,14 @@
#ifndef RenderSVGTextPath_h
#define RenderSVGTextPath_h
+#if ENABLE(SVG)
#include "RenderSVGInline.h"
namespace WebCore {
class RenderSVGTextPath final : public RenderSVGInline {
public:
- RenderSVGTextPath(SVGTextPathElement&, Ref<RenderStyle>&&);
+ RenderSVGTextPath(SVGTextPathElement&, PassRef<RenderStyle>);
SVGTextPathElement& textPathElement() const;
@@ -45,8 +46,9 @@ private:
Path m_layoutPath;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGTextPath, isSVGTextPath())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGTextPath, isSVGTextPath())
+}
+#endif // ENABLE(SVG)
#endif // RenderSVGTextPath_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
index ea64d3cc9..3268b676a 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.cpp
@@ -20,6 +20,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGTransformableContainer.h"
#include "SVGNames.h"
@@ -27,8 +29,8 @@
namespace WebCore {
-RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGGraphicsElement& element, Ref<RenderStyle>&& style)
- : RenderSVGContainer(element, WTF::move(style))
+RenderSVGTransformableContainer::RenderSVGTransformableContainer(SVGGraphicsElement& element, PassRef<RenderStyle> style)
+ : RenderSVGContainer(element, std::move(style))
, m_needsTransformUpdate(true)
, m_didTransformToRootUpdate(false)
{
@@ -41,13 +43,13 @@ bool RenderSVGTransformableContainer::calculateLocalTransform()
// If we're either the renderer for a <use> element, or for any <g> element inside the shadow
// tree, that was created during the use/symbol/svg expansion in SVGUseElement. These containers
// need to respect the translations induced by their corresponding use elements x/y attributes.
- SVGUseElement* useElement = nullptr;
- if (is<SVGUseElement>(element))
- useElement = &downcast<SVGUseElement>(element);
- else if (element.isInShadowTree() && is<SVGGElement>(element)) {
+ SVGUseElement* useElement = 0;
+ if (isSVGUseElement(element))
+ useElement = &toSVGUseElement(element);
+ else if (element.isInShadowTree() && isSVGGElement(element)) {
SVGElement* correspondingElement = element.correspondingElement();
- if (is<SVGUseElement>(correspondingElement))
- useElement = downcast<SVGUseElement>(correspondingElement);
+ if (correspondingElement && isSVGUseElement(correspondingElement))
+ useElement = toSVGUseElement(correspondingElement);
}
if (useElement) {
@@ -69,3 +71,5 @@ bool RenderSVGTransformableContainer::calculateLocalTransform()
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
index b9f6c1803..d97eafda0 100644
--- a/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGTransformableContainer.h
@@ -21,6 +21,7 @@
#ifndef RenderSVGTransformableContainer_h
#define RenderSVGTransformableContainer_h
+#if ENABLE(SVG)
#include "RenderSVGContainer.h"
#include "SVGGraphicsElement.h"
@@ -29,18 +30,18 @@ namespace WebCore {
class SVGGraphicsElement;
class RenderSVGTransformableContainer final : public RenderSVGContainer {
public:
- RenderSVGTransformableContainer(SVGGraphicsElement&, Ref<RenderStyle>&&);
- SVGGraphicsElement& graphicsElement() { return downcast<SVGGraphicsElement>(RenderSVGContainer::element()); }
+ RenderSVGTransformableContainer(SVGGraphicsElement&, PassRef<RenderStyle>);
+ SVGGraphicsElement& graphicsElement() { return toSVGGraphicsElement(RenderSVGContainer::element()); }
- virtual bool isSVGTransformableContainer() const override { return true; }
- virtual const AffineTransform& localToParentTransform() const override { return m_localTransform; }
- virtual void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
- virtual bool didTransformToRootUpdate() override { return m_didTransformToRootUpdate; }
+ virtual bool isSVGTransformableContainer() const { return true; }
+ virtual const AffineTransform& localToParentTransform() const { return m_localTransform; }
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
+ virtual bool didTransformToRootUpdate() { return m_didTransformToRootUpdate; }
private:
void element() const = delete;
- virtual bool calculateLocalTransform() override;
- virtual AffineTransform localTransform() const override { return m_localTransform; }
+ virtual bool calculateLocalTransform();
+ virtual AffineTransform localTransform() const { return m_localTransform; }
bool m_needsTransformUpdate : 1;
bool m_didTransformToRootUpdate : 1;
@@ -48,8 +49,7 @@ private:
FloatSize m_lastTranslation;
};
-} // namespace WebCore
-
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGTransformableContainer, isSVGTransformableContainer())
+}
+#endif // ENABLE(SVG)
#endif // RenderSVGTransformableContainer_h
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
index 02703d3df..f03467c62 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.cpp
@@ -21,17 +21,21 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "RenderSVGViewportContainer.h"
#include "GraphicsContext.h"
#include "RenderView.h"
+#include "SVGElementInstance.h"
#include "SVGNames.h"
#include "SVGSVGElement.h"
+#include "SVGUseElement.h"
namespace WebCore {
-RenderSVGViewportContainer::RenderSVGViewportContainer(SVGSVGElement& element, Ref<RenderStyle>&& style)
- : RenderSVGContainer(element, WTF::move(style))
+RenderSVGViewportContainer::RenderSVGViewportContainer(SVGSVGElement& element, PassRef<RenderStyle> style)
+ : RenderSVGContainer(element, std::move(style))
, m_didTransformToRootUpdate(false)
, m_isLayoutSizeChanged(false)
, m_needsTransformUpdate(true)
@@ -40,7 +44,7 @@ RenderSVGViewportContainer::RenderSVGViewportContainer(SVGSVGElement& element, R
SVGSVGElement& RenderSVGViewportContainer::svgSVGElement() const
{
- return downcast<SVGSVGElement>(RenderSVGContainer::element());
+ return toSVGSVGElement(RenderSVGContainer::element());
}
void RenderSVGViewportContainer::determineIfLayoutSizeChanged()
@@ -56,17 +60,62 @@ void RenderSVGViewportContainer::applyViewportClip(PaintInfo& paintInfo)
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;
-
- m_viewport = newViewport;
-
- setNeedsBoundariesUpdate();
- setNeedsTransformUpdate();
+ SVGSVGElement& svg = svgSVGElement();
+ FloatRect oldViewport = m_viewport;
+
+ SVGLengthContext lengthContext(&svg);
+ m_viewport = FloatRect(svg.x().value(lengthContext), svg.y().value(lengthContext), svg.width().value(lengthContext), svg.height().value(lengthContext));
+
+ SVGElement* correspondingElement = svg.correspondingElement();
+ if (correspondingElement && svg.isInShadowTree()) {
+ const HashSet<SVGElementInstance*>& instances = correspondingElement->instancesForElement();
+ ASSERT(!instances.isEmpty());
+
+ SVGUseElement* useElement = 0;
+ const HashSet<SVGElementInstance*>::const_iterator end = instances.end();
+ for (HashSet<SVGElementInstance*>::const_iterator it = instances.begin(); it != end; ++it) {
+ const SVGElementInstance* instance = (*it);
+ ASSERT(instance->correspondingElement()->hasTagName(SVGNames::svgTag) || instance->correspondingElement()->hasTagName(SVGNames::symbolTag));
+ if (instance->shadowTreeElement() == &svg) {
+ ASSERT(correspondingElement == instance->correspondingElement());
+ useElement = instance->directUseElement();
+ if (!useElement)
+ useElement = instance->correspondingUseElement();
+ break;
+ }
+ }
+
+ ASSERT(useElement);
+ bool isSymbolElement = correspondingElement->hasTagName(SVGNames::symbolTag);
+
+ // Spec (<use> on <symbol>): This generated 'svg' will always have explicit values for attributes width and height.
+ // If attributes width and/or height are provided on the 'use' element, then these attributes
+ // will be transferred to the generated 'svg'. If attributes width and/or height are not specified,
+ // the generated 'svg' element will use values of 100% for these attributes.
+
+ // Spec (<use> on <svg>): If attributes width and/or height are provided on the 'use' element, then these
+ // values will override the corresponding attributes on the 'svg' in the generated tree.
+
+ SVGLengthContext lengthContext(&svg);
+ if (useElement->hasAttribute(SVGNames::widthAttr))
+ m_viewport.setWidth(useElement->width().value(lengthContext));
+ else if (isSymbolElement && svg.hasAttribute(SVGNames::widthAttr)) {
+ SVGLength containerWidth(LengthModeWidth, "100%");
+ m_viewport.setWidth(containerWidth.value(lengthContext));
+ }
+
+ if (useElement->hasAttribute(SVGNames::heightAttr))
+ m_viewport.setHeight(useElement->height().value(lengthContext));
+ else if (isSymbolElement && svg.hasAttribute(SVGNames::heightAttr)) {
+ SVGLength containerHeight(LengthModeHeight, "100%");
+ m_viewport.setHeight(containerHeight.value(lengthContext));
+ }
+ }
+
+ if (oldViewport != m_viewport) {
+ setNeedsBoundariesUpdate();
+ setNeedsTransformUpdate();
+ }
}
bool RenderSVGViewportContainer::calculateLocalTransform()
@@ -104,3 +153,5 @@ void RenderSVGViewportContainer::paint(PaintInfo& paintInfo, const LayoutPoint&
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
index 5969aeb67..182431eb5 100644
--- a/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
+++ b/Source/WebCore/rendering/svg/RenderSVGViewportContainer.h
@@ -23,6 +23,7 @@
#ifndef RenderSVGViewportContainer_h
#define RenderSVGViewportContainer_h
+#if ENABLE(SVG)
#include "RenderSVGContainer.h"
namespace WebCore {
@@ -31,34 +32,34 @@ namespace WebCore {
// thus we inherit from RenderSVGContainer instead of RenderSVGTransformableContainer
class RenderSVGViewportContainer final : public RenderSVGContainer {
public:
- RenderSVGViewportContainer(SVGSVGElement&, Ref<RenderStyle>&&);
+ RenderSVGViewportContainer(SVGSVGElement&, PassRef<RenderStyle>);
SVGSVGElement& svgSVGElement() const;
FloatRect viewport() const { return m_viewport; }
bool isLayoutSizeChanged() const { return m_isLayoutSizeChanged; }
- virtual bool didTransformToRootUpdate() override { return m_didTransformToRootUpdate; }
+ virtual bool didTransformToRootUpdate() { return m_didTransformToRootUpdate; }
- virtual void determineIfLayoutSizeChanged() override;
- virtual void setNeedsTransformUpdate() override { m_needsTransformUpdate = true; }
+ virtual void determineIfLayoutSizeChanged();
+ virtual void setNeedsTransformUpdate() { m_needsTransformUpdate = true; }
virtual void paint(PaintInfo&, const LayoutPoint&) override;
private:
void element() const = delete;
- virtual bool isSVGViewportContainer() const override { return true; }
- virtual const char* renderName() const override { return "RenderSVGViewportContainer"; }
+ virtual bool isSVGViewportContainer() const { return true; }
+ virtual const char* renderName() const { return "RenderSVGViewportContainer"; }
AffineTransform viewportTransform() const;
- virtual const AffineTransform& localToParentTransform() const override { return m_localToParentTransform; }
+ virtual const AffineTransform& localToParentTransform() const { return m_localToParentTransform; }
- virtual void calcViewport() override;
- virtual bool calculateLocalTransform() override;
+ virtual void calcViewport();
+ virtual bool calculateLocalTransform();
- virtual void applyViewportClip(PaintInfo&) override;
- virtual bool pointIsInsideViewportClip(const FloatPoint& pointInParent) override;
+ virtual void applyViewportClip(PaintInfo&);
+ virtual bool pointIsInsideViewportClip(const FloatPoint& pointInParent);
FloatRect m_viewport;
mutable AffineTransform m_localToParentTransform;
@@ -67,8 +68,9 @@ private:
bool m_needsTransformUpdate : 1;
};
-} // namespace WebCore
+RENDER_OBJECT_TYPE_CASTS(RenderSVGViewportContainer, isSVGViewportContainer())
-SPECIALIZE_TYPE_TRAITS_RENDER_OBJECT(RenderSVGViewportContainer, isSVGViewportContainer())
+} // namespace WebCore
+#endif // ENABLE(SVG)
#endif // RenderSVGViewportContainer_h
diff --git a/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp b/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp
index ad345f0c9..db017adba 100644
--- a/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineFlowBox.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer Inc.
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
@@ -23,6 +23,7 @@
#include "config.h"
#include "SVGInlineFlowBox.h"
+#if ENABLE(SVG)
#include "DocumentMarkerController.h"
#include "GraphicsContext.h"
#include "RenderedDocumentMarker.h"
@@ -38,14 +39,14 @@ void SVGInlineFlowBox::paintSelectionBackground(PaintInfo& paintInfo)
PaintInfo childPaintInfo(paintInfo);
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
- if (is<SVGInlineTextBox>(*child))
- downcast<SVGInlineTextBox>(*child).paintSelectionBackground(childPaintInfo);
- else if (is<SVGInlineFlowBox>(*child))
- downcast<SVGInlineFlowBox>(*child).paintSelectionBackground(childPaintInfo);
+ if (child->isSVGInlineTextBox())
+ toSVGInlineTextBox(child)->paintSelectionBackground(childPaintInfo);
+ else if (child->isSVGInlineFlowBox())
+ toSVGInlineFlowBox(child)->paintSelectionBackground(childPaintInfo);
}
}
-void SVGInlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
+void SVGInlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
{
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
ASSERT(!paintInfo.context->paintingDisabled());
@@ -53,10 +54,10 @@ void SVGInlineFlowBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
SVGRenderingContext renderingContext(renderer(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
if (renderingContext.isRenderingPrepared()) {
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
- if (is<SVGInlineTextBox>(*child))
- computeTextMatchMarkerRectForRenderer(&downcast<SVGInlineTextBox>(*child).renderer());
+ if (child->isSVGInlineTextBox())
+ computeTextMatchMarkerRectForRenderer(&(toSVGInlineTextBox(child)->renderer()));
- child->paint(paintInfo, paintOffset, 0, 0);
+ child->paint(paintInfo, LayoutPoint(), 0, 0);
}
}
}
@@ -83,21 +84,25 @@ void SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(RenderSVGInlineText
RenderStyle& style = textRenderer->style();
AffineTransform fragmentTransform;
- Vector<RenderedDocumentMarker*> markers = textRenderer->document().markers().markersFor(&textNode);
- for (auto* marker : markers) {
+ Vector<DocumentMarker*> markers = textRenderer->document().markers().markersFor(&textNode);
+
+ Vector<DocumentMarker*>::iterator markerEnd = markers.end();
+ for (Vector<DocumentMarker*>::iterator markerIt = markers.begin(); markerIt != markerEnd; ++markerIt) {
+ DocumentMarker* marker = *markerIt;
+
// SVG is only interessted in the TextMatch marker, for now.
if (marker->type() != DocumentMarker::TextMatch)
continue;
FloatRect markerRect;
for (InlineTextBox* box = textRenderer->firstTextBox(); box; box = box->nextTextBox()) {
- if (!is<SVGInlineTextBox>(*box))
+ if (!box->isSVGInlineTextBox())
continue;
- auto& textBox = downcast<SVGInlineTextBox>(*box);
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(box);
- int markerStartPosition = std::max<int>(marker->startOffset() - textBox.start(), 0);
- int markerEndPosition = std::min<int>(marker->endOffset() - textBox.start(), textBox.len());
+ int markerStartPosition = std::max<int>(marker->startOffset() - textBox->start(), 0);
+ int markerEndPosition = std::min<int>(marker->endOffset() - textBox->start(), textBox->len());
if (markerStartPosition >= markerEndPosition)
continue;
@@ -105,17 +110,17 @@ void SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(RenderSVGInlineText
int fragmentStartPosition = 0;
int fragmentEndPosition = 0;
- const Vector<SVGTextFragment>& fragments = textBox.textFragments();
+ const Vector<SVGTextFragment>& fragments = textBox->textFragments();
unsigned textFragmentsSize = fragments.size();
for (unsigned i = 0; i < textFragmentsSize; ++i) {
const SVGTextFragment& fragment = fragments.at(i);
fragmentStartPosition = markerStartPosition;
fragmentEndPosition = markerEndPosition;
- if (!textBox.mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
+ if (!textBox->mapStartEndPositionsIntoFragmentCoordinates(fragment, fragmentStartPosition, fragmentEndPosition))
continue;
- FloatRect fragmentRect = textBox.selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, &style);
+ FloatRect fragmentRect = textBox->selectionRectForTextFragment(fragment, fragmentStartPosition, fragmentEndPosition, &style);
fragment.buildFragmentTransform(fragmentTransform);
if (!fragmentTransform.isIdentity())
fragmentRect = fragmentTransform.mapRect(fragmentRect);
@@ -124,8 +129,10 @@ void SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(RenderSVGInlineText
}
}
- marker->setRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
+ toRenderedDocumentMarker(marker)->setRenderedRect(textRenderer->localToAbsoluteQuad(markerRect).enclosingBoundingBox());
}
}
} // namespace WebCore
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGInlineFlowBox.h b/Source/WebCore/rendering/svg/SVGInlineFlowBox.h
index 0dccc8f20..88165dfda 100644
--- a/Source/WebCore/rendering/svg/SVGInlineFlowBox.h
+++ b/Source/WebCore/rendering/svg/SVGInlineFlowBox.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer Inc.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Library General Public
@@ -21,6 +21,7 @@
#ifndef SVGInlineFlowBox_h
#define SVGInlineFlowBox_h
+#if ENABLE(SVG)
#include "InlineFlowBox.h"
#include "RenderSVGInline.h"
@@ -52,8 +53,10 @@ private:
float m_logicalHeight;
};
+INLINE_BOX_OBJECT_TYPE_CASTS(SVGInlineFlowBox, isSVGInlineFlowBox())
+
} // namespace WebCore
-SPECIALIZE_TYPE_TRAITS_INLINE_BOX(SVGInlineFlowBox, isSVGInlineFlowBox())
+#endif // ENABLE(SVG)
#endif // SVGInlineFlowBox_h
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
index 83b175dfc..f55976e95 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.cpp
@@ -22,6 +22,8 @@
#include "config.h"
#include "SVGInlineTextBox.h"
+#if ENABLE(SVG)
+#include "FontCache.h"
#include "Frame.h"
#include "FrameView.h"
#include "GraphicsContext.h"
@@ -29,14 +31,12 @@
#include "InlineFlowBox.h"
#include "PointerEventsHitRules.h"
#include "RenderBlock.h"
-#include "RenderInline.h"
#include "RenderSVGResourceSolidColor.h"
#include "RenderView.h"
#include "SVGRenderingContext.h"
#include "SVGResourcesCache.h"
#include "SVGRootInlineBox.h"
#include "SVGTextRunRenderingContext.h"
-#include "TextPainter.h"
namespace WebCore {
@@ -54,7 +54,7 @@ SVGInlineTextBox::SVGInlineTextBox(RenderSVGInlineText& renderer)
, m_logicalHeight(0)
, m_paintingResourceMode(ApplyToDefaultMode)
, m_startsNewTextChunk(false)
- , m_paintingResource(nullptr)
+ , m_paintingResource(0)
{
}
@@ -113,10 +113,12 @@ FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
ASSERT_WITH_SECURITY_IMPLICATION(startPosition < endPosition);
ASSERT(style);
+ FontCachePurgePreventer fontCachePurgePreventer;
+
float scalingFactor = renderer().scalingFactor();
ASSERT(scalingFactor);
- const FontCascade& scaledFont = renderer().scaledFont();
+ const Font& scaledFont = renderer().scaledFont();
const FontMetrics& scaledFontMetrics = scaledFont.fontMetrics();
FloatPoint textOrigin(fragment.x, fragment.y);
if (scalingFactor != 1)
@@ -124,15 +126,12 @@ FloatRect SVGInlineTextBox::selectionRectForTextFragment(const SVGTextFragment&
textOrigin.move(0, -scaledFontMetrics.floatAscent());
- LayoutRect selectionRect = LayoutRect(textOrigin, LayoutSize(0, fragment.height * scalingFactor));
- TextRun run = constructTextRun(style, fragment);
- scaledFont.adjustSelectionRectForText(run, selectionRect, startPosition, endPosition);
- FloatRect snappedSelectionRect = snapRectToDevicePixelsWithWritingDirection(selectionRect, renderer().document().deviceScaleFactor(), run.ltr());
+ FloatRect selectionRect = scaledFont.selectionRectForText(constructTextRun(style, fragment), textOrigin, fragment.height * scalingFactor, startPosition, endPosition);
if (scalingFactor == 1)
- return snappedSelectionRect;
+ return selectionRect;
- snappedSelectionRect.scale(1 / scalingFactor);
- return snappedSelectionRect;
+ selectionRect.scale(1 / scalingFactor);
+ return selectionRect;
}
LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPosition) const
@@ -172,7 +171,7 @@ LayoutRect SVGInlineTextBox::localSelectionRect(int startPosition, int endPositi
static inline bool textShouldBePainted(const RenderSVGInlineText& textRenderer)
{
- // FontCascade::pixelSize(), returns FontDescription::computedPixelSize(), which returns "int(x + 0.5)".
+ // Font::pixelSize(), returns FontDescription::computedPixelSize(), which returns "int(x + 0.5)".
// If the absolute font size on screen is below x=0.5, don't render anything.
return textRenderer.scaledFont().pixelSize();
}
@@ -186,7 +185,7 @@ void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
if (renderer().style().visibility() != VISIBLE)
return;
- auto& parentRenderer = parent()->renderer();
+ RenderObject& parentRenderer = parent()->renderer();
ASSERT(!parentRenderer.document().printing());
// Determine whether or not we're selected.
@@ -204,6 +203,13 @@ void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
RenderStyle& style = parentRenderer.style();
+ RenderStyle* selectionStyle = &style;
+ if (hasSelection) {
+ selectionStyle = parentRenderer.getCachedPseudoStyle(SELECTION);
+ if (!selectionStyle)
+ selectionStyle = &style;
+ }
+
int startPosition, endPosition;
selectionStartEnd(startPosition, endPosition);
@@ -234,7 +240,7 @@ void SVGInlineTextBox::paintSelectionBackground(PaintInfo& paintInfo)
ASSERT(!m_paintingResource);
}
-void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
+void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
{
ASSERT(paintInfo.shouldPaintWithinRoot(renderer()));
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
@@ -246,7 +252,7 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
// Note: We're explicitely not supporting composition & custom underlines and custom highlighters - unlike InlineTextBox.
// If we ever need that for SVG, it's very easy to refactor and reuse the code.
- auto& parentRenderer = parent()->renderer();
+ RenderObject& parentRenderer = parent()->renderer();
bool paintSelectedTextOnly = paintInfo.phase == PaintPhaseSelection;
bool hasSelection = !parentRenderer.document().printing() && selectionState() != RenderObject::SelectionNone;
@@ -300,24 +306,16 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
if (decorations & TextDecorationOverline)
paintDecoration(paintInfo.context, TextDecorationOverline, fragment);
- auto paintOrder = style.svgStyle().paintTypesForPaintOrder();
- for (unsigned i = 0; i < paintOrder.size(); ++i) {
- switch (paintOrder.at(i)) {
- case PaintTypeFill:
- if (!hasFill)
- continue;
- m_paintingResourceMode = ApplyToFillMode | ApplyToTextMode;
- paintText(paintInfo.context, &style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
- break;
- case PaintTypeStroke:
- if (!hasVisibleStroke)
- continue;
- m_paintingResourceMode = ApplyToStrokeMode | ApplyToTextMode;
- paintText(paintInfo.context, &style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
- break;
- case PaintTypeMarkers:
- continue;
- }
+ // Fill text
+ if (hasFill) {
+ m_paintingResourceMode = ApplyToFillMode | ApplyToTextMode;
+ paintText(paintInfo.context, &style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
+ }
+
+ // Stroke text
+ if (hasVisibleStroke) {
+ m_paintingResourceMode = ApplyToStrokeMode | ApplyToTextMode;
+ paintText(paintInfo.context, &style, selectionStyle, fragment, hasSelection, paintSelectedTextOnly);
}
// Spec: Line-through should be drawn after the text is filled and stroked; thus, the line-through is rendered on top of the text.
@@ -327,10 +325,6 @@ void SVGInlineTextBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
m_paintingResourceMode = ApplyToDefaultMode;
}
- // Finally, paint the outline if any.
- if (renderer().style().hasOutline() && is<RenderInline>(parentRenderer))
- downcast<RenderInline>(parentRenderer).paintOutline(paintInfo, paintOffset);
-
ASSERT(!m_paintingResource);
}
@@ -373,7 +367,7 @@ void SVGInlineTextBox::releasePaintingResource(GraphicsContext*& context, const
{
ASSERT(m_paintingResource);
- m_paintingResource->postApplyResource(parent()->renderer(), context, m_paintingResourceMode, path, /*RenderSVGShape*/ nullptr);
+ m_paintingResource->postApplyResource(parent()->renderer(), context, m_paintingResourceMode, path, /*RenderSVGShape*/ 0);
m_paintingResource = nullptr;
}
@@ -388,8 +382,6 @@ bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& c
TextRun::RenderingContext* renderingContext = textRun.renderingContext();
if (renderingContext)
static_cast<SVGTextRunRenderingContext*>(renderingContext)->setActivePaintingResource(m_paintingResource);
-#else
- UNUSED_PARAM(textRun);
#endif
return true;
@@ -397,12 +389,12 @@ bool SVGInlineTextBox::prepareGraphicsContextForTextPainting(GraphicsContext*& c
void SVGInlineTextBox::restoreGraphicsContextAfterTextPainting(GraphicsContext*& context, TextRun& textRun)
{
- releasePaintingResource(context, /* path */nullptr);
+ releasePaintingResource(context, /* path */0);
#if ENABLE(SVG_FONTS)
TextRun::RenderingContext* renderingContext = textRun.renderingContext();
if (renderingContext)
- static_cast<SVGTextRunRenderingContext*>(renderingContext)->setActivePaintingResource(nullptr);
+ static_cast<SVGTextRunRenderingContext*>(renderingContext)->setActivePaintingResource(0);
#else
UNUSED_PARAM(textRun);
#endif
@@ -412,14 +404,15 @@ TextRun SVGInlineTextBox::constructTextRun(RenderStyle* style, const SVGTextFrag
{
ASSERT(style);
- TextRun run(StringView(renderer().text()).substring(fragment.characterOffset, fragment.length)
+ TextRun run(renderer().deprecatedCharacters() + fragment.characterOffset
+ , fragment.length
, 0 /* xPos, only relevant with allowTabs=true */
, 0 /* padding, only relevant for justified text, not relevant for SVG */
- , AllowTrailingExpansion
+ , TextRun::AllowTrailingExpansion
, direction()
, dirOverride() || style->rtlOrdering() == VisualOrder /* directionalOverride */);
- if (style->fontCascade().primaryFont().isSVGFont())
+ if (style->font().isSVGFont())
run.setRenderingContext(SVGTextRunRenderingContext::create(renderer()));
run.disableRoundingHacks();
@@ -475,7 +468,7 @@ static inline float positionOffsetForDecoration(TextDecoration decoration, const
return 0.0f;
}
-static inline float thicknessForDecoration(TextDecoration, const FontCascade& font)
+static inline float thicknessForDecoration(TextDecoration, const Font& font)
{
// FIXME: For SVG Fonts we need to use the attributes defined in the <font-face> if specified.
// Compatible with Batik/Opera
@@ -535,8 +528,8 @@ void SVGInlineTextBox::paintDecorationWithStyle(GraphicsContext* context, TextDe
RenderStyle& decorationStyle = decorationRenderer.style();
float scalingFactor = 1;
- FontCascade scaledFont;
- RenderSVGInlineText::computeNewScaledFontForStyle(decorationRenderer, decorationStyle, scalingFactor, scaledFont);
+ Font scaledFont;
+ RenderSVGInlineText::computeNewScaledFontForStyle(&decorationRenderer, &decorationStyle, scalingFactor, scaledFont);
ASSERT(scalingFactor);
// The initial y value refers to overline position.
@@ -570,7 +563,7 @@ void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
float scalingFactor = renderer().scalingFactor();
ASSERT(scalingFactor);
- const FontCascade& scaledFont = renderer().scaledFont();
+ const Font& scaledFont = renderer().scaledFont();
const ShadowData* shadow = style->textShadow();
FloatPoint textOrigin(fragment.x, fragment.y);
@@ -587,24 +580,27 @@ void SVGInlineTextBox::paintTextWithShadows(GraphicsContext* context, RenderStyl
if (!prepareGraphicsContextForTextPainting(context, scalingFactor, textRun, style))
break;
- {
- ShadowApplier shadowApplier(*context, shadow, shadowRect);
+ FloatSize extraOffset;
+ if (shadow)
+ extraOffset = applyShadowToGraphicsContext(context, shadow, shadowRect, false /* stroked */, true /* opaque */, true /* horizontal */);
- if (!shadowApplier.didSaveContext())
- context->save();
- context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
+ context->save();
+ context->scale(FloatSize(1 / scalingFactor, 1 / scalingFactor));
- scaledFont.drawText(context, textRun, textOrigin + shadowApplier.extraOffset(), startPosition, endPosition);
+ scaledFont.drawText(context, textRun, textOrigin + extraOffset, startPosition, endPosition);
- if (!shadowApplier.didSaveContext())
- context->restore();
- }
+ context->restore();
restoreGraphicsContextAfterTextPainting(context, textRun);
if (!shadow)
break;
+ if (shadow->next())
+ context->restore();
+ else
+ context->clearShadow();
+
shadow = shadow->next();
} while (shadow);
}
@@ -671,7 +667,7 @@ FloatRect SVGInlineTextBox::calculateBoundaries() const
return textRect;
}
-bool SVGInlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit, LayoutUnit, HitTestAction)
+bool SVGInlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit, LayoutUnit)
{
// FIXME: integrate with InlineTextBox::nodeAtPoint better.
ASSERT(!isLineBreak());
@@ -695,3 +691,5 @@ bool SVGInlineTextBox::nodeAtPoint(const HitTestRequest& request, HitTestResult&
}
} // namespace WebCore
+
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGInlineTextBox.h b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
index 23c0769fe..97df4d698 100644
--- a/Source/WebCore/rendering/svg/SVGInlineTextBox.h
+++ b/Source/WebCore/rendering/svg/SVGInlineTextBox.h
@@ -22,6 +22,7 @@
#ifndef SVGInlineTextBox_h
#define SVGInlineTextBox_h
+#if ENABLE(SVG)
#include "InlineTextBox.h"
#include "SVGTextLayoutEngine.h"
#include "RenderSVGInlineText.h"
@@ -35,30 +36,30 @@ class SVGInlineTextBox final : public InlineTextBox {
public:
explicit SVGInlineTextBox(RenderSVGInlineText&);
- RenderSVGInlineText& renderer() const { return downcast<RenderSVGInlineText>(InlineTextBox::renderer()); }
+ RenderSVGInlineText& renderer() const { return toRenderSVGInlineText(InlineTextBox::renderer()); }
- virtual float virtualLogicalHeight() const override { return m_logicalHeight; }
+ virtual float virtualLogicalHeight() const { return m_logicalHeight; }
void setLogicalHeight(float height) { m_logicalHeight = height; }
- int selectionTop() { return top(); }
- int selectionHeight() { return static_cast<int>(ceilf(m_logicalHeight)); }
- virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const override;
- virtual float positionForOffset(int offset) const override;
+ virtual int selectionTop() { return top(); }
+ virtual int selectionHeight() { return static_cast<int>(ceilf(m_logicalHeight)); }
+ virtual int offsetForPosition(float x, bool includePartialGlyphs = true) const;
+ virtual float positionForOffset(int offset) const;
void paintSelectionBackground(PaintInfo&);
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom);
virtual LayoutRect localSelectionRect(int startPosition, int endPosition) const override;
bool mapStartEndPositionsIntoFragmentCoordinates(const SVGTextFragment&, int& startPosition, int& endPosition) const;
- virtual FloatRect calculateBoundaries() const override;
+ virtual FloatRect calculateBoundaries() const;
void clearTextFragments() { m_textFragments.clear(); }
Vector<SVGTextFragment>& textFragments() { return m_textFragments; }
const Vector<SVGTextFragment>& textFragments() const { return m_textFragments; }
- virtual void dirtyOwnLineBoxes() override;
- virtual void dirtyLineBoxes() override;
+ virtual void dirtyOwnLineBoxes() override final;
+ virtual void dirtyLineBoxes() override final;
bool startsNewTextChunk() const { return m_startsNewTextChunk; }
void setStartsNewTextChunk(bool newTextChunk) { m_startsNewTextChunk = newTextChunk; }
@@ -82,7 +83,7 @@ private:
void paintTextWithShadows(GraphicsContext*, RenderStyle*, TextRun&, const SVGTextFragment&, int startPosition, int endPosition);
void paintText(GraphicsContext*, RenderStyle*, RenderStyle* selectionStyle, const SVGTextFragment&, bool hasSelection, bool paintSelectedTextOnly);
- virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom, HitTestAction) override;
+ virtual bool nodeAtPoint(const HitTestRequest&, HitTestResult&, const HitTestLocation& locationInContainer, const LayoutPoint& accumulatedOffset, LayoutUnit lineTop, LayoutUnit lineBottom) override;
private:
float m_logicalHeight;
@@ -92,8 +93,9 @@ private:
Vector<SVGTextFragment> m_textFragments;
};
-} // namespace WebCore
+INLINE_BOX_OBJECT_TYPE_CASTS(SVGInlineTextBox, isSVGInlineTextBox())
-SPECIALIZE_TYPE_TRAITS_INLINE_BOX(SVGInlineTextBox, isSVGInlineTextBox())
+} // namespace WebCore
+#endif
#endif // SVGInlineTextBox_h
diff --git a/Source/WebCore/rendering/svg/SVGMarkerData.h b/Source/WebCore/rendering/svg/SVGMarkerData.h
index 16b10ebd9..5d5a86d98 100644
--- a/Source/WebCore/rendering/svg/SVGMarkerData.h
+++ b/Source/WebCore/rendering/svg/SVGMarkerData.h
@@ -20,8 +20,10 @@
#ifndef SVGMarkerData_h
#define SVGMarkerData_h
+#if ENABLE(SVG)
#include "FloatConversion.h"
#include "Path.h"
+#include <wtf/MathExtras.h>
namespace WebCore {
@@ -54,20 +56,22 @@ public:
{
}
- static void updateFromPathElement(SVGMarkerData& markerData, const PathElement& element)
+ static void updateFromPathElement(void* info, const PathElement* element)
{
+ SVGMarkerData* markerData = static_cast<SVGMarkerData*>(info);
+
// First update the outslope for the previous element.
- markerData.updateOutslope(element.points[0]);
+ markerData->updateOutslope(element->points[0]);
// Record the marker for the previous element.
- if (markerData.m_elementIndex > 0) {
- SVGMarkerType markerType = markerData.m_elementIndex == 1 ? StartMarker : MidMarker;
- markerData.m_positions.append(MarkerPosition(markerType, markerData.m_origin, markerData.currentAngle(markerType)));
+ if (markerData->m_elementIndex > 0) {
+ SVGMarkerType markerType = markerData->m_elementIndex == 1 ? StartMarker : MidMarker;
+ markerData->m_positions.append(MarkerPosition(markerType, markerData->m_origin, markerData->currentAngle(markerType)));
}
// Update our marker data for this element.
- markerData.updateMarkerDataForPathElement(element);
- ++markerData.m_elementIndex;
+ markerData->updateMarkerDataForPathElement(element);
+ ++markerData->m_elementIndex;
}
void pathIsDone()
@@ -107,11 +111,11 @@ private:
m_outslopePoints[1] = point;
}
- void updateMarkerDataForPathElement(const PathElement& element)
+ void updateMarkerDataForPathElement(const PathElement* element)
{
- FloatPoint* points = element.points;
+ FloatPoint* points = element->points;
- switch (element.type) {
+ switch (element->type) {
case PathElementAddQuadCurveToPoint:
// FIXME: https://bugs.webkit.org/show_bug.cgi?id=33115 (PathElementAddQuadCurveToPoint not handled for <marker>)
m_origin = points[1];
@@ -151,4 +155,5 @@ private:
}
+#endif // ENABLE(SVG)
#endif // SVGMarkerData_h
diff --git a/Source/WebCore/rendering/svg/SVGPathData.cpp b/Source/WebCore/rendering/svg/SVGPathData.cpp
index 2743f52a9..01ef871f7 100644
--- a/Source/WebCore/rendering/svg/SVGPathData.cpp
+++ b/Source/WebCore/rendering/svg/SVGPathData.cpp
@@ -20,12 +20,10 @@
#include "config.h"
#include "SVGPathData.h"
+#if ENABLE(SVG)
#include "Path.h"
-#include "RenderElement.h"
-#include "RenderStyle.h"
#include "SVGCircleElement.h"
#include "SVGEllipseElement.h"
-#include "SVGLengthContext.h"
#include "SVGLineElement.h"
#include "SVGNames.h"
#include "SVGPathElement.h"
@@ -39,42 +37,32 @@ namespace WebCore {
static void updatePathFromCircleElement(SVGElement* element, Path& path)
{
- ASSERT(is<SVGCircleElement>(element));
+ ASSERT(isSVGCircleElement(element));
+ SVGCircleElement* circle = toSVGCircleElement(element);
SVGLengthContext lengthContext(element);
- RenderElement* renderer = element->renderer();
- if (!renderer)
- return;
- RenderStyle& style = renderer->style();
- float r = lengthContext.valueForLength(style.svgStyle().r());
- if (r > 0) {
- float cx = lengthContext.valueForLength(style.svgStyle().cx(), LengthModeWidth);
- float cy = lengthContext.valueForLength(style.svgStyle().cy(), LengthModeHeight);
- path.addEllipse(FloatRect(cx - r, cy - r, r * 2, r * 2));
- }
+ float r = circle->r().value(lengthContext);
+ if (r > 0)
+ path.addEllipse(FloatRect(circle->cx().value(lengthContext) - r, circle->cy().value(lengthContext) - r, r * 2, r * 2));
}
static void updatePathFromEllipseElement(SVGElement* element, Path& path)
{
- RenderElement* renderer = element->renderer();
- if (!renderer)
- return;
- RenderStyle& style = renderer->style();
+ SVGEllipseElement* ellipse = toSVGEllipseElement(element);
+
SVGLengthContext lengthContext(element);
- float rx = lengthContext.valueForLength(style.svgStyle().rx(), LengthModeWidth);
+ float rx = ellipse->rx().value(lengthContext);
if (rx <= 0)
return;
- float ry = lengthContext.valueForLength(style.svgStyle().ry(), LengthModeHeight);
+ float ry = ellipse->ry().value(lengthContext);
if (ry <= 0)
return;
- float cx = lengthContext.valueForLength(style.svgStyle().cx(), LengthModeWidth);
- float cy = lengthContext.valueForLength(style.svgStyle().cy(), LengthModeHeight);
- path.addEllipse(FloatRect(cx - rx, cy - ry, rx * 2, ry * 2));
+ path.addEllipse(FloatRect(ellipse->cx().value(lengthContext) - rx, ellipse->cy().value(lengthContext) - ry, rx * 2, ry * 2));
}
static void updatePathFromLineElement(SVGElement* element, Path& path)
{
- SVGLineElement* line = downcast<SVGLineElement>(element);
+ SVGLineElement* line = toSVGLineElement(element);
SVGLengthContext lengthContext(element);
path.moveTo(FloatPoint(line->x1().value(lengthContext), line->y1().value(lengthContext)));
@@ -83,12 +71,12 @@ static void updatePathFromLineElement(SVGElement* element, Path& path)
static void updatePathFromPathElement(SVGElement* element, Path& path)
{
- buildPathFromByteStream(downcast<SVGPathElement>(element)->pathByteStream(), path);
+ buildPathFromByteStream(toSVGPathElement(element)->pathByteStream(), path);
}
static void updatePathFromPolygonElement(SVGElement* element, Path& path)
{
- SVGPointList& points = downcast<SVGPolygonElement>(element)->animatedPoints()->values();
+ SVGPointList& points = toSVGPolygonElement(element)->animatedPoints()->values();
if (points.isEmpty())
return;
@@ -103,7 +91,7 @@ static void updatePathFromPolygonElement(SVGElement* element, Path& path)
static void updatePathFromPolylineElement(SVGElement* element, Path& path)
{
- SVGPointList& points = downcast<SVGPolylineElement>(element)->animatedPoints()->values();
+ SVGPointList& points = toSVGPolylineElement(element)->animatedPoints()->values();
if (points.isEmpty())
return;
@@ -116,22 +104,19 @@ static void updatePathFromPolylineElement(SVGElement* element, Path& path)
static void updatePathFromRectElement(SVGElement* element, Path& path)
{
- RenderElement* renderer = element->renderer();
- if (!renderer)
- return;
+ SVGRectElement* rect = toSVGRectElement(element);
- RenderStyle& style = renderer->style();
SVGLengthContext lengthContext(element);
- float width = lengthContext.valueForLength(style.width(), LengthModeWidth);
+ float width = rect->width().value(lengthContext);
if (width <= 0)
return;
- float height = lengthContext.valueForLength(style.height(), LengthModeHeight);
+ float height = rect->height().value(lengthContext);
if (height <= 0)
return;
- float x = lengthContext.valueForLength(style.svgStyle().x(), LengthModeWidth);
- float y = lengthContext.valueForLength(style.svgStyle().y(), LengthModeHeight);
- float rx = lengthContext.valueForLength(style.svgStyle().rx(), LengthModeWidth);
- float ry = lengthContext.valueForLength(style.svgStyle().ry(), LengthModeHeight);
+ float x = rect->x().value(lengthContext);
+ float y = rect->y().value(lengthContext);
+ float rx = rect->rx().value(lengthContext);
+ float ry = rect->ry().value(lengthContext);
bool hasRx = rx > 0;
bool hasRy = ry > 0;
if (hasRx || hasRy) {
@@ -172,3 +157,5 @@ void updatePathFromGraphicsElement(SVGElement* element, Path& path)
}
} // namespace WebCore
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGPathData.h b/Source/WebCore/rendering/svg/SVGPathData.h
index 4a6289748..1a4b7ba89 100644
--- a/Source/WebCore/rendering/svg/SVGPathData.h
+++ b/Source/WebCore/rendering/svg/SVGPathData.h
@@ -20,6 +20,7 @@
#ifndef SVGPathData_h
#define SVGPathData_h
+#if ENABLE(SVG)
namespace WebCore {
class SVGElement;
@@ -29,4 +30,5 @@ void updatePathFromGraphicsElement(SVGElement*, Path&);
};
+#endif // ENABLE(SVG)
#endif // SVGPathData_h
diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
index 2b17b2ccc..9602927f2 100644
--- a/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.cpp
@@ -23,6 +23,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGRenderSupport.h"
#include "NodeRenderStyle.h"
@@ -30,14 +32,12 @@
#include "RenderGeometryMap.h"
#include "RenderIterator.h"
#include "RenderLayer.h"
-#include "RenderSVGImage.h"
#include "RenderSVGResourceClipper.h"
#include "RenderSVGResourceFilter.h"
#include "RenderSVGResourceMarker.h"
#include "RenderSVGResourceMasker.h"
#include "RenderSVGRoot.h"
#include "RenderSVGText.h"
-#include "RenderSVGTransformableContainer.h"
#include "RenderSVGViewportContainer.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
@@ -49,8 +49,8 @@ FloatRect SVGRenderSupport::repaintRectForRendererInLocalCoordinatesExcludingSVG
{
// FIXME: Add support for RenderSVGBlock.
- if (is<RenderSVGModelObject>(renderer))
- return downcast<RenderSVGModelObject>(renderer).repaintRectInLocalCoordinatesExcludingSVGShadow();
+ if (renderer.isSVGShape() || renderer.isSVGImage() || renderer.isSVGContainer())
+ return toRenderSVGModelObject(renderer).repaintRectInLocalCoordinatesExcludingSVGShadow();
return renderer.repaintRectInLocalCoordinates();
}
@@ -83,27 +83,18 @@ void SVGRenderSupport::computeFloatRectForRepaint(const RenderElement& renderer,
renderer.parent()->computeFloatRectForRepaint(repaintContainer, repaintRect, fixed);
}
-const RenderElement& SVGRenderSupport::localToParentTransform(const RenderElement& renderer, AffineTransform &transform)
+void SVGRenderSupport::mapLocalToContainer(const RenderElement& renderer, const RenderLayerModelObject* repaintContainer, TransformState& transformState, bool* wasFixed)
{
+ transformState.applyTransform(renderer.localToParentTransform());
+
ASSERT(renderer.parent());
auto& parent = *renderer.parent();
-
- // At the SVG/HTML boundary (aka RenderSVGRoot), we apply the localToBorderBoxTransform
+
+ // At the SVG/HTML boundary (aka RenderSVGRoot), we apply the localToBorderBoxTransform
// to map an element from SVG viewport coordinates to CSS box coordinates.
- if (is<RenderSVGRoot>(parent))
- transform = downcast<RenderSVGRoot>(parent).localToBorderBoxTransform() * renderer.localToParentTransform();
- else
- transform = renderer.localToParentTransform();
-
- return parent;
-}
-
-void SVGRenderSupport::mapLocalToContainer(const RenderElement& renderer, const RenderLayerModelObject* repaintContainer, TransformState& transformState, bool* wasFixed)
-{
- AffineTransform transform;
- auto& parent = localToParentTransform(renderer, transform);
-
- transformState.applyTransform(transform);
+ // RenderSVGRoot's mapLocalToContainer method expects CSS box coordinates.
+ if (parent.isSVGRoot())
+ transformState.applyTransform(toRenderSVGRoot(parent).localToBorderBoxTransform());
MapCoordinatesFlags mode = UseTransforms;
parent.mapLocalToContainer(repaintContainer, transformState, mode, wasFixed);
@@ -113,10 +104,19 @@ const RenderElement* SVGRenderSupport::pushMappingToContainer(const RenderElemen
{
ASSERT_UNUSED(ancestorToStopAt, ancestorToStopAt != &renderer);
- AffineTransform transform;
- auto& parent = localToParentTransform(renderer, transform);
+ ASSERT(renderer.parent());
+ auto& parent = *renderer.parent();
+
+ // At the SVG/HTML boundary (aka RenderSVGRoot), we apply the localToBorderBoxTransform
+ // to map an element from SVG viewport coordinates to CSS box coordinates.
+ // RenderSVGRoot's mapLocalToContainer method expects CSS box coordinates.
+ if (parent.isSVGRoot()) {
+ TransformationMatrix matrix(renderer.localToParentTransform());
+ matrix.multiply(toRenderSVGRoot(parent).localToBorderBoxTransform());
+ geometryMap.push(&renderer, matrix);
+ } else
+ geometryMap.push(&renderer, renderer.localToParentTransform());
- geometryMap.push(&renderer, transform);
return &parent;
}
@@ -127,13 +127,13 @@ bool SVGRenderSupport::checkForSVGRepaintDuringLayout(const RenderElement& rende
// When a parent container is transformed in SVG, all children will be painted automatically
// so we are able to skip redundant repaint checks.
auto parent = renderer.parent();
- return !(is<RenderSVGContainer>(parent) && downcast<RenderSVGContainer>(*parent).didTransformToRootUpdate());
+ return !(parent && parent->isSVGContainer() && toRenderSVGContainer(parent)->didTransformToRootUpdate());
}
// Update a bounding box taking into account the validity of the other bounding box.
static inline void updateObjectBoundingBox(FloatRect& objectBoundingBox, bool& objectBoundingBoxValid, RenderObject* other, FloatRect otherBoundingBox)
{
- bool otherValid = is<RenderSVGContainer>(*other) ? downcast<RenderSVGContainer>(*other).isObjectBoundingBoxValid() : true;
+ bool otherValid = other->isSVGContainer() ? toRenderSVGContainer(other)->isObjectBoundingBoxValid() : true;
if (!otherValid)
return;
@@ -159,10 +159,6 @@ void SVGRenderSupport::computeContainerBoundingBoxes(const RenderElement& contai
if (current->isSVGHiddenContainer())
continue;
- // Don't include elements in the union that do not render.
- if (is<RenderSVGShape>(*current) && downcast<RenderSVGShape>(*current).isRenderingDisabled())
- continue;
-
const AffineTransform& transform = current->localToParentTransform();
if (transform.isIdentity()) {
updateObjectBoundingBox(objectBoundingBox, objectBoundingBoxValid, current, current->objectBoundingBox());
@@ -189,36 +185,37 @@ const RenderSVGRoot& SVGRenderSupport::findTreeRootObject(const RenderElement& s
return *lineageOfType<RenderSVGRoot>(start).first();
}
-static inline void invalidateResourcesOfChildren(RenderElement& renderer)
+static inline void invalidateResourcesOfChildren(RenderObject& start)
{
- ASSERT(!renderer.needsLayout());
- if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer))
- resources->removeClientFromCache(renderer, false);
+ ASSERT(!start.needsLayout());
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(start))
+ resources->removeClientFromCache(start, false);
- for (auto& child : childrenOfType<RenderElement>(renderer))
- invalidateResourcesOfChildren(child);
+ for (RenderObject* child = start.firstChildSlow(); child; child = child->nextSibling())
+ invalidateResourcesOfChildren(*child);
}
static inline bool layoutSizeOfNearestViewportChanged(const RenderElement& renderer)
{
const RenderElement* start = &renderer;
- while (start && !is<RenderSVGRoot>(*start) && !is<RenderSVGViewportContainer>(*start))
+ while (start && !start->isSVGRoot() && !start->isSVGViewportContainer())
start = start->parent();
ASSERT(start);
- if (is<RenderSVGViewportContainer>(*start))
- return downcast<RenderSVGViewportContainer>(*start).isLayoutSizeChanged();
+ ASSERT(start->isSVGRoot() || start->isSVGViewportContainer());
+ if (start->isSVGViewportContainer())
+ return toRenderSVGViewportContainer(start)->isLayoutSizeChanged();
- return downcast<RenderSVGRoot>(*start).isLayoutSizeChanged();
+ return toRenderSVGRoot(start)->isLayoutSizeChanged();
}
bool SVGRenderSupport::transformToRootChanged(RenderElement* ancestor)
{
- while (ancestor && !is<RenderSVGRoot>(*ancestor)) {
- if (is<RenderSVGTransformableContainer>(*ancestor))
- return downcast<RenderSVGTransformableContainer>(*ancestor).didTransformToRootUpdate();
- if (is<RenderSVGViewportContainer>(*ancestor))
- return downcast<RenderSVGViewportContainer>(*ancestor).didTransformToRootUpdate();
+ while (ancestor && !ancestor->isSVGRoot()) {
+ if (ancestor->isSVGTransformableContainer())
+ return toRenderSVGContainer(ancestor)->didTransformToRootUpdate();
+ if (ancestor->isSVGViewportContainer())
+ return toRenderSVGViewportContainer(ancestor)->didTransformToRootUpdate();
ancestor = ancestor->parent();
}
@@ -231,7 +228,7 @@ void SVGRenderSupport::layoutChildren(RenderElement& start, bool selfNeedsLayout
bool transformChanged = transformToRootChanged(&start);
bool hasSVGShadow = rendererHasSVGShadow(start);
bool needsBoundariesUpdate = start.needsBoundariesUpdate();
- HashSet<RenderElement*> elementsThatDidNotReceiveLayout;
+ HashSet<RenderObject*> notlayoutedObjects;
for (RenderObject* child = start.firstChild(); child; child = child->nextSibling()) {
bool needsLayout = selfNeedsLayout;
@@ -246,22 +243,21 @@ void SVGRenderSupport::layoutChildren(RenderElement& start, bool selfNeedsLayout
if (transformChanged) {
// If the transform changed we need to update the text metrics (note: this also happens for layoutSizeChanged=true).
- if (is<RenderSVGText>(*child))
- downcast<RenderSVGText>(*child).setNeedsTextMetricsUpdate();
+ if (child->isSVGText())
+ toRenderSVGText(child)->setNeedsTextMetricsUpdate();
needsLayout = true;
}
if (layoutSizeChanged) {
// When selfNeedsLayout is false and the layout size changed, we have to check whether this child uses relative lengths
- if (SVGElement* element = is<SVGElement>(*child->node()) ? downcast<SVGElement>(child->node()) : nullptr) {
+ if (SVGElement* element = child->node()->isSVGElement() ? toSVGElement(child->node()) : 0) {
if (element->hasRelativeLengths()) {
// When the layout size changed and when using relative values tell the RenderSVGShape to update its shape object
- if (is<RenderSVGShape>(*child))
- downcast<RenderSVGShape>(*child).setNeedsShapeUpdate();
- else if (is<RenderSVGText>(*child)) {
- RenderSVGText& svgText = downcast<RenderSVGText>(*child);
- svgText.setNeedsTextMetricsUpdate();
- svgText.setNeedsPositioningValuesUpdate();
+ if (child->isSVGShape())
+ toRenderSVGShape(child)->setNeedsShapeUpdate();
+ else if (child->isSVGText()) {
+ toRenderSVGText(child)->setNeedsTextMetricsUpdate();
+ toRenderSVGText(child)->setNeedsPositioningValuesUpdate();
}
needsLayout = true;
@@ -273,46 +269,52 @@ void SVGRenderSupport::layoutChildren(RenderElement& start, bool selfNeedsLayout
child->setNeedsLayout(MarkOnlyThis);
if (child->needsLayout()) {
- downcast<RenderElement>(*child).layout();
+ toRenderElement(child)->layout();
// Renderers are responsible for repainting themselves when changing, except
// for the initial paint to avoid potential double-painting caused by non-sensical "old" bounds.
// We could handle this in the individual objects, but for now it's easier to have
// parent containers call repaint(). (RenderBlock::layout* has similar logic.)
if (!childEverHadLayout)
child->repaint();
- } else if (layoutSizeChanged && is<RenderElement>(*child))
- elementsThatDidNotReceiveLayout.add(downcast<RenderElement>(child));
+ } else if (layoutSizeChanged)
+ notlayoutedObjects.add(child);
ASSERT(!child->needsLayout());
}
if (!layoutSizeChanged) {
- ASSERT(elementsThatDidNotReceiveLayout.isEmpty());
+ ASSERT(notlayoutedObjects.isEmpty());
return;
}
// If the layout size changed, invalidate all resources of all children that didn't go through the layout() code path.
- for (auto* element : elementsThatDidNotReceiveLayout)
- invalidateResourcesOfChildren(*element);
+ for (auto child : notlayoutedObjects)
+ invalidateResourcesOfChildren(*child);
}
bool SVGRenderSupport::isOverflowHidden(const RenderElement& renderer)
{
+ // SVG doesn't support independent x/y overflow
+ ASSERT(renderer.style().overflowX() == renderer.style().overflowY());
+
+ // OSCROLL is never set for SVG - see StyleResolver::adjustRenderStyle
+ ASSERT(renderer.style().overflowX() != OSCROLL);
+
// RenderSVGRoot should never query for overflow state - it should always clip itself to the initial viewport size.
ASSERT(!renderer.isRoot());
- return renderer.style().overflowX() == OHIDDEN || renderer.style().overflowX() == OSCROLL;
+ return renderer.style().overflowX() == OHIDDEN;
}
bool SVGRenderSupport::rendererHasSVGShadow(const RenderObject& renderer)
{
// FIXME: Add support for RenderSVGBlock.
- if (is<RenderSVGModelObject>(renderer))
- return downcast<RenderSVGModelObject>(renderer).hasSVGShadow();
+ if (renderer.isSVGShape() || renderer.isSVGImage() || renderer.isSVGContainer())
+ return toRenderSVGModelObject(renderer).hasSVGShadow();
- if (is<RenderSVGRoot>(renderer))
- return downcast<RenderSVGRoot>(renderer).hasSVGShadow();
+ if (renderer.isSVGRoot())
+ return toRenderSVGRoot(renderer).hasSVGShadow();
return false;
}
@@ -321,13 +323,13 @@ void SVGRenderSupport::setRendererHasSVGShadow(RenderObject& renderer, bool hasS
{
// FIXME: Add support for RenderSVGBlock.
- if (is<RenderSVGModelObject>(renderer)) {
- downcast<RenderSVGModelObject>(renderer).setHasSVGShadow(hasShadow);
+ if (renderer.isSVGShape() || renderer.isSVGImage() || renderer.isSVGContainer()) {
+ toRenderSVGModelObject(renderer).setHasSVGShadow(hasShadow);
return;
}
- if (is<RenderSVGRoot>(renderer))
- downcast<RenderSVGRoot>(renderer).setHasSVGShadow(hasShadow);
+ if (renderer.isSVGRoot())
+ toRenderSVGRoot(renderer).setHasSVGShadow(hasShadow);
}
void SVGRenderSupport::intersectRepaintRectWithShadows(const RenderElement& renderer, FloatRect& repaintRect)
@@ -361,12 +363,14 @@ void SVGRenderSupport::intersectRepaintRectWithShadows(const RenderElement& rend
void SVGRenderSupport::intersectRepaintRectWithResources(const RenderElement& renderer, FloatRect& repaintRect)
{
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
if (!resources)
return;
+#if ENABLE(FILTERS)
if (RenderSVGResourceFilter* filter = resources->filter())
repaintRect = filter->resourceBoundingBox(renderer);
+#endif
if (RenderSVGResourceClipper* clipper = resources->clipper())
repaintRect.intersect(clipper->resourceBoundingBox(renderer));
@@ -382,7 +386,7 @@ bool SVGRenderSupport::filtersForceContainerLayout(const RenderElement& renderer
if (!renderer.normalChildNeedsLayout())
return false;
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
if (!resources || !resources->filter())
return false;
@@ -393,7 +397,7 @@ bool SVGRenderSupport::pointInClippingArea(const RenderElement& renderer, const
{
// We just take clippers into account to determine if a point is on the node. The Specification may
// change later and we also need to check maskers.
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
if (!resources)
return true;
@@ -411,8 +415,8 @@ void SVGRenderSupport::applyStrokeStyleToContext(GraphicsContext* context, const
const SVGRenderStyle& svgStyle = style.svgStyle();
- SVGLengthContext lengthContext(downcast<SVGElement>(renderer.element()));
- context->setStrokeThickness(lengthContext.valueForLength(svgStyle.strokeWidth()));
+ SVGLengthContext lengthContext(toSVGElement(renderer.element()));
+ context->setStrokeThickness(svgStyle.strokeWidth().value(lengthContext));
context->setLineCap(svgStyle.capStyle());
context->setLineJoin(svgStyle.joinStyle());
if (svgStyle.joinStyle() == MiterJoin)
@@ -424,10 +428,10 @@ void SVGRenderSupport::applyStrokeStyleToContext(GraphicsContext* context, const
else {
DashArray dashArray;
dashArray.reserveInitialCapacity(dashes.size());
- for (auto& dash : dashes)
- dashArray.uncheckedAppend(dash.value(lengthContext));
+ for (unsigned i = 0, size = dashes.size(); i < size; ++i)
+ dashArray.uncheckedAppend(dashes[i].value(lengthContext));
- context->setLineDash(dashArray, lengthContext.valueForLength(svgStyle.strokeDashOffset()));
+ context->setLineDash(dashArray, svgStyle.strokeDashOffset().value(lengthContext));
}
}
@@ -436,40 +440,12 @@ void SVGRenderSupport::childAdded(RenderElement& parent, RenderObject& child)
SVGRenderSupport::setRendererHasSVGShadow(child, SVGRenderSupport::rendererHasSVGShadow(parent) || SVGRenderSupport::rendererHasSVGShadow(child));
}
-void SVGRenderSupport::styleChanged(RenderElement& renderer, const RenderStyle* oldStyle)
+void SVGRenderSupport::styleChanged(RenderElement& renderer)
{
auto parent = renderer.parent();
SVGRenderSupport::setRendererHasSVGShadow(renderer, (parent && SVGRenderSupport::rendererHasSVGShadow(*parent)) || renderer.style().svgStyle().shadow());
-
-#if ENABLE(CSS_COMPOSITING)
- if (renderer.element() && renderer.element()->isSVGElement() && (!oldStyle || renderer.style().hasBlendMode() != oldStyle->hasBlendMode()))
- SVGRenderSupport::updateMaskedAncestorShouldIsolateBlending(renderer);
-#else
- UNUSED_PARAM(oldStyle);
-#endif
}
-#if ENABLE(CSS_COMPOSITING)
-bool SVGRenderSupport::isolatesBlending(const RenderStyle& style)
-{
- return style.svgStyle().isolatesBlending() || style.hasBlendMode() || style.opacity() < 1.0f;
}
-void SVGRenderSupport::updateMaskedAncestorShouldIsolateBlending(const RenderElement& renderer)
-{
- ASSERT(renderer.element());
- ASSERT(renderer.element()->isSVGElement());
-
- bool maskedAncestorShouldIsolateBlending = renderer.style().hasBlendMode();
- for (auto* ancestor = renderer.element()->parentElement(); ancestor && ancestor->isSVGElement(); ancestor = ancestor->parentElement()) {
- if (!downcast<SVGElement>(*ancestor).isSVGGraphicsElement() || !isolatesBlending(*ancestor->computedStyle()))
- continue;
-
- if (ancestor->computedStyle()->svgStyle().hasMasker())
- downcast<SVGGraphicsElement>(*ancestor).setShouldIsolateBlending(maskedAncestorShouldIsolateBlending);
-
- return;
- }
-}
#endif
-}
diff --git a/Source/WebCore/rendering/svg/SVGRenderSupport.h b/Source/WebCore/rendering/svg/SVGRenderSupport.h
index 8d7bdb3ce..026c14e7a 100644
--- a/Source/WebCore/rendering/svg/SVGRenderSupport.h
+++ b/Source/WebCore/rendering/svg/SVGRenderSupport.h
@@ -24,6 +24,7 @@
#ifndef SVGRenderSupport_h
#define SVGRenderSupport_h
+#if ENABLE(SVG)
#include "PaintInfo.h"
namespace WebCore {
@@ -68,8 +69,7 @@ public:
static FloatRect repaintRectForRendererInLocalCoordinatesExcludingSVGShadow(const RenderElement&);
static LayoutRect clippedOverflowRectForRepaint(const RenderElement&, const RenderLayerModelObject* repaintContainer);
static void computeFloatRectForRepaint(const RenderElement&, const RenderLayerModelObject* repaintContainer, FloatRect&, bool fixed);
- static const RenderElement& localToParentTransform(const RenderElement&, AffineTransform &);
- static void mapLocalToContainer(const RenderElement&, const RenderLayerModelObject* repaintContainer, TransformState&, bool* wasFixed);
+ static void mapLocalToContainer(const RenderElement&, const RenderLayerModelObject* repaintContainer, TransformState&, bool* wasFixed = 0);
static const RenderElement* pushMappingToContainer(const RenderElement&, const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap&);
static bool checkForSVGRepaintDuringLayout(const RenderElement&);
@@ -84,12 +84,7 @@ public:
static void setRendererHasSVGShadow(RenderObject&, bool hasShadow);
static void childAdded(RenderElement& parent, RenderObject& child);
- static void styleChanged(RenderElement&, const RenderStyle*);
-
-#if ENABLE(CSS_COMPOSITING)
- static bool isolatesBlending(const RenderStyle&);
- static void updateMaskedAncestorShouldIsolateBlending(const RenderElement&);
-#endif
+ static void styleChanged(RenderElement&);
// FIXME: These methods do not belong here.
static const RenderSVGRoot& findTreeRootObject(const RenderElement&);
@@ -102,4 +97,5 @@ private:
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif // SVGRenderSupport_h
diff --git a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
index fc85f23fc..aa6040968 100644
--- a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.cpp
@@ -13,10 +13,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -27,13 +27,14 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGRenderTreeAsText.h"
#include "GraphicsTypes.h"
#include "HTMLNames.h"
#include "NodeRenderStyle.h"
#include "RenderImage.h"
-#include "RenderIterator.h"
#include "RenderSVGGradientStop.h"
#include "RenderSVGImage.h"
#include "RenderSVGPath.h"
@@ -249,17 +250,17 @@ static void writeSVGPaintingResource(TextStream& ts, RenderSVGResource* resource
ts << " [id=\"" << element.getIdAttribute() << "\"]";
}
-static void writeStyle(TextStream& ts, const RenderElement& renderer)
+static void writeStyle(TextStream& ts, const RenderObject& object)
{
- const RenderStyle& style = renderer.style();
+ const RenderStyle& style = object.style();
const SVGRenderStyle& svgStyle = style.svgStyle();
- if (!renderer.localTransform().isIdentity())
- writeNameValuePair(ts, "transform", renderer.localTransform());
+ if (!object.localTransform().isIdentity())
+ writeNameValuePair(ts, "transform", object.localTransform());
writeIfNotDefault(ts, "image rendering", style.imageRendering(), RenderStyle::initialImageRendering());
writeIfNotDefault(ts, "opacity", style.opacity(), RenderStyle::initialOpacity());
- if (is<RenderSVGShape>(renderer)) {
- const auto& shape = downcast<RenderSVGShape>(renderer);
+ if (object.isSVGShape()) {
+ const RenderSVGShape& shape = static_cast<const RenderSVGShape&>(object);
Color fallbackColor;
if (RenderSVGResource* strokePaintingResource = RenderSVGResource::strokePaintingResource(const_cast<RenderSVGShape&>(shape), shape.style(), fallbackColor)) {
@@ -268,8 +269,8 @@ static void writeStyle(TextStream& ts, const RenderElement& renderer)
writeSVGPaintingResource(ts, strokePaintingResource);
SVGLengthContext lengthContext(&shape.graphicsElement());
- double dashOffset = lengthContext.valueForLength(svgStyle.strokeDashOffset());
- double strokeWidth = lengthContext.valueForLength(svgStyle.strokeWidth());
+ double dashOffset = svgStyle.strokeDashOffset().value(lengthContext);
+ double strokeWidth = svgStyle.strokeWidth().value(lengthContext);
const Vector<SVGLength>& dashes = svgStyle.strokeDashArray();
DashArray dashArray;
@@ -306,10 +307,10 @@ static void writeStyle(TextStream& ts, const RenderElement& renderer)
writeIfNotEmpty(ts, "end marker", svgStyle.markerEndResource());
}
-static TextStream& writePositionAndStyle(TextStream& ts, const RenderElement& renderer)
+static TextStream& writePositionAndStyle(TextStream& ts, const RenderObject& object)
{
- ts << " " << enclosingIntRect(renderer.absoluteClippedOverflowRect());
- writeStyle(ts, renderer);
+ ts << " " << enclosingIntRect(const_cast<RenderObject&>(object).absoluteClippedOverflowRect());
+ writeStyle(ts, object);
return ts;
}
@@ -320,34 +321,34 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGShape& shape)
SVGGraphicsElement& svgElement = shape.graphicsElement();
SVGLengthContext lengthContext(&svgElement);
- if (is<SVGRectElement>(svgElement)) {
- const SVGRectElement& element = downcast<SVGRectElement>(svgElement);
+ if (isSVGRectElement(svgElement)) {
+ const SVGRectElement& element = toSVGRectElement(svgElement);
writeNameValuePair(ts, "x", element.x().value(lengthContext));
writeNameValuePair(ts, "y", element.y().value(lengthContext));
writeNameValuePair(ts, "width", element.width().value(lengthContext));
writeNameValuePair(ts, "height", element.height().value(lengthContext));
- } else if (is<SVGLineElement>(svgElement)) {
- const SVGLineElement& element = downcast<SVGLineElement>(svgElement);
+ } else if (isSVGLineElement(svgElement)) {
+ const SVGLineElement& element = toSVGLineElement(svgElement);
writeNameValuePair(ts, "x1", element.x1().value(lengthContext));
writeNameValuePair(ts, "y1", element.y1().value(lengthContext));
writeNameValuePair(ts, "x2", element.x2().value(lengthContext));
writeNameValuePair(ts, "y2", element.y2().value(lengthContext));
- } else if (is<SVGEllipseElement>(svgElement)) {
- const SVGEllipseElement& element = downcast<SVGEllipseElement>(svgElement);
+ } else if (isSVGEllipseElement(svgElement)) {
+ const SVGEllipseElement& element = toSVGEllipseElement(svgElement);
writeNameValuePair(ts, "cx", element.cx().value(lengthContext));
writeNameValuePair(ts, "cy", element.cy().value(lengthContext));
writeNameValuePair(ts, "rx", element.rx().value(lengthContext));
writeNameValuePair(ts, "ry", element.ry().value(lengthContext));
- } else if (is<SVGCircleElement>(svgElement)) {
- const SVGCircleElement& element = downcast<SVGCircleElement>(svgElement);
+ } else if (isSVGCircleElement(svgElement)) {
+ const SVGCircleElement& element = toSVGCircleElement(svgElement);
writeNameValuePair(ts, "cx", element.cx().value(lengthContext));
writeNameValuePair(ts, "cy", element.cy().value(lengthContext));
writeNameValuePair(ts, "r", element.r().value(lengthContext));
- } else if (is<SVGPolyElement>(svgElement)) {
- const SVGPolyElement& element = downcast<SVGPolyElement>(svgElement);
+ } else if (svgElement.hasTagName(SVGNames::polygonTag) || svgElement.hasTagName(SVGNames::polylineTag)) {
+ const SVGPolyElement& element = toSVGPolyElement(svgElement);
writeNameAndQuotedValue(ts, "points", element.pointList().valueAsString());
- } else if (is<SVGPathElement>(svgElement)) {
- const SVGPathElement& element = downcast<SVGPathElement>(svgElement);
+ } else if (isSVGPathElement(svgElement)) {
+ const SVGPathElement& element = toSVGPathElement(svgElement);
String pathString;
// FIXME: We should switch to UnalteredParsing here - this will affect the path dumping output of dozens of tests.
buildStringFromByteStream(element.pathByteStream(), pathString, NormalizedParsing);
@@ -364,7 +365,7 @@ static TextStream& operator<<(TextStream& ts, const RenderSVGRoot& root)
static void writeRenderSVGTextBox(TextStream& ts, const RenderSVGText& text)
{
- auto* box = downcast<SVGRootInlineBox>(text.firstRootBox());
+ SVGRootInlineBox* box = toSVGRootInlineBox(text.firstRootBox());
if (!box)
return;
@@ -434,10 +435,10 @@ static inline void writeSVGInlineTextBox(TextStream& ts, SVGInlineTextBox* textB
static inline void writeSVGInlineTextBoxes(TextStream& ts, const RenderText& text, int indent)
{
for (InlineTextBox* box = text.firstTextBox(); box; box = box->nextTextBox()) {
- if (!is<SVGInlineTextBox>(*box))
+ if (!box->isSVGInlineTextBox())
continue;
- writeSVGInlineTextBox(ts, downcast<SVGInlineTextBox>(box), indent);
+ writeSVGInlineTextBox(ts, toSVGInlineTextBox(box), indent);
}
}
@@ -450,10 +451,10 @@ static void writeStandardPrefix(TextStream& ts, const RenderObject& object, int
ts << " {" << object.node()->nodeName() << "}";
}
-static void writeChildren(TextStream& ts, const RenderElement& parent, int indent)
+static void writeChildren(TextStream& ts, const RenderObject& object, int indent)
{
- for (const auto& child : childrenOfType<RenderObject>(parent))
- write(ts, child, indent + 1);
+ for (RenderObject* child = object.firstChildSlow(); child; child = child->nextSibling())
+ write(ts, *child, indent + 1);
}
static inline void writeCommonGradientProperties(TextStream& ts, SVGSpreadMethodType spreadMethod, const AffineTransform& gradientTransform, SVGUnitTypes::SVGUnitType gradientUnits)
@@ -467,50 +468,56 @@ static inline void writeCommonGradientProperties(TextStream& ts, SVGSpreadMethod
ts << " [gradientTransform=" << gradientTransform << "]";
}
-void writeSVGResourceContainer(TextStream& ts, const RenderSVGResourceContainer& resource, int indent)
+void writeSVGResourceContainer(TextStream& ts, const RenderObject& object, int indent)
{
- writeStandardPrefix(ts, resource, indent);
+ writeStandardPrefix(ts, object, indent);
- const AtomicString& id = resource.element().getIdAttribute();
+ Element* element = toElement(object.node());
+ const AtomicString& id = element->getIdAttribute();
writeNameAndQuotedValue(ts, "id", id);
- if (resource.resourceType() == MaskerResourceType) {
- const auto& masker = static_cast<const RenderSVGResourceMasker&>(resource);
- writeNameValuePair(ts, "maskUnits", masker.maskUnits());
- writeNameValuePair(ts, "maskContentUnits", masker.maskContentUnits());
+ RenderSVGResourceContainer* resource = const_cast<RenderObject&>(object).toRenderSVGResourceContainer();
+ ASSERT(resource);
+
+ if (resource->resourceType() == MaskerResourceType) {
+ RenderSVGResourceMasker* masker = static_cast<RenderSVGResourceMasker*>(resource);
+ writeNameValuePair(ts, "maskUnits", masker->maskUnits());
+ writeNameValuePair(ts, "maskContentUnits", masker->maskContentUnits());
ts << "\n";
- } else if (resource.resourceType() == FilterResourceType) {
- const auto& filter = static_cast<const RenderSVGResourceFilter&>(resource);
- writeNameValuePair(ts, "filterUnits", filter.filterUnits());
- writeNameValuePair(ts, "primitiveUnits", filter.primitiveUnits());
+#if ENABLE(FILTERS)
+ } else if (resource->resourceType() == FilterResourceType) {
+ RenderSVGResourceFilter* filter = static_cast<RenderSVGResourceFilter*>(resource);
+ writeNameValuePair(ts, "filterUnits", filter->filterUnits());
+ writeNameValuePair(ts, "primitiveUnits", filter->primitiveUnits());
ts << "\n";
// Creating a placeholder filter which is passed to the builder.
FloatRect dummyRect;
RefPtr<SVGFilter> dummyFilter = SVGFilter::create(AffineTransform(), dummyRect, dummyRect, dummyRect, true);
- if (auto builder = filter.buildPrimitives(*dummyFilter)) {
+ if (auto builder = filter->buildPrimitives(dummyFilter.get())) {
if (FilterEffect* lastEffect = builder->lastEffect())
lastEffect->externalRepresentation(ts, indent + 1);
}
- } else if (resource.resourceType() == ClipperResourceType) {
- const auto& clipper = static_cast<const RenderSVGResourceClipper&>(resource);
- writeNameValuePair(ts, "clipPathUnits", clipper.clipPathUnits());
+#endif
+ } else if (resource->resourceType() == ClipperResourceType) {
+ RenderSVGResourceClipper* clipper = static_cast<RenderSVGResourceClipper*>(resource);
+ writeNameValuePair(ts, "clipPathUnits", clipper->clipPathUnits());
ts << "\n";
- } else if (resource.resourceType() == MarkerResourceType) {
- const auto& marker = static_cast<const RenderSVGResourceMarker&>(resource);
- writeNameValuePair(ts, "markerUnits", marker.markerUnits());
- ts << " [ref at " << marker.referencePoint() << "]";
+ } else if (resource->resourceType() == MarkerResourceType) {
+ RenderSVGResourceMarker* marker = static_cast<RenderSVGResourceMarker*>(resource);
+ writeNameValuePair(ts, "markerUnits", marker->markerUnits());
+ ts << " [ref at " << marker->referencePoint() << "]";
ts << " [angle=";
- if (marker.angle() == -1)
+ if (marker->angle() == -1)
ts << "auto" << "]\n";
else
- ts << marker.angle() << "]\n";
- } else if (resource.resourceType() == PatternResourceType) {
- const auto& pattern = static_cast<const RenderSVGResourcePattern&>(resource);
+ ts << marker->angle() << "]\n";
+ } else if (resource->resourceType() == PatternResourceType) {
+ RenderSVGResourcePattern* pattern = static_cast<RenderSVGResourcePattern*>(resource);
// Dump final results that are used for rendering. No use in asking SVGPatternElement for its patternUnits(), as it may
// link to other patterns using xlink:href, we need to build the full inheritance chain, aka. collectPatternProperties()
PatternAttributes attributes;
- pattern.patternElement().collectPatternAttributes(attributes);
+ pattern->patternElement().collectPatternAttributes(attributes);
writeNameValuePair(ts, "patternUnits", attributes.patternUnits());
writeNameValuePair(ts, "patternContentUnits", attributes.patternContentUnits());
@@ -519,37 +526,37 @@ void writeSVGResourceContainer(TextStream& ts, const RenderSVGResourceContainer&
if (!transform.isIdentity())
ts << " [patternTransform=" << transform << "]";
ts << "\n";
- } else if (resource.resourceType() == LinearGradientResourceType) {
- const auto& gradient = static_cast<const RenderSVGResourceLinearGradient&>(resource);
+ } else if (resource->resourceType() == LinearGradientResourceType) {
+ RenderSVGResourceLinearGradient* gradient = static_cast<RenderSVGResourceLinearGradient*>(resource);
// Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may
// link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties()
LinearGradientAttributes attributes;
- gradient.linearGradientElement().collectGradientAttributes(attributes);
+ gradient->linearGradientElement().collectGradientAttributes(attributes);
writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.gradientUnits());
- ts << " [start=" << gradient.startPoint(attributes) << "] [end=" << gradient.endPoint(attributes) << "]\n";
- } else if (resource.resourceType() == RadialGradientResourceType) {
- const auto& gradient = static_cast<const RenderSVGResourceRadialGradient&>(resource);
+ ts << " [start=" << gradient->startPoint(attributes) << "] [end=" << gradient->endPoint(attributes) << "]\n";
+ } else if (resource->resourceType() == RadialGradientResourceType) {
+ RenderSVGResourceRadialGradient* gradient = static_cast<RenderSVGResourceRadialGradient*>(resource);
// Dump final results that are used for rendering. No use in asking SVGGradientElement for its gradientUnits(), as it may
// link to other gradients using xlink:href, we need to build the full inheritance chain, aka. collectGradientProperties()
RadialGradientAttributes attributes;
- gradient.radialGradientElement().collectGradientAttributes(attributes);
+ gradient->radialGradientElement().collectGradientAttributes(attributes);
writeCommonGradientProperties(ts, attributes.spreadMethod(), attributes.gradientTransform(), attributes.gradientUnits());
- FloatPoint focalPoint = gradient.focalPoint(attributes);
- FloatPoint centerPoint = gradient.centerPoint(attributes);
- float radius = gradient.radius(attributes);
- float focalRadius = gradient.focalRadius(attributes);
+ FloatPoint focalPoint = gradient->focalPoint(attributes);
+ FloatPoint centerPoint = gradient->centerPoint(attributes);
+ float radius = gradient->radius(attributes);
+ float focalRadius = gradient->focalRadius(attributes);
ts << " [center=" << centerPoint << "] [focal=" << focalPoint << "] [radius=" << radius << "] [focalRadius=" << focalRadius << "]\n";
} else
ts << "\n";
- writeChildren(ts, resource, indent);
+ writeChildren(ts, object, indent);
}
-void writeSVGContainer(TextStream& ts, const RenderSVGContainer& container, int indent)
+void writeSVGContainer(TextStream& ts, const RenderObject& container, int indent)
{
// Currently RenderSVGResourceFilterPrimitive has no meaningful output.
if (container.isSVGResourceFilterPrimitive())
@@ -580,7 +587,7 @@ void writeSVGText(TextStream& ts, const RenderSVGText& text, int indent)
void writeSVGInlineText(TextStream& ts, const RenderSVGInlineText& text, int indent)
{
writeStandardPrefix(ts, text, indent);
- ts << " " << enclosingIntRect(FloatRect(text.firstRunLocation(), text.floatLinesBoundingBox().size())) << "\n";
+ ts << " " << enclosingIntRect(FloatRect(text.firstRunOrigin(), text.floatLinesBoundingBox().size())) << "\n";
writeResources(ts, text, indent);
writeSVGInlineTextBoxes(ts, text, indent);
}
@@ -604,18 +611,22 @@ void writeSVGGradientStop(TextStream& ts, const RenderSVGGradientStop& stop, int
{
writeStandardPrefix(ts, stop, indent);
- ts << " [offset=" << stop.element().offset() << "] [color=" << stop.element().stopColorIncludingOpacity() << "]\n";
+ SVGStopElement* stopElement = toSVGStopElement(toSVGElement(stop.element()));
+ ASSERT(stopElement);
+
+ ts << " [offset=" << stopElement->offset() << "] [color=" << stopElement->stopColorIncludingOpacity() << "]\n";
}
-void writeResources(TextStream& ts, const RenderObject& renderer, int indent)
+void writeResources(TextStream& ts, const RenderObject& object, int indent)
{
- const RenderStyle& style = renderer.style();
+ const RenderStyle& style = object.style();
const SVGRenderStyle& svgStyle = style.svgStyle();
// FIXME: We want to use SVGResourcesCache to determine which resources are present, instead of quering the resource <-> id cache.
// For now leave the DRT output as is, but later on we should change this so cycles are properly ignored in the DRT output.
+ RenderObject& renderer = const_cast<RenderObject&>(object);
if (!svgStyle.maskerResource().isEmpty()) {
- if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(renderer.document(), svgStyle.maskerResource())) {
+ if (RenderSVGResourceMasker* masker = getRenderSVGResourceById<RenderSVGResourceMasker>(object.document(), svgStyle.maskerResource())) {
writeIndent(ts, indent);
ts << " ";
writeNameAndQuotedValue(ts, "masker", svgStyle.maskerResource());
@@ -625,7 +636,7 @@ void writeResources(TextStream& ts, const RenderObject& renderer, int indent)
}
}
if (!svgStyle.clipperResource().isEmpty()) {
- if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(renderer.document(), svgStyle.clipperResource())) {
+ if (RenderSVGResourceClipper* clipper = getRenderSVGResourceById<RenderSVGResourceClipper>(object.document(), svgStyle.clipperResource())) {
writeIndent(ts, indent);
ts << " ";
writeNameAndQuotedValue(ts, "clipPath", svgStyle.clipperResource());
@@ -634,8 +645,9 @@ void writeResources(TextStream& ts, const RenderObject& renderer, int indent)
ts << " " << clipper->resourceBoundingBox(renderer) << "\n";
}
}
+#if ENABLE(FILTERS)
if (!svgStyle.filterResource().isEmpty()) {
- if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(renderer.document(), svgStyle.filterResource())) {
+ if (RenderSVGResourceFilter* filter = getRenderSVGResourceById<RenderSVGResourceFilter>(object.document(), svgStyle.filterResource())) {
writeIndent(ts, indent);
ts << " ";
writeNameAndQuotedValue(ts, "filter", svgStyle.filterResource());
@@ -644,6 +656,9 @@ void writeResources(TextStream& ts, const RenderObject& renderer, int indent)
ts << " " << filter->resourceBoundingBox(renderer) << "\n";
}
}
+#endif
}
} // namespace WebCore
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.h b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.h
index ebc3932f4..5458c0dd2 100644
--- a/Source/WebCore/rendering/svg/SVGRenderTreeAsText.h
+++ b/Source/WebCore/rendering/svg/SVGRenderTreeAsText.h
@@ -10,10 +10,10 @@
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
+ * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
@@ -26,6 +26,8 @@
#ifndef SVGRenderTreeAsText_h
#define SVGRenderTreeAsText_h
+#if ENABLE(SVG)
+
#include "TextStream.h"
namespace WebCore {
@@ -36,11 +38,9 @@ class FloatSize;
class Node;
class RenderImage;
class RenderObject;
-class RenderSVGContainer;
class RenderSVGGradientStop;
class RenderSVGImage;
class RenderSVGInlineText;
-class RenderSVGResourceContainer;
class RenderSVGShape;
class RenderSVGRoot;
class RenderSVGText;
@@ -51,8 +51,8 @@ class SVGUnitTypes;
void write(TextStream&, const RenderSVGShape&, int indent);
void write(TextStream&, const RenderSVGRoot&, int indent);
void writeSVGGradientStop(TextStream&, const RenderSVGGradientStop&, int indent);
-void writeSVGResourceContainer(TextStream&, const RenderSVGResourceContainer&, int indent);
-void writeSVGContainer(TextStream&, const RenderSVGContainer&, int indent);
+void writeSVGResourceContainer(TextStream&, const RenderObject&, int indent);
+void writeSVGContainer(TextStream&, const RenderObject&, int indent);
void writeSVGImage(TextStream&, const RenderSVGImage&, int indent);
void writeSVGInlineText(TextStream&, const RenderSVGInlineText&, int indent);
void writeSVGText(TextStream&, const RenderSVGText&, int indent);
@@ -90,4 +90,6 @@ TextStream& operator<<(TextStream& ts, Pointer* t)
} // namespace WebCore
+#endif // ENABLE(SVG)
+
#endif // SVGRenderTreeAsText_h
diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
index 927a7c1fc..a0ad33016 100644
--- a/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
+++ b/Source/WebCore/rendering/svg/SVGRenderingContext.cpp
@@ -23,6 +23,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGRenderingContext.h"
#include "BasicShapes.h"
@@ -35,10 +37,11 @@
#include "RenderSVGResourceFilter.h"
#include "RenderSVGResourceMasker.h"
#include "RenderView.h"
-#include "SVGLengthContext.h"
#include "SVGResources.h"
#include "SVGResourcesCache.h"
+static int kMaxImageBufferSize = 4096;
+
namespace WebCore {
static inline bool isRenderingMaskImage(const RenderObject& object)
@@ -54,12 +57,14 @@ SVGRenderingContext::~SVGRenderingContext()
ASSERT(m_renderer && m_paintInfo);
+#if ENABLE(FILTERS)
if (m_renderingFlags & EndFilterLayer) {
ASSERT(m_filter);
m_filter->postApplyResource(*m_renderer, m_paintInfo->context, ApplyToDefaultMode, 0, 0);
m_paintInfo->context = m_savedContext;
m_paintInfo->rect = m_savedPaintRect;
}
+#endif
if (m_renderingFlags & EndOpacityLayer)
m_paintInfo->context->endTransparencyLayer();
@@ -81,7 +86,9 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderElement& renderer, Pai
m_renderer = &renderer;
m_paintInfo = &paintInfo;
+#if ENABLE(FILTERS)
m_filter = 0;
+#endif
// We need to save / restore the context even if the initialization failed.
if (needsGraphicsContextSave == SaveGraphicsContext) {
@@ -95,38 +102,19 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderElement& renderer, Pai
// Setup transparency layers before setting up SVG resources!
bool isRenderingMask = isRenderingMaskImage(*m_renderer);
- // RenderLayer takes care of root opacity.
- float opacity = (renderer.isSVGRoot() || isRenderingMask) ? 1 : style.opacity();
+ float opacity = isRenderingMask ? 1 : style.opacity();
const ShadowData* shadow = svgStyle.shadow();
- bool hasBlendMode = style.hasBlendMode();
- bool hasIsolation = style.hasIsolation();
- bool isolateMaskForBlending = false;
-
-#if ENABLE(CSS_COMPOSITING)
- if (svgStyle.hasMasker() && is<SVGGraphicsElement>(downcast<SVGElement>(*renderer.element()))) {
- SVGGraphicsElement& graphicsElement = downcast<SVGGraphicsElement>(*renderer.element());
- isolateMaskForBlending = graphicsElement.shouldIsolateBlending();
- }
-#endif
-
- if (opacity < 1 || shadow || hasBlendMode || isolateMaskForBlending || hasIsolation) {
+ if (opacity < 1 || shadow) {
FloatRect repaintRect = m_renderer->repaintRectInLocalCoordinates();
- m_paintInfo->context->clip(repaintRect);
-
- if (opacity < 1 || hasBlendMode || isolateMaskForBlending || hasIsolation) {
-
- if (hasBlendMode)
- m_paintInfo->context->setCompositeOperation(m_paintInfo->context->compositeOperation(), style.blendMode());
+ if (opacity < 1) {
+ m_paintInfo->context->clip(repaintRect);
m_paintInfo->context->beginTransparencyLayer(opacity);
-
- if (hasBlendMode)
- m_paintInfo->context->setCompositeOperation(m_paintInfo->context->compositeOperation(), BlendModeNormal);
-
m_renderingFlags |= EndOpacityLayer;
}
if (shadow) {
+ m_paintInfo->context->clip(repaintRect);
m_paintInfo->context->setShadow(IntSize(roundToInt(shadow->x()), roundToInt(shadow->y())), shadow->radius(), shadow->color(), style.colorSpace());
m_paintInfo->context->beginTransparencyLayer(1);
m_renderingFlags |= EndShadowLayer;
@@ -134,27 +122,17 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderElement& renderer, Pai
}
ClipPathOperation* clipPathOperation = style.clipPath();
- if (is<ShapeClipPathOperation>(clipPathOperation)) {
- auto& clipPath = downcast<ShapeClipPathOperation>(*clipPathOperation);
- FloatRect referenceBox;
- if (clipPath.referenceBox() == Stroke)
- // FIXME: strokeBoundingBox() takes dasharray into account but shouldn't.
- referenceBox = renderer.strokeBoundingBox();
- else if (clipPath.referenceBox() == ViewBox && renderer.element()) {
- FloatSize viewportSize;
- SVGLengthContext(downcast<SVGElement>(renderer.element())).determineViewport(viewportSize);
- referenceBox.setWidth(viewportSize.width());
- referenceBox.setHeight(viewportSize.height());
- } else
- referenceBox = renderer.objectBoundingBox();
- m_paintInfo->context->clipPath(clipPath.pathForReferenceRect(referenceBox), clipPath.windRule());
+ if (clipPathOperation && clipPathOperation->type() == ClipPathOperation::Shape) {
+ ShapeClipPathOperation* clipPath = static_cast<ShapeClipPathOperation*>(clipPathOperation);
+ m_paintInfo->context->clipPath(clipPath->pathForReferenceRect(renderer.objectBoundingBox()), clipPath->windRule());
}
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(*m_renderer);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(*m_renderer);
if (!resources) {
+#if ENABLE(FILTERS)
if (svgStyle.hasFilter())
return;
-
+#endif
m_renderingFlags |= RenderingPrepared;
return;
}
@@ -172,6 +150,7 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderElement& renderer, Pai
return;
}
+#if ENABLE(FILTERS)
if (!isRenderingMask) {
m_filter = resources->filter();
if (m_filter) {
@@ -190,38 +169,45 @@ void SVGRenderingContext::prepareToRenderSVGContent(RenderElement& renderer, Pai
m_paintInfo->rect = IntRect(m_filter->drawingRegion(m_renderer));
}
}
+#endif
m_renderingFlags |= RenderingPrepared;
}
static AffineTransform& currentContentTransformation()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(AffineTransform, s_currentContentTransformation, ());
+ DEFINE_STATIC_LOCAL(AffineTransform, s_currentContentTransformation, ());
return s_currentContentTransformation;
}
-float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObject& renderer)
+float SVGRenderingContext::calculateScreenFontSizeScalingFactor(const RenderObject* renderer)
{
- AffineTransform ctm = calculateTransformationToOutermostCoordinateSystem(renderer);
+ ASSERT(renderer);
+
+ AffineTransform ctm;
+ calculateTransformationToOutermostCoordinateSystem(renderer, ctm);
return narrowPrecisionToFloat(sqrt((pow(ctm.xScale(), 2) + pow(ctm.yScale(), 2)) / 2));
}
-AffineTransform SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(const RenderObject& renderer)
+void SVGRenderingContext::calculateTransformationToOutermostCoordinateSystem(const RenderObject* renderer, AffineTransform& absoluteTransform)
{
- AffineTransform absoluteTransform = currentContentTransformation();
+ ASSERT(renderer);
+ absoluteTransform = currentContentTransformation();
+
+ float deviceScaleFactor = 1;
+ if (Page* page = renderer->document().page())
+ deviceScaleFactor = page->deviceScaleFactor();
- float deviceScaleFactor = renderer.document().deviceScaleFactor();
// Walk up the render tree, accumulating SVG transforms.
- const RenderObject* ancestor = &renderer;
- while (ancestor) {
- absoluteTransform = ancestor->localToParentTransform() * absoluteTransform;
- if (ancestor->isSVGRoot())
+ while (renderer) {
+ absoluteTransform = renderer->localToParentTransform() * absoluteTransform;
+ if (renderer->isSVGRoot())
break;
- ancestor = ancestor->parent();
+ renderer = renderer->parent();
}
// Continue walking up the layer tree, accumulating CSS transforms.
- RenderLayer* layer = ancestor ? ancestor->enclosingLayer() : nullptr;
+ RenderLayer* layer = renderer ? renderer->enclosingLayer() : 0;
while (layer) {
if (TransformationMatrix* layerTransform = layer->transform())
absoluteTransform = layerTransform->toAffineTransform() * absoluteTransform;
@@ -234,53 +220,53 @@ AffineTransform SVGRenderingContext::calculateTransformationToOutermostCoordinat
}
absoluteTransform.scale(deviceScaleFactor);
- return absoluteTransform;
}
-std::unique_ptr<ImageBuffer> SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, ColorSpace colorSpace, RenderingMode renderingMode)
+bool SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, std::unique_ptr<ImageBuffer>& imageBuffer, ColorSpace colorSpace, RenderingMode renderingMode)
{
IntRect paintRect = calculateImageBufferRect(targetRect, absoluteTransform);
// Don't create empty ImageBuffers.
if (paintRect.isEmpty())
- return nullptr;
-
- FloatSize scale;
- FloatSize clampedSize = ImageBuffer::clampedSize(paintRect.size(), scale);
-
- auto imageBuffer = ImageBuffer::create(clampedSize, renderingMode, 1, colorSpace);
- if (!imageBuffer)
- return nullptr;
+ return false;
- AffineTransform transform;
- transform.scale(scale).translate(-paintRect.location()).multiply(absoluteTransform);
+ IntSize clampedSize = clampedAbsoluteSize(paintRect.size());
+ std::unique_ptr<ImageBuffer> image = ImageBuffer::create(clampedSize, 1, colorSpace, renderingMode);
+ if (!image)
+ return false;
- GraphicsContext* imageContext = imageBuffer->context();
+ GraphicsContext* imageContext = image->context();
ASSERT(imageContext);
- imageContext->concatCTM(transform);
- return imageBuffer;
+ imageContext->scale(FloatSize(static_cast<float>(clampedSize.width()) / paintRect.width(),
+ static_cast<float>(clampedSize.height()) / paintRect.height()));
+ imageContext->translate(-paintRect.x(), -paintRect.y());
+ imageContext->concatCTM(absoluteTransform);
+
+ imageBuffer = std::move(image);
+ return true;
}
-std::unique_ptr<ImageBuffer> SVGRenderingContext::createImageBuffer(const FloatRect& targetRect, const FloatRect& clampedRect, ColorSpace colorSpace, RenderingMode renderingMode)
+bool SVGRenderingContext::createImageBufferForPattern(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, std::unique_ptr<ImageBuffer>& imageBuffer, ColorSpace colorSpace, RenderingMode renderingMode)
{
- IntSize clampedSize = roundedIntSize(clampedRect.size());
- IntSize unclampedSize = roundedIntSize(targetRect.size());
+ IntSize imageSize(roundedIntSize(clampedAbsoluteTargetRect.size()));
+ IntSize unclampedImageSize(roundedIntSize(absoluteTargetRect.size()));
// Don't create empty ImageBuffers.
- if (clampedSize.isEmpty())
- return nullptr;
+ if (imageSize.isEmpty())
+ return false;
- auto imageBuffer = ImageBuffer::create(clampedSize, renderingMode, 1, colorSpace);
- if (!imageBuffer)
- return nullptr;
+ std::unique_ptr<ImageBuffer> image = ImageBuffer::create(imageSize, 1, colorSpace, renderingMode);
+ if (!image)
+ return false;
- GraphicsContext* imageContext = imageBuffer->context();
+ GraphicsContext* imageContext = image->context();
ASSERT(imageContext);
// Compensate rounding effects, as the absolute target rect is using floating-point numbers and the image buffer size is integer.
- imageContext->scale(FloatSize(unclampedSize.width() / targetRect.width(), unclampedSize.height() / targetRect.height()));
+ imageContext->scale(FloatSize(unclampedImageSize.width() / absoluteTargetRect.width(), unclampedImageSize.height() / absoluteTargetRect.height()));
- return imageBuffer;
+ imageBuffer = std::move(image);
+ return true;
}
void SVGRenderingContext::renderSubtreeToImageBuffer(ImageBuffer* image, RenderElement& item, const AffineTransform& subtreeContentTransformation)
@@ -288,7 +274,7 @@ void SVGRenderingContext::renderSubtreeToImageBuffer(ImageBuffer* image, RenderE
ASSERT(image);
ASSERT(image->context());
- PaintInfo info(image->context(), LayoutRect::infiniteRect(), PaintPhaseForeground, PaintBehaviorNormal);
+ PaintInfo info(image->context(), IntRect::infiniteRect(), PaintPhaseForeground, PaintBehaviorNormal);
AffineTransform& contentTransformation = currentContentTransformation();
AffineTransform savedContentTransformation = contentTransformation;
@@ -319,6 +305,18 @@ void SVGRenderingContext::clipToImageBuffer(GraphicsContext* context, const Affi
imageBuffer.reset();
}
+FloatRect SVGRenderingContext::clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect)
+{
+ const FloatSize maxImageBufferSize(kMaxImageBufferSize, kMaxImageBufferSize);
+ return FloatRect(absoluteTargetRect.location(), absoluteTargetRect.size().shrunkTo(maxImageBufferSize));
+}
+
+IntSize SVGRenderingContext::clampedAbsoluteSize(const IntSize& absoluteSize)
+{
+ const IntSize maxImageBufferSize(kMaxImageBufferSize, kMaxImageBufferSize);
+ return absoluteSize.shrunkTo(maxImageBufferSize);
+}
+
void SVGRenderingContext::clear2DRotation(AffineTransform& transform)
{
AffineTransform::DecomposedType decomposition;
@@ -330,7 +328,7 @@ void SVGRenderingContext::clear2DRotation(AffineTransform& transform)
bool SVGRenderingContext::bufferForeground(std::unique_ptr<ImageBuffer>& imageBuffer)
{
ASSERT(m_paintInfo);
- ASSERT(is<RenderSVGImage>(*m_renderer));
+ ASSERT(m_renderer->isSVGImage());
FloatRect boundingBox = m_renderer->objectBoundingBox();
// Invalidate an existing buffer if the scale is not correct.
@@ -349,7 +347,7 @@ bool SVGRenderingContext::bufferForeground(std::unique_ptr<ImageBuffer>& imageBu
bufferedRenderingContext->translate(-boundingBox.x(), -boundingBox.y());
PaintInfo bufferedInfo(*m_paintInfo);
bufferedInfo.context = bufferedRenderingContext;
- downcast<RenderSVGImage>(*m_renderer).paintForeground(bufferedInfo);
+ toRenderSVGImage(m_renderer)->paintForeground(bufferedInfo);
} else
return false;
}
@@ -359,3 +357,5 @@ bool SVGRenderingContext::bufferForeground(std::unique_ptr<ImageBuffer>& imageBu
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGRenderingContext.h b/Source/WebCore/rendering/svg/SVGRenderingContext.h
index 9a23c2512..3bf604cc2 100644
--- a/Source/WebCore/rendering/svg/SVGRenderingContext.h
+++ b/Source/WebCore/rendering/svg/SVGRenderingContext.h
@@ -25,6 +25,7 @@
#ifndef SVGRenderingContext_h
#define SVGRenderingContext_h
+#if ENABLE(SVG)
#include "ImageBuffer.h"
#include "PaintInfo.h"
@@ -50,7 +51,9 @@ public:
, m_renderer(nullptr)
, m_paintInfo(nullptr)
, m_savedContext(nullptr)
+#if ENABLE(FILTERS)
, m_filter(nullptr)
+#endif
{
}
@@ -59,7 +62,9 @@ public:
, m_renderer(nullptr)
, m_paintInfo(nullptr)
, m_savedContext(nullptr)
+#if ENABLE(FILTERS)
, m_filter(nullptr)
+#endif
{
prepareToRenderSVGContent(object, paintinfo, needsGraphicsContextSave);
}
@@ -71,14 +76,17 @@ public:
void prepareToRenderSVGContent(RenderElement&, PaintInfo&, NeedsGraphicsContextSave = DontSaveGraphicsContext);
bool isRenderingPrepared() const { return m_renderingFlags & RenderingPrepared; }
- static std::unique_ptr<ImageBuffer> createImageBuffer(const FloatRect& targetRect, const AffineTransform& absoluteTransform, ColorSpace, RenderingMode);
- static std::unique_ptr<ImageBuffer> createImageBuffer(const FloatRect& targetRect, const FloatRect& clampedRect, ColorSpace, RenderingMode);
+ static bool createImageBuffer(const FloatRect& paintRect, const AffineTransform& absoluteTransform, std::unique_ptr<ImageBuffer>&, ColorSpace, RenderingMode);
+ // Patterns need a different float-to-integer coordinate mapping.
+ static bool createImageBufferForPattern(const FloatRect& absoluteTargetRect, const FloatRect& clampedAbsoluteTargetRect, std::unique_ptr<ImageBuffer>&, ColorSpace, RenderingMode);
static void renderSubtreeToImageBuffer(ImageBuffer*, RenderElement&, const AffineTransform&);
static void clipToImageBuffer(GraphicsContext*, const AffineTransform& absoluteTransform, const FloatRect& targetRect, std::unique_ptr<ImageBuffer>&, bool safeToClear);
- static float calculateScreenFontSizeScalingFactor(const RenderObject&);
- static AffineTransform calculateTransformationToOutermostCoordinateSystem(const RenderObject&);
+ static float calculateScreenFontSizeScalingFactor(const RenderObject*);
+ static void calculateTransformationToOutermostCoordinateSystem(const RenderObject*, AffineTransform& absoluteTransform);
+ static IntSize clampedAbsoluteSize(const IntSize&);
+ static FloatRect clampedAbsoluteTargetRect(const FloatRect& absoluteTargetRect);
static void clear2DRotation(AffineTransform&);
static IntRect calculateImageBufferRect(const FloatRect& targetRect, const AffineTransform& absoluteTransform)
@@ -108,9 +116,12 @@ private:
PaintInfo* m_paintInfo;
GraphicsContext* m_savedContext;
LayoutRect m_savedPaintRect;
+#if ENABLE(FILTERS)
RenderSVGResourceFilter* m_filter;
+#endif
};
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif // SVGRenderingContext_h
diff --git a/Source/WebCore/rendering/svg/SVGResources.cpp b/Source/WebCore/rendering/svg/SVGResources.cpp
index ab61dd3a2..bdb586b89 100644
--- a/Source/WebCore/rendering/svg/SVGResources.cpp
+++ b/Source/WebCore/rendering/svg/SVGResources.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "SVGResources.h"
+#if ENABLE(SVG)
#include "RenderSVGResourceClipper.h"
#include "RenderSVGResourceFilter.h"
#include "RenderSVGResourceMarker.h"
@@ -31,7 +32,7 @@
#include "SVGRenderStyle.h"
#include "SVGURIReference.h"
-#if ENABLE(TREE_DEBUGGING)
+#ifndef NDEBUG
#include <stdio.h>
#endif
@@ -44,7 +45,7 @@ SVGResources::SVGResources()
static HashSet<AtomicString>& clipperFilterMaskerTags()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
+ DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
if (s_tagList.isEmpty()) {
// "container elements": http://www.w3.org/TR/SVG11/intro.html#TermContainerElement
// "graphics elements" : http://www.w3.org/TR/SVG11/intro.html#TermGraphicsElement
@@ -93,7 +94,7 @@ static HashSet<AtomicString>& clipperFilterMaskerTags()
static HashSet<AtomicString>& markerTags()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
+ DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
if (s_tagList.isEmpty()) {
s_tagList.add(SVGNames::lineTag.localName());
s_tagList.add(SVGNames::pathTag.localName());
@@ -106,7 +107,7 @@ static HashSet<AtomicString>& markerTags()
static HashSet<AtomicString>& fillAndStrokeTags()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
+ DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
if (s_tagList.isEmpty()) {
s_tagList.add(SVGNames::altGlyphTag.localName());
s_tagList.add(SVGNames::circleTag.localName());
@@ -127,7 +128,7 @@ static HashSet<AtomicString>& fillAndStrokeTags()
static HashSet<AtomicString>& chainableResourceTags()
{
- DEPRECATED_DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
+ DEFINE_STATIC_LOCAL(HashSet<AtomicString>, s_tagList, ());
if (s_tagList.isEmpty()) {
s_tagList.add(SVGNames::linearGradientTag.localName());
s_tagList.add(SVGNames::filterTag.localName());
@@ -141,12 +142,14 @@ static HashSet<AtomicString>& chainableResourceTags()
static inline String targetReferenceFromResource(SVGElement& element)
{
String target;
- if (is<SVGPatternElement>(element))
- target = downcast<SVGPatternElement>(element).href();
- else if (is<SVGGradientElement>(element))
- target = downcast<SVGGradientElement>(element).href();
- else if (is<SVGFilterElement>(element))
- target = downcast<SVGFilterElement>(element).href();
+ if (isSVGPatternElement(element))
+ target = toSVGPatternElement(element).href();
+ else if (isSVGGradientElement(element))
+ target = toSVGGradientElement(element).href();
+#if ENABLE(FILTERS)
+ else if (isSVGFilterElement(element))
+ target = toSVGFilterElement(element).href();
+#endif
else
ASSERT_NOT_REACHED();
@@ -172,9 +175,9 @@ static inline RenderSVGResourceContainer* paintingResourceFromSVGPaint(Document&
return container;
}
-static inline void registerPendingResource(SVGDocumentExtensions& extensions, const AtomicString& id, SVGElement& element)
+static inline void registerPendingResource(SVGDocumentExtensions* extensions, const AtomicString& id, SVGElement& element)
{
- extensions.addPendingResource(id, &element);
+ extensions->addPendingResource(id, &element);
}
bool SVGResources::buildCachedResources(const RenderElement& renderer, const SVGRenderStyle& svgStyle)
@@ -185,11 +188,12 @@ bool SVGResources::buildCachedResources(const RenderElement& renderer, const SVG
if (!renderer.element())
return false;
- auto& element = downcast<SVGElement>(*renderer.element());
+ auto& element = toSVGElement(*renderer.element());
Document& document = element.document();
- SVGDocumentExtensions& extensions = document.accessSVGExtensions();
+ SVGDocumentExtensions* extensions = document.accessSVGExtensions();
+ ASSERT(extensions);
const AtomicString& tagName = element.localName();
if (tagName.isNull())
@@ -205,6 +209,7 @@ bool SVGResources::buildCachedResources(const RenderElement& renderer, const SVG
registerPendingResource(extensions, id, element);
}
+#if ENABLE(FILTERS)
if (svgStyle.hasFilter()) {
AtomicString id(svgStyle.filterResource());
if (setFilter(getRenderSVGResourceById<RenderSVGResourceFilter>(document, id)))
@@ -212,6 +217,7 @@ bool SVGResources::buildCachedResources(const RenderElement& renderer, const SVG
else
registerPendingResource(extensions, id, element);
}
+#endif
if (svgStyle.hasMasker()) {
AtomicString id(svgStyle.maskerResource());
@@ -273,7 +279,7 @@ bool SVGResources::buildCachedResources(const RenderElement& renderer, const SVG
return foundResources;
}
-void SVGResources::removeClientFromCache(RenderElement& renderer, bool markForInvalidation) const
+void SVGResources::removeClientFromCache(RenderObject& object, bool markForInvalidation) const
{
if (!m_clipperFilterMaskerData && !m_markerData && !m_fillStrokeData && !m_linkedResource)
return;
@@ -282,33 +288,35 @@ void SVGResources::removeClientFromCache(RenderElement& renderer, bool markForIn
ASSERT(!m_clipperFilterMaskerData);
ASSERT(!m_markerData);
ASSERT(!m_fillStrokeData);
- m_linkedResource->removeClientFromCache(renderer, markForInvalidation);
+ m_linkedResource->removeClientFromCache(object, markForInvalidation);
return;
}
if (m_clipperFilterMaskerData) {
if (m_clipperFilterMaskerData->clipper)
- m_clipperFilterMaskerData->clipper->removeClientFromCache(renderer, markForInvalidation);
+ m_clipperFilterMaskerData->clipper->removeClientFromCache(object, markForInvalidation);
+#if ENABLE(FILTERS)
if (m_clipperFilterMaskerData->filter)
- m_clipperFilterMaskerData->filter->removeClientFromCache(renderer, markForInvalidation);
+ m_clipperFilterMaskerData->filter->removeClientFromCache(object, markForInvalidation);
+#endif
if (m_clipperFilterMaskerData->masker)
- m_clipperFilterMaskerData->masker->removeClientFromCache(renderer, markForInvalidation);
+ m_clipperFilterMaskerData->masker->removeClientFromCache(object, markForInvalidation);
}
if (m_markerData) {
if (m_markerData->markerStart)
- m_markerData->markerStart->removeClientFromCache(renderer, markForInvalidation);
+ m_markerData->markerStart->removeClientFromCache(object, markForInvalidation);
if (m_markerData->markerMid)
- m_markerData->markerMid->removeClientFromCache(renderer, markForInvalidation);
+ m_markerData->markerMid->removeClientFromCache(object, markForInvalidation);
if (m_markerData->markerEnd)
- m_markerData->markerEnd->removeClientFromCache(renderer, markForInvalidation);
+ m_markerData->markerEnd->removeClientFromCache(object, markForInvalidation);
}
if (m_fillStrokeData) {
if (m_fillStrokeData->fill)
- m_fillStrokeData->fill->removeClientFromCache(renderer, markForInvalidation);
+ m_fillStrokeData->fill->removeClientFromCache(object, markForInvalidation);
if (m_fillStrokeData->stroke)
- m_fillStrokeData->stroke->removeClientFromCache(renderer, markForInvalidation);
+ m_fillStrokeData->stroke->removeClientFromCache(object, markForInvalidation);
}
}
@@ -366,12 +374,16 @@ void SVGResources::resourceDestroyed(RenderSVGResourceContainer& resource)
}
break;
case FilterResourceType:
+#if ENABLE(FILTERS)
if (!m_clipperFilterMaskerData)
break;
if (m_clipperFilterMaskerData->filter == &resource) {
m_clipperFilterMaskerData->filter->removeAllClientsFromCache();
m_clipperFilterMaskerData->filter = 0;
}
+#else
+ ASSERT_NOT_REACHED();
+#endif
break;
case ClipperResourceType:
if (!m_clipperFilterMaskerData)
@@ -402,8 +414,10 @@ void SVGResources::buildSetOfResources(HashSet<RenderSVGResourceContainer*>& set
if (m_clipperFilterMaskerData) {
if (m_clipperFilterMaskerData->clipper)
set.add(m_clipperFilterMaskerData->clipper);
+#if ENABLE(FILTERS)
if (m_clipperFilterMaskerData->filter)
set.add(m_clipperFilterMaskerData->filter);
+#endif
if (m_clipperFilterMaskerData->masker)
set.add(m_clipperFilterMaskerData->masker);
}
@@ -433,7 +447,7 @@ bool SVGResources::setClipper(RenderSVGResourceClipper* clipper)
ASSERT(clipper->resourceType() == ClipperResourceType);
if (!m_clipperFilterMaskerData)
- m_clipperFilterMaskerData = std::make_unique<ClipperFilterMaskerData>();
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
m_clipperFilterMaskerData->clipper = clipper;
return true;
@@ -446,6 +460,7 @@ void SVGResources::resetClipper()
m_clipperFilterMaskerData->clipper = 0;
}
+#if ENABLE(FILTERS)
bool SVGResources::setFilter(RenderSVGResourceFilter* filter)
{
if (!filter)
@@ -454,7 +469,7 @@ bool SVGResources::setFilter(RenderSVGResourceFilter* filter)
ASSERT(filter->resourceType() == FilterResourceType);
if (!m_clipperFilterMaskerData)
- m_clipperFilterMaskerData = std::make_unique<ClipperFilterMaskerData>();
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
m_clipperFilterMaskerData->filter = filter;
return true;
@@ -466,6 +481,7 @@ void SVGResources::resetFilter()
ASSERT(m_clipperFilterMaskerData->filter);
m_clipperFilterMaskerData->filter = 0;
}
+#endif
bool SVGResources::setMarkerStart(RenderSVGResourceMarker* markerStart)
{
@@ -475,7 +491,7 @@ bool SVGResources::setMarkerStart(RenderSVGResourceMarker* markerStart)
ASSERT(markerStart->resourceType() == MarkerResourceType);
if (!m_markerData)
- m_markerData = std::make_unique<MarkerData>();
+ m_markerData = MarkerData::create();
m_markerData->markerStart = markerStart;
return true;
@@ -496,7 +512,7 @@ bool SVGResources::setMarkerMid(RenderSVGResourceMarker* markerMid)
ASSERT(markerMid->resourceType() == MarkerResourceType);
if (!m_markerData)
- m_markerData = std::make_unique<MarkerData>();
+ m_markerData = MarkerData::create();
m_markerData->markerMid = markerMid;
return true;
@@ -517,7 +533,7 @@ bool SVGResources::setMarkerEnd(RenderSVGResourceMarker* markerEnd)
ASSERT(markerEnd->resourceType() == MarkerResourceType);
if (!m_markerData)
- m_markerData = std::make_unique<MarkerData>();
+ m_markerData = MarkerData::create();
m_markerData->markerEnd = markerEnd;
return true;
@@ -538,7 +554,7 @@ bool SVGResources::setMasker(RenderSVGResourceMasker* masker)
ASSERT(masker->resourceType() == MaskerResourceType);
if (!m_clipperFilterMaskerData)
- m_clipperFilterMaskerData = std::make_unique<ClipperFilterMaskerData>();
+ m_clipperFilterMaskerData = ClipperFilterMaskerData::create();
m_clipperFilterMaskerData->masker = masker;
return true;
@@ -561,7 +577,7 @@ bool SVGResources::setFill(RenderSVGResourceContainer* fill)
|| fill->resourceType() == RadialGradientResourceType);
if (!m_fillStrokeData)
- m_fillStrokeData = std::make_unique<FillStrokeData>();
+ m_fillStrokeData = FillStrokeData::create();
m_fillStrokeData->fill = fill;
return true;
@@ -584,7 +600,7 @@ bool SVGResources::setStroke(RenderSVGResourceContainer* stroke)
|| stroke->resourceType() == RadialGradientResourceType);
if (!m_fillStrokeData)
- m_fillStrokeData = std::make_unique<FillStrokeData>();
+ m_fillStrokeData = FillStrokeData::create();
m_fillStrokeData->stroke = stroke;
return true;
@@ -612,7 +628,7 @@ void SVGResources::resetLinkedResource()
m_linkedResource = 0;
}
-#if ENABLE(TREE_DEBUGGING)
+#ifndef NDEBUG
void SVGResources::dump(const RenderObject* object)
{
ASSERT(object);
@@ -626,8 +642,10 @@ void SVGResources::dump(const RenderObject* object)
if (m_clipperFilterMaskerData) {
if (RenderSVGResourceClipper* clipper = m_clipperFilterMaskerData->clipper)
fprintf(stderr, " |-> Clipper : %p (node=%p)\n", clipper, &clipper->clipPathElement());
+#if ENABLE(FILTERS)
if (RenderSVGResourceFilter* filter = m_clipperFilterMaskerData->filter)
fprintf(stderr, " |-> Filter : %p (node=%p)\n", filter, &filter->filterElement());
+#endif
if (RenderSVGResourceMasker* masker = m_clipperFilterMaskerData->masker)
fprintf(stderr, " |-> Masker : %p (node=%p)\n", masker, &masker->maskElement());
}
@@ -654,3 +672,5 @@ void SVGResources::dump(const RenderObject* object)
#endif
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGResources.h b/Source/WebCore/rendering/svg/SVGResources.h
index 8db1d4e33..240276a1d 100644
--- a/Source/WebCore/rendering/svg/SVGResources.h
+++ b/Source/WebCore/rendering/svg/SVGResources.h
@@ -20,9 +20,11 @@
#ifndef SVGResources_h
#define SVGResources_h
-#include <memory>
+#if ENABLE(SVG)
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
+#include <wtf/PassOwnPtr.h>
namespace WebCore {
@@ -53,8 +55,10 @@ public:
RenderSVGResourceFilter* filter() const
{
+#if ENABLE(FILTERS)
if (m_clipperFilterMaskerData)
return m_clipperFilterMaskerData->filter;
+#endif
return 0;
}
@@ -68,10 +72,10 @@ public:
void buildSetOfResources(HashSet<RenderSVGResourceContainer*>&);
// Methods operating on all cached resources
- void removeClientFromCache(RenderElement&, bool markForInvalidation = true) const;
+ void removeClientFromCache(RenderObject&, bool markForInvalidation = true) const;
void resourceDestroyed(RenderSVGResourceContainer&);
-#if ENABLE(TREE_DEBUGGING)
+#ifndef NDEBUG
void dump(const RenderObject*);
#endif
@@ -80,7 +84,9 @@ private:
// Only used by SVGResourcesCache cycle detection logic
void resetClipper();
+#if ENABLE(FILTERS)
void resetFilter();
+#endif
void resetMarkerStart();
void resetMarkerMid();
void resetMarkerEnd();
@@ -91,7 +97,9 @@ private:
private:
bool setClipper(RenderSVGResourceClipper*);
+#if ENABLE(FILTERS)
bool setFilter(RenderSVGResourceFilter*);
+#endif
bool setMarkerStart(RenderSVGResourceMarker*);
bool setMarkerMid(RenderSVGResourceMarker*);
bool setMarkerEnd(RenderSVGResourceMarker*);
@@ -110,13 +118,22 @@ private:
public:
ClipperFilterMaskerData()
: clipper(0)
+#if ENABLE(FILTERS)
, filter(0)
+#endif
, masker(0)
{
}
+ static PassOwnPtr<ClipperFilterMaskerData> create()
+ {
+ return adoptPtr(new ClipperFilterMaskerData);
+ }
+
RenderSVGResourceClipper* clipper;
+#if ENABLE(FILTERS)
RenderSVGResourceFilter* filter;
+#endif
RenderSVGResourceMasker* masker;
};
@@ -132,6 +149,11 @@ private:
{
}
+ static PassOwnPtr<MarkerData> create()
+ {
+ return adoptPtr(new MarkerData);
+ }
+
RenderSVGResourceMarker* markerStart;
RenderSVGResourceMarker* markerMid;
RenderSVGResourceMarker* markerEnd;
@@ -150,16 +172,22 @@ private:
{
}
+ static PassOwnPtr<FillStrokeData> create()
+ {
+ return adoptPtr(new FillStrokeData);
+ }
+
RenderSVGResourceContainer* fill;
RenderSVGResourceContainer* stroke;
};
- std::unique_ptr<ClipperFilterMaskerData> m_clipperFilterMaskerData;
- std::unique_ptr<MarkerData> m_markerData;
- std::unique_ptr<FillStrokeData> m_fillStrokeData;
+ OwnPtr<ClipperFilterMaskerData> m_clipperFilterMaskerData;
+ OwnPtr<MarkerData> m_markerData;
+ OwnPtr<FillStrokeData> m_fillStrokeData;
RenderSVGResourceContainer* m_linkedResource;
};
}
#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGResourcesCache.cpp b/Source/WebCore/rendering/svg/SVGResourcesCache.cpp
index 8556ecde2..fad518a32 100644
--- a/Source/WebCore/rendering/svg/SVGResourcesCache.cpp
+++ b/Source/WebCore/rendering/svg/SVGResourcesCache.cpp
@@ -20,6 +20,7 @@
#include "config.h"
#include "SVGResourcesCache.h"
+#if ENABLE(SVG)
#include "HTMLNames.h"
#include "RenderSVGResourceContainer.h"
#include "SVGResources.h"
@@ -42,12 +43,12 @@ void SVGResourcesCache::addResourcesFromRenderer(RenderElement& renderer, const
const SVGRenderStyle& svgStyle = style.svgStyle();
// Build a list of all resources associated with the passed RenderObject
- auto newResources = std::make_unique<SVGResources>();
+ OwnPtr<SVGResources> newResources = adoptPtr(new SVGResources);
if (!newResources->buildCachedResources(renderer, svgStyle))
return;
// Put object in cache.
- SVGResources& resources = *m_cache.add(&renderer, WTF::move(newResources)).iterator->value;
+ SVGResources& resources = *m_cache.add(&renderer, newResources.release()).iterator->value;
// Run cycle-detection _afterwards_, so self-references can be caught as well.
SVGResourcesCycleSolver solver(renderer, resources);
@@ -57,13 +58,13 @@ void SVGResourcesCache::addResourcesFromRenderer(RenderElement& renderer, const
HashSet<RenderSVGResourceContainer*> resourceSet;
resources.buildSetOfResources(resourceSet);
- for (auto* resourceContainer : resourceSet)
- resourceContainer->addClient(renderer);
+ for (auto it = resourceSet.begin(), end = resourceSet.end(); it != end; ++it)
+ (*it)->addClient(&renderer);
}
void SVGResourcesCache::removeResourcesFromRenderer(RenderElement& renderer)
{
- std::unique_ptr<SVGResources> resources = m_cache.take(&renderer);
+ OwnPtr<SVGResources> resources = m_cache.take(&renderer);
if (!resources)
return;
@@ -71,23 +72,29 @@ void SVGResourcesCache::removeResourcesFromRenderer(RenderElement& renderer)
HashSet<RenderSVGResourceContainer*> resourceSet;
resources->buildSetOfResources(resourceSet);
- for (auto* resourceContainer : resourceSet)
- resourceContainer->removeClient(renderer);
+ for (auto it = resourceSet.begin(), end = resourceSet.end(); it != end; ++it)
+ (*it)->removeClient(&renderer);
}
-static inline SVGResourcesCache& resourcesCacheFromRenderer(const RenderElement& renderer)
+static inline SVGResourcesCache* resourcesCacheFromRenderObject(const RenderObject& renderer)
{
- return renderer.document().accessSVGExtensions().resourcesCache();
+ SVGDocumentExtensions* extensions = renderer.document().accessSVGExtensions();
+ ASSERT(extensions);
+
+ SVGResourcesCache* cache = extensions->resourcesCache();
+ ASSERT(cache);
+
+ return cache;
}
-SVGResources* SVGResourcesCache::cachedResourcesForRenderer(const RenderElement& renderer)
+SVGResources* SVGResourcesCache::cachedResourcesForRenderObject(const RenderObject& renderer)
{
- return resourcesCacheFromRenderer(renderer).m_cache.get(&renderer);
+ return resourcesCacheFromRenderObject(renderer)->m_cache.get(&renderer);
}
void SVGResourcesCache::clientLayoutChanged(RenderElement& renderer)
{
- auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer);
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
if (!resources)
return;
@@ -115,9 +122,9 @@ void SVGResourcesCache::clientStyleChanged(RenderElement& renderer, StyleDiffere
// FIXME: Avoid passing in a useless StyleDifference, but instead compare oldStyle/newStyle to see which resources changed
// to be able to selectively rebuild individual resources, instead of all of them.
if (rendererCanHaveResources(renderer)) {
- auto& cache = resourcesCacheFromRenderer(renderer);
- cache.removeResourcesFromRenderer(renderer);
- cache.addResourcesFromRenderer(renderer, newStyle);
+ SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
+ cache->removeResourcesFromRenderer(renderer);
+ cache->addResourcesFromRenderer(renderer, newStyle);
}
RenderSVGResource::markForLayoutAndParentResourceInvalidation(renderer, false);
@@ -135,8 +142,9 @@ void SVGResourcesCache::clientWasAddedToTree(RenderObject& renderer)
if (!rendererCanHaveResources(renderer))
return;
- RenderElement& elementRenderer = downcast<RenderElement>(renderer);
- resourcesCacheFromRenderer(elementRenderer).addResourcesFromRenderer(elementRenderer, elementRenderer.style());
+ RenderElement& elementRenderer = toRenderElement(renderer);
+ SVGResourcesCache* cache = resourcesCacheFromRenderObject(elementRenderer);
+ cache->addResourcesFromRenderer(elementRenderer, elementRenderer.style());
}
void SVGResourcesCache::clientWillBeRemovedFromTree(RenderObject& renderer)
@@ -148,33 +156,40 @@ void SVGResourcesCache::clientWillBeRemovedFromTree(RenderObject& renderer)
if (!rendererCanHaveResources(renderer))
return;
- RenderElement& elementRenderer = downcast<RenderElement>(renderer);
- resourcesCacheFromRenderer(elementRenderer).removeResourcesFromRenderer(elementRenderer);
+ RenderElement& elementRenderer = toRenderElement(renderer);
+ SVGResourcesCache* cache = resourcesCacheFromRenderObject(elementRenderer);
+ cache->removeResourcesFromRenderer(elementRenderer);
}
void SVGResourcesCache::clientDestroyed(RenderElement& renderer)
{
- if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer))
+ SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer);
+ if (resources)
resources->removeClientFromCache(renderer);
- resourcesCacheFromRenderer(renderer).removeResourcesFromRenderer(renderer);
+ SVGResourcesCache* cache = resourcesCacheFromRenderObject(renderer);
+ cache->removeResourcesFromRenderer(renderer);
}
void SVGResourcesCache::resourceDestroyed(RenderSVGResourceContainer& resource)
{
- auto& cache = resourcesCacheFromRenderer(resource);
+ SVGResourcesCache* cache = resourcesCacheFromRenderObject(resource);
// The resource itself may have clients, that need to be notified.
- cache.removeResourcesFromRenderer(resource);
+ cache->removeResourcesFromRenderer(resource);
- for (auto& it : cache.m_cache) {
- it.value->resourceDestroyed(resource);
+ for (auto it = cache->m_cache.begin(), end = cache->m_cache.end(); it != end; ++it) {
+ it->value->resourceDestroyed(resource);
// Mark users of destroyed resources as pending resolution based on the id of the old resource.
Element& resourceElement = resource.element();
- Element* clientElement = it.key->element();
- clientElement->document().accessSVGExtensions().addPendingResource(resourceElement.getIdAttribute(), clientElement);
+ Element* clientElement = toElement(it->key->node());
+ SVGDocumentExtensions* extensions = clientElement->document().accessSVGExtensions();
+
+ extensions->addPendingResource(resourceElement.getIdAttribute(), clientElement);
}
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGResourcesCache.h b/Source/WebCore/rendering/svg/SVGResourcesCache.h
index b6d297e56..fe6d5e6ed 100644
--- a/Source/WebCore/rendering/svg/SVGResourcesCache.h
+++ b/Source/WebCore/rendering/svg/SVGResourcesCache.h
@@ -20,10 +20,10 @@
#ifndef SVGResourcesCache_h
#define SVGResourcesCache_h
+#if ENABLE(SVG)
#include "RenderStyleConstants.h"
-#include <memory>
#include <wtf/HashMap.h>
-#include <wtf/Noncopyable.h>
+#include <wtf/OwnPtr.h>
namespace WebCore {
@@ -39,7 +39,7 @@ public:
SVGResourcesCache();
~SVGResourcesCache();
- static SVGResources* cachedResourcesForRenderer(const RenderElement&);
+ static SVGResources* cachedResourcesForRenderObject(const RenderObject&);
// Called from all SVG renderers addChild() methods.
static void clientWasAddedToTree(RenderObject&);
@@ -63,10 +63,11 @@ private:
void addResourcesFromRenderer(RenderElement&, const RenderStyle&);
void removeResourcesFromRenderer(RenderElement&);
- typedef HashMap<const RenderElement*, std::unique_ptr<SVGResources>> CacheMap;
+ typedef HashMap<const RenderObject*, OwnPtr<SVGResources>> CacheMap;
CacheMap m_cache;
};
}
#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGResourcesCycleSolver.cpp b/Source/WebCore/rendering/svg/SVGResourcesCycleSolver.cpp
index be76c1f9d..c6776f667 100644
--- a/Source/WebCore/rendering/svg/SVGResourcesCycleSolver.cpp
+++ b/Source/WebCore/rendering/svg/SVGResourcesCycleSolver.cpp
@@ -20,8 +20,12 @@
#include "config.h"
#include "SVGResourcesCycleSolver.h"
-#include "Logging.h"
-#include "RenderAncestorIterator.h"
+// Set to a value > 0, to debug the resource cache.
+#define DEBUG_CYCLE_DETECTION 0
+
+#if ENABLE(SVG)
+#include "RenderElement.h"
+#include "RenderIterator.h"
#include "RenderSVGResourceClipper.h"
#include "RenderSVGResourceFilter.h"
#include "RenderSVGResourceMarker.h"
@@ -31,15 +35,6 @@
#include "SVGResources.h"
#include "SVGResourcesCache.h"
-// Set to truthy value to debug the resource cache.
-#define DEBUG_CYCLE_DETECTION 0
-
-#if DEBUG_CYCLE_DETECTION
-#define LOG_DEBUG_CYCLE(...) LOG(SVG, __VA_ARGS__)
-#else
-#define LOG_DEBUG_CYCLE(...) ((void)0)
-#endif
-
namespace WebCore {
SVGResourcesCycleSolver::SVGResourcesCycleSolver(RenderElement& renderer, SVGResources& resources)
@@ -54,65 +49,43 @@ SVGResourcesCycleSolver::~SVGResourcesCycleSolver()
bool SVGResourcesCycleSolver::resourceContainsCycles(RenderElement& renderer) const
{
- LOG_DEBUG_CYCLE("\n(%p) Check for cycles\n", &renderer);
-
// First operate on the resources of the given renderer.
// <marker id="a"> <path marker-start="url(#b)"/> ...
// <marker id="b" marker-start="url(#a)"/>
- if (auto* resources = SVGResourcesCache::cachedResourcesForRenderer(renderer)) {
+ if (SVGResources* resources = SVGResourcesCache::cachedResourcesForRenderObject(renderer)) {
HashSet<RenderSVGResourceContainer*> resourceSet;
resources->buildSetOfResources(resourceSet);
- LOG_DEBUG_CYCLE("(%p) Examine our cached resources\n", &renderer);
-
- // Walk all resources and check whether they reference any resource contained in the resources set.
- for (auto* resource : resourceSet) {
- LOG_DEBUG_CYCLE("(%p) Check %p\n", &renderer, resource);
+ // Walk all resources and check wheter they reference any resource contained in the resources set.
+ for (auto resource : resourceSet) {
if (m_allResources.contains(resource))
return true;
-
- // Now check if the resources themselves contain cycles.
- if (resourceContainsCycles(*resource))
- return true;
}
}
- LOG_DEBUG_CYCLE("(%p) Now the children renderers\n", &renderer);
-
// Then operate on the child resources of the given renderer.
// <marker id="a"> <path marker-start="url(#b)"/> ...
// <marker id="b"> <path marker-start="url(#a)"/> ...
for (auto& child : childrenOfType<RenderElement>(renderer)) {
-
- LOG_DEBUG_CYCLE("(%p) Checking child %p\n", &renderer, &child);
-
- if (auto* childResources = SVGResourcesCache::cachedResourcesForRenderer(child)) {
-
- LOG_DEBUG_CYCLE("(%p) Child %p had cached resources. Check them.\n", &renderer, &child);
-
- // A child of the given 'resource' contains resources.
- HashSet<RenderSVGResourceContainer*> childResourceSet;
- childResources->buildSetOfResources(childResourceSet);
-
- // Walk all child resources and check whether they reference any resource contained in the resources set.
- for (auto* resource : childResourceSet) {
- LOG_DEBUG_CYCLE("(%p) Child %p had resource %p\n", &renderer, &child, resource);
- if (m_allResources.contains(resource))
- return true;
- }
+ SVGResources* childResources = SVGResourcesCache::cachedResourcesForRenderObject(child);
+ if (!childResources)
+ continue;
+
+ // A child of the given 'resource' contains resources.
+ HashSet<RenderSVGResourceContainer*> childResourceSet;
+ childResources->buildSetOfResources(childResourceSet);
+
+ // Walk all child resources and check wheter they reference any resource contained in the resources set.
+ for (auto& resource : childResourceSet) {
+ if (m_allResources.contains(resource))
+ return true;
}
- LOG_DEBUG_CYCLE("(%p) Recurse into child %p\n", &renderer, &child);
-
// Walk children recursively, stop immediately if we found a cycle
if (resourceContainsCycles(child))
return true;
-
- LOG_DEBUG_CYCLE("\n(%p) Child %p was ok\n", &renderer, &child);
}
- LOG_DEBUG_CYCLE("\n(%p) No cycles found\n", &renderer);
-
return false;
}
@@ -120,8 +93,8 @@ void SVGResourcesCycleSolver::resolveCycles()
{
ASSERT(m_allResources.isEmpty());
-#if DEBUG_CYCLE_DETECTION
- LOG_DEBUG_CYCLE("\nBefore cycle detection:\n");
+#if DEBUG_CYCLE_DETECTION > 0
+ fprintf(stderr, "\nBefore cycle detection:\n");
m_resources.dump(&m_renderer);
#endif
@@ -131,52 +104,49 @@ void SVGResourcesCycleSolver::resolveCycles()
ASSERT(!localResources.isEmpty());
// Add all parent resource containers to the HashSet.
- HashSet<RenderSVGResourceContainer*> ancestorResources;
- for (auto& resource : ancestorsOfType<RenderSVGResourceContainer>(m_renderer))
- ancestorResources.add(&resource);
+ HashSet<RenderSVGResourceContainer*> parentResources;
+ auto parent = m_renderer.parent();
+ while (parent) {
+ if (parent->isSVGResourceContainer())
+ parentResources.add(parent->toRenderSVGResourceContainer());
+ parent = parent->parent();
+ }
-#if DEBUG_CYCLE_DETECTION
- LOG_DEBUG_CYCLE("\nDetecting whether any resources references any of following objects:\n");
+#if DEBUG_CYCLE_DETECTION > 0
+ fprintf(stderr, "\nDetecting wheter any resources references any of following objects:\n");
{
- LOG_DEBUG_CYCLE("Local resources:\n");
- for (RenderObject* resource : localResources)
- LOG_DEBUG_CYCLE("|> %s : %p (node %p)\n", resource->renderName(), resource, resource->node());
+ fprintf(stderr, "Local resources:\n");
+ for (auto it = localResources.begin(), end = localResources.end(); it != end; ++it)
+ fprintf(stderr, "|> %s: object=%p (node=%p)\n", (*it)->renderName(), *it, (*it)->node());
fprintf(stderr, "Parent resources:\n");
- for (RenderObject* resource : ancestorResources)
- LOG_DEBUG_CYCLE("|> %s : %p (node %p)\n", resource->renderName(), resource, resource->node());
+ for (auto it = parentResources.begin(), end = parentResources.end(); it != end; ++it)
+ fprintf(stderr, "|> %s: object=%p (node=%p)\n", (*it)->renderName(), *it, (*it)->node());
}
#endif
// Build combined set of local and parent resources.
m_allResources = localResources;
- for (auto* resource : ancestorResources)
- m_allResources.add(resource);
+ for (auto it = parentResources.begin(), end = parentResources.end(); it != end; ++it)
+ m_allResources.add(*it);
// If we're a resource, add ourselves to the HashSet.
- if (is<RenderSVGResourceContainer>(m_renderer))
- m_allResources.add(&downcast<RenderSVGResourceContainer>(m_renderer));
+ if (m_renderer.isSVGResourceContainer())
+ m_allResources.add(m_renderer.toRenderSVGResourceContainer());
ASSERT(!m_allResources.isEmpty());
-#if DEBUG_CYCLE_DETECTION
- LOG_DEBUG_CYCLE("\nAll resources:\n");
- for (auto* resource : m_allResources)
- LOG_DEBUG_CYCLE("- %p\n", resource);
-#endif
-
// The job of this function is to determine wheter any of the 'resources' associated with the given 'renderer'
- // references us (or whether any of its kids references us) -> that's a cycle, we need to find and break it.
- for (auto* resource : localResources) {
- if (ancestorResources.contains(resource) || resourceContainsCycles(*resource)) {
- LOG_DEBUG_CYCLE("\n**** Detected a cycle (see the last test in the output above) ****\n");
- breakCycle(*resource);
- }
+ // references us (or wheter any of its kids references us) -> that's a cycle, we need to find and break it.
+ for (auto it = localResources.begin(), end = localResources.end(); it != end; ++it) {
+ RenderSVGResourceContainer& resource = **it;
+ if (parentResources.contains(&resource) || resourceContainsCycles(resource))
+ breakCycle(resource);
}
-#if DEBUG_CYCLE_DETECTION
- LOG_DEBUG_CYCLE("\nAfter cycle detection:\n");
- m_resources.dump(&m_renderer);
+#if DEBUG_CYCLE_DETECTION > 0
+ fprintf(stderr, "\nAfter cycle detection:\n");
+ m_resources.dump(m_renderer);
#endif
m_allResources.clear();
@@ -213,8 +183,10 @@ void SVGResourcesCycleSolver::breakCycle(RenderSVGResourceContainer& resourceLea
m_resources.resetStroke();
break;
case FilterResourceType:
+#if ENABLE(FILTERS)
ASSERT(&resourceLeadingToCycle == m_resources.filter());
m_resources.resetFilter();
+#endif
break;
case ClipperResourceType:
ASSERT(&resourceLeadingToCycle == m_resources.clipper());
@@ -227,3 +199,5 @@ void SVGResourcesCycleSolver::breakCycle(RenderSVGResourceContainer& resourceLea
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGResourcesCycleSolver.h b/Source/WebCore/rendering/svg/SVGResourcesCycleSolver.h
index 691b325cd..fd95a7428 100644
--- a/Source/WebCore/rendering/svg/SVGResourcesCycleSolver.h
+++ b/Source/WebCore/rendering/svg/SVGResourcesCycleSolver.h
@@ -20,6 +20,7 @@
#ifndef SVGResourcesCycleSolver_h
#define SVGResourcesCycleSolver_h
+#if ENABLE(SVG)
#include <wtf/HashSet.h>
#include <wtf/Noncopyable.h>
@@ -49,3 +50,4 @@ private:
}
#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp b/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp
index d1a78389a..ec628b168 100644
--- a/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp
+++ b/Source/WebCore/rendering/svg/SVGRootInlineBox.cpp
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer Inc.
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
* Copyright (C) 2011 Torch Mobile (Beijing) CO. Ltd. All rights reserved.
@@ -24,9 +24,9 @@
#include "config.h"
#include "SVGRootInlineBox.h"
+#if ENABLE(SVG)
#include "GraphicsContext.h"
#include "RenderSVGText.h"
-#include "RenderSVGTextPath.h"
#include "SVGInlineFlowBox.h"
#include "SVGInlineTextBox.h"
#include "SVGNames.h"
@@ -43,10 +43,10 @@ SVGRootInlineBox::SVGRootInlineBox(RenderSVGText& renderSVGText)
RenderSVGText& SVGRootInlineBox::renderSVGText()
{
- return downcast<RenderSVGText>(blockFlow());
+ return toRenderSVGText(blockFlow());
}
-void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffset, LayoutUnit, LayoutUnit)
+void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint&, LayoutUnit, LayoutUnit)
{
ASSERT(paintInfo.phase == PaintPhaseForeground || paintInfo.phase == PaintPhaseSelection);
ASSERT(!paintInfo.context->paintingDisabled());
@@ -57,33 +57,34 @@ void SVGRootInlineBox::paint(PaintInfo& paintInfo, const LayoutPoint& paintOffse
PaintInfo childPaintInfo(paintInfo);
if (hasSelection) {
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
- if (is<SVGInlineTextBox>(*child))
- downcast<SVGInlineTextBox>(*child).paintSelectionBackground(childPaintInfo);
- else if (is<SVGInlineFlowBox>(*child))
- downcast<SVGInlineFlowBox>(*child).paintSelectionBackground(childPaintInfo);
+ if (child->isSVGInlineTextBox())
+ toSVGInlineTextBox(child)->paintSelectionBackground(childPaintInfo);
+ else if (child->isSVGInlineFlowBox())
+ toSVGInlineFlowBox(child)->paintSelectionBackground(childPaintInfo);
}
}
SVGRenderingContext renderingContext(renderSVGText(), paintInfo, SVGRenderingContext::SaveGraphicsContext);
if (renderingContext.isRenderingPrepared()) {
for (InlineBox* child = firstChild(); child; child = child->nextOnLine()) {
- if (is<SVGInlineTextBox>(*child))
- SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(&downcast<SVGInlineTextBox>(*child).renderer());
+ if (child->isSVGInlineTextBox())
+ SVGInlineFlowBox::computeTextMatchMarkerRectForRenderer(&toSVGInlineTextBox(child)->renderer());
- child->paint(paintInfo, paintOffset, 0, 0);
+ child->paint(paintInfo, LayoutPoint(), 0, 0);
}
}
}
void SVGRootInlineBox::computePerCharacterLayoutInformation()
{
- auto& textRoot = downcast<RenderSVGText>(blockFlow());
+ RenderSVGText* textRoot = toRenderSVGText(&blockFlow());
+ ASSERT(textRoot);
- Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot.layoutAttributes();
+ Vector<SVGTextLayoutAttributes*>& layoutAttributes = textRoot->layoutAttributes();
if (layoutAttributes.isEmpty())
return;
- if (textRoot.needsReordering())
+ if (textRoot->needsReordering())
reorderValueLists(layoutAttributes);
// Perform SVG text layout phase two (see SVGTextLayoutEngine for details).
@@ -103,27 +104,31 @@ void SVGRootInlineBox::computePerCharacterLayoutInformation()
void SVGRootInlineBox::layoutCharactersInTextBoxes(InlineFlowBox* start, SVGTextLayoutEngine& characterLayout)
{
for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
- if (is<SVGInlineTextBox>(*child)) {
- ASSERT(is<RenderSVGInlineText>(child->renderer()));
- characterLayout.layoutInlineTextBox(downcast<SVGInlineTextBox>(*child));
+ if (child->isSVGInlineTextBox()) {
+ ASSERT(child->renderer().isSVGInlineText());
+
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
+ characterLayout.layoutInlineTextBox(textBox);
} else {
// Skip generated content.
Node* node = child->renderer().node();
if (!node)
continue;
- auto& flowBox = downcast<SVGInlineFlowBox>(*child);
+ ASSERT_WITH_SECURITY_IMPLICATION(child->isInlineFlowBox());
+
+ SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
bool isTextPath = node->hasTagName(SVGNames::textPathTag);
if (isTextPath) {
// Build text chunks for all <textPath> children, using the line layout algorithm.
// This is needeed as text-anchor is just an additional startOffset for text paths.
SVGTextLayoutEngine lineLayout(characterLayout.layoutAttributes());
- layoutCharactersInTextBoxes(&flowBox, lineLayout);
+ layoutCharactersInTextBoxes(flowBox, lineLayout);
- characterLayout.beginTextPathLayout(downcast<RenderSVGTextPath>(child->renderer()), lineLayout);
+ characterLayout.beginTextPathLayout(&child->renderer(), lineLayout);
}
- layoutCharactersInTextBoxes(&flowBox, characterLayout);
+ layoutCharactersInTextBoxes(flowBox, characterLayout);
if (isTextPath)
characterLayout.endTextPathLayout();
@@ -135,28 +140,30 @@ void SVGRootInlineBox::layoutChildBoxes(InlineFlowBox* start, FloatRect* childRe
{
for (InlineBox* child = start->firstChild(); child; child = child->nextOnLine()) {
FloatRect boxRect;
- if (is<SVGInlineTextBox>(*child)) {
- ASSERT(is<RenderSVGInlineText>(child->renderer()));
-
- auto& textBox = downcast<SVGInlineTextBox>(*child);
- boxRect = textBox.calculateBoundaries();
- textBox.setX(boxRect.x());
- textBox.setY(boxRect.y());
- textBox.setLogicalWidth(boxRect.width());
- textBox.setLogicalHeight(boxRect.height());
+ if (child->isSVGInlineTextBox()) {
+ ASSERT(child->renderer().isSVGInlineText());
+
+ SVGInlineTextBox* textBox = toSVGInlineTextBox(child);
+ boxRect = textBox->calculateBoundaries();
+ textBox->setX(boxRect.x());
+ textBox->setY(boxRect.y());
+ textBox->setLogicalWidth(boxRect.width());
+ textBox->setLogicalHeight(boxRect.height());
} else {
// Skip generated content.
if (!child->renderer().node())
continue;
- auto& flowBox = downcast<SVGInlineFlowBox>(*child);
- layoutChildBoxes(&flowBox);
+ ASSERT_WITH_SECURITY_IMPLICATION(child->isInlineFlowBox());
- boxRect = flowBox.calculateBoundaries();
- flowBox.setX(boxRect.x());
- flowBox.setY(boxRect.y());
- flowBox.setLogicalWidth(boxRect.width());
- flowBox.setLogicalHeight(boxRect.height());
+ SVGInlineFlowBox* flowBox = toSVGInlineFlowBox(child);
+ layoutChildBoxes(flowBox);
+
+ boxRect = flowBox->calculateBoundaries();
+ flowBox->setX(boxRect.x());
+ flowBox->setY(boxRect.y());
+ flowBox->setLogicalWidth(boxRect.width());
+ flowBox->setLogicalHeight(boxRect.height());
}
if (childRect)
childRect->unite(boxRect);
@@ -196,7 +203,7 @@ InlineBox* SVGRootInlineBox::closestLeafChildForPosition(const LayoutPoint& poin
return firstLeaf;
// FIXME: Check for vertical text!
- InlineBox* closestLeaf = nullptr;
+ InlineBox* closestLeaf = 0;
for (InlineBox* leaf = firstLeaf; leaf; leaf = leaf->nextLeafChild()) {
if (!leaf->isSVGInlineTextBox())
continue;
@@ -239,8 +246,8 @@ static inline void swapItemsInLayoutAttributes(SVGTextLayoutAttributes* firstAtt
static inline void findFirstAndLastAttributesInVector(Vector<SVGTextLayoutAttributes*>& attributes, RenderSVGInlineText* firstContext, RenderSVGInlineText* lastContext,
SVGTextLayoutAttributes*& first, SVGTextLayoutAttributes*& last)
{
- first = nullptr;
- last = nullptr;
+ first = 0;
+ last = 0;
unsigned attributesSize = attributes.size();
for (unsigned i = 0; i < attributesSize; ++i) {
@@ -267,7 +274,7 @@ static inline void reverseInlineBoxRangeAndValueListsIfNeeded(void* userData, Ve
if (first == last || first == --last)
return;
- if (!is<SVGInlineTextBox>(**last) || !is<SVGInlineTextBox>(**first)) {
+ if (!(*last)->isSVGInlineTextBox() || !(*first)->isSVGInlineTextBox()) {
InlineBox* temp = *first;
*first = *last;
*last = temp;
@@ -275,18 +282,18 @@ static inline void reverseInlineBoxRangeAndValueListsIfNeeded(void* userData, Ve
continue;
}
- auto& firstTextBox = downcast<SVGInlineTextBox>(**first);
- auto& lastTextBox = downcast<SVGInlineTextBox>(**last);
+ SVGInlineTextBox* firstTextBox = toSVGInlineTextBox(*first);
+ SVGInlineTextBox* lastTextBox = toSVGInlineTextBox(*last);
// Reordering is only necessary for BiDi text that is _absolutely_ positioned.
- if (firstTextBox.len() == 1 && firstTextBox.len() == lastTextBox.len()) {
- RenderSVGInlineText& firstContext = firstTextBox.renderer();
- RenderSVGInlineText& lastContext = lastTextBox.renderer();
+ if (firstTextBox->len() == 1 && firstTextBox->len() == lastTextBox->len()) {
+ RenderSVGInlineText& firstContext = firstTextBox->renderer();
+ RenderSVGInlineText& lastContext = lastTextBox->renderer();
- SVGTextLayoutAttributes* firstAttributes = nullptr;
- SVGTextLayoutAttributes* lastAttributes = nullptr;
+ SVGTextLayoutAttributes* firstAttributes = 0;
+ SVGTextLayoutAttributes* lastAttributes = 0;
findFirstAndLastAttributesInVector(attributes, &firstContext, &lastContext, firstAttributes, lastAttributes);
- swapItemsInLayoutAttributes(firstAttributes, lastAttributes, firstTextBox.start(), lastTextBox.start());
+ swapItemsInLayoutAttributes(firstAttributes, lastAttributes, firstTextBox->start(), lastTextBox->start());
}
InlineBox* temp = *first;
@@ -304,3 +311,5 @@ void SVGRootInlineBox::reorderValueLists(Vector<SVGTextLayoutAttributes*>& attri
}
} // namespace WebCore
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGRootInlineBox.h b/Source/WebCore/rendering/svg/SVGRootInlineBox.h
index bca9ffdf2..643af3108 100644
--- a/Source/WebCore/rendering/svg/SVGRootInlineBox.h
+++ b/Source/WebCore/rendering/svg/SVGRootInlineBox.h
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
- * Copyright (C) 2006 Apple Inc.
+ * Copyright (C) 2006 Apple Computer Inc.
* Copyright (C) 2007 Nikolas Zimmermann <zimmermann@kde.org>
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
*
@@ -23,6 +23,7 @@
#ifndef SVGRootInlineBox_h
#define SVGRootInlineBox_h
+#if ENABLE(SVG)
#include "RootInlineBox.h"
#include "SVGRenderSupport.h"
#include "SVGTextLayoutEngine.h"
@@ -38,27 +39,29 @@ public:
RenderSVGText& renderSVGText();
- virtual float virtualLogicalHeight() const override { return m_logicalHeight; }
+ virtual float virtualLogicalHeight() const override final { return m_logicalHeight; }
void setLogicalHeight(float height) { m_logicalHeight = height; }
- virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override;
+ virtual void paint(PaintInfo&, const LayoutPoint&, LayoutUnit lineTop, LayoutUnit lineBottom) override final;
void computePerCharacterLayoutInformation();
InlineBox* closestLeafChildForPosition(const LayoutPoint&);
private:
- virtual bool isSVGRootInlineBox() const override { return true; }
+ virtual bool isSVGRootInlineBox() const override final { return true; }
void reorderValueLists(Vector<SVGTextLayoutAttributes*>&);
void layoutCharactersInTextBoxes(InlineFlowBox*, SVGTextLayoutEngine&);
- void layoutChildBoxes(InlineFlowBox*, FloatRect* = nullptr);
+ void layoutChildBoxes(InlineFlowBox*, FloatRect* = 0);
void layoutRootBox(const FloatRect&);
float m_logicalHeight;
};
+INLINE_BOX_OBJECT_TYPE_CASTS(SVGRootInlineBox, isSVGRootInlineBox())
+
} // namespace WebCore
-SPECIALIZE_TYPE_TRAITS_INLINE_BOX(SVGRootInlineBox, isSVGRootInlineBox())
+#endif // ENABLE(SVG)
#endif // SVGRootInlineBox_h
diff --git a/Source/WebCore/rendering/svg/SVGSubpathData.h b/Source/WebCore/rendering/svg/SVGSubpathData.h
index 5ae2512cf..cf7901d8d 100644
--- a/Source/WebCore/rendering/svg/SVGSubpathData.h
+++ b/Source/WebCore/rendering/svg/SVGSubpathData.h
@@ -20,6 +20,7 @@
#ifndef SVGSubpathData_h
#define SVGSubpathData_h
+#if ENABLE(SVG)
#include "Path.h"
#include <wtf/Vector.h>
@@ -29,46 +30,51 @@ class SVGSubpathData {
public:
SVGSubpathData(Vector<FloatPoint>& zeroLengthSubpathLocations)
: m_zeroLengthSubpathLocations(zeroLengthSubpathLocations)
+ , m_haveSeenMoveOnly(true)
+ , m_pathIsZeroLength(true)
{
+ m_lastPoint.set(0, 0);
+ m_movePoint.set(0, 0);
}
- static void updateFromPathElement(SVGSubpathData& subpathFinder, const PathElement& element)
+ static void updateFromPathElement(void* info, const PathElement* element)
{
- switch (element.type) {
+ SVGSubpathData* subpathFinder = static_cast<SVGSubpathData*>(info);
+ switch (element->type) {
case PathElementMoveToPoint:
- if (subpathFinder.m_pathIsZeroLength && !subpathFinder.m_haveSeenMoveOnly)
- subpathFinder.m_zeroLengthSubpathLocations.append(subpathFinder.m_lastPoint);
- subpathFinder.m_lastPoint = subpathFinder.m_movePoint = element.points[0];
- subpathFinder.m_haveSeenMoveOnly = true;
- subpathFinder.m_pathIsZeroLength = true;
+ if (subpathFinder->m_pathIsZeroLength && !subpathFinder->m_haveSeenMoveOnly)
+ subpathFinder->m_zeroLengthSubpathLocations.append(subpathFinder->m_lastPoint);
+ subpathFinder->m_lastPoint = subpathFinder->m_movePoint = element->points[0];
+ subpathFinder->m_haveSeenMoveOnly = true;
+ subpathFinder->m_pathIsZeroLength = true;
break;
case PathElementAddLineToPoint:
- if (subpathFinder.m_lastPoint != element.points[0]) {
- subpathFinder.m_pathIsZeroLength = false;
- subpathFinder.m_lastPoint = element.points[0];
+ if (subpathFinder->m_lastPoint != element->points[0]) {
+ subpathFinder->m_pathIsZeroLength = false;
+ subpathFinder->m_lastPoint = element->points[0];
}
- subpathFinder.m_haveSeenMoveOnly = false;
+ subpathFinder->m_haveSeenMoveOnly = false;
break;
case PathElementAddQuadCurveToPoint:
- if (subpathFinder.m_lastPoint != element.points[0] || element.points[0] != element.points[1]) {
- subpathFinder.m_pathIsZeroLength = false;
- subpathFinder.m_lastPoint = element.points[1];
+ if (subpathFinder->m_lastPoint != element->points[0] || element->points[0] != element->points[1]) {
+ subpathFinder->m_pathIsZeroLength = false;
+ subpathFinder->m_lastPoint = element->points[1];
}
- subpathFinder.m_haveSeenMoveOnly = false;
+ subpathFinder->m_haveSeenMoveOnly = false;
break;
case PathElementAddCurveToPoint:
- if (subpathFinder.m_lastPoint != element.points[0] || element.points[0] != element.points[1] || element.points[1] != element.points[2]) {
- subpathFinder.m_pathIsZeroLength = false;
- subpathFinder.m_lastPoint = element.points[2];
+ if (subpathFinder->m_lastPoint != element->points[0] || element->points[0] != element->points[1] || element->points[1] != element->points[2]) {
+ subpathFinder->m_pathIsZeroLength = false;
+ subpathFinder->m_lastPoint = element->points[2];
}
- subpathFinder.m_haveSeenMoveOnly = false;
+ subpathFinder->m_haveSeenMoveOnly = false;
break;
case PathElementCloseSubpath:
- if (subpathFinder.m_pathIsZeroLength)
- subpathFinder.m_zeroLengthSubpathLocations.append(subpathFinder.m_lastPoint);
- subpathFinder.m_haveSeenMoveOnly = true; // This is an implicit move for the next element
- subpathFinder.m_pathIsZeroLength = true; // A new sub-path also starts here
- subpathFinder.m_lastPoint = subpathFinder.m_movePoint;
+ if (subpathFinder->m_pathIsZeroLength)
+ subpathFinder->m_zeroLengthSubpathLocations.append(subpathFinder->m_lastPoint);
+ subpathFinder->m_haveSeenMoveOnly = true; // This is an implicit move for the next element
+ subpathFinder->m_pathIsZeroLength = true; // A new sub-path also starts here
+ subpathFinder->m_lastPoint = subpathFinder->m_movePoint;
break;
}
}
@@ -83,11 +89,12 @@ private:
Vector<FloatPoint>& m_zeroLengthSubpathLocations;
FloatPoint m_lastPoint;
FloatPoint m_movePoint;
- bool m_haveSeenMoveOnly { false };
- bool m_pathIsZeroLength { false };
+ bool m_haveSeenMoveOnly;
+ bool m_pathIsZeroLength;
};
}
+#endif // ENABLE(SVG)
#endif // SVGSubpathData_h
diff --git a/Source/WebCore/rendering/svg/SVGTextChunk.cpp b/Source/WebCore/rendering/svg/SVGTextChunk.cpp
index 999b0821d..b7072753b 100644
--- a/Source/WebCore/rendering/svg/SVGTextChunk.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextChunk.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2015 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
@@ -19,191 +18,67 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextChunk.h"
#include "SVGInlineTextBox.h"
namespace WebCore {
-SVGTextChunk::SVGTextChunk(const Vector<SVGInlineTextBox*>& lineLayoutBoxes, unsigned first, unsigned limit)
+SVGTextChunk::SVGTextChunk(unsigned chunkStyle, float desiredTextLength)
+ : m_chunkStyle(chunkStyle)
+ , m_desiredTextLength(desiredTextLength)
{
- ASSERT(first < limit);
- ASSERT(limit <= lineLayoutBoxes.size());
-
- const SVGInlineTextBox* box = lineLayoutBoxes[first];
- const RenderStyle& style = box->renderer().style();
- const SVGRenderStyle& svgStyle = style.svgStyle();
-
- if (!style.isLeftToRightDirection())
- m_chunkStyle |= SVGTextChunk::RightToLeftText;
-
- if (svgStyle.isVerticalWritingMode())
- m_chunkStyle |= SVGTextChunk::VerticalText;
-
- switch (svgStyle.textAnchor()) {
- case TA_START:
- break;
- case TA_MIDDLE:
- m_chunkStyle |= MiddleAnchor;
- break;
- case TA_END:
- m_chunkStyle |= EndAnchor;
- break;
- }
-
- if (auto* textContentElement = SVGTextContentElement::elementFromRenderer(box->renderer().parent())) {
- SVGLengthContext lengthContext(textContentElement);
- m_desiredTextLength = textContentElement->specifiedTextLength().value(lengthContext);
-
- switch (textContentElement->lengthAdjust()) {
- case SVGLengthAdjustUnknown:
- break;
- case SVGLengthAdjustSpacing:
- m_chunkStyle |= LengthAdjustSpacing;
- break;
- case SVGLengthAdjustSpacingAndGlyphs:
- m_chunkStyle |= LengthAdjustSpacingAndGlyphs;
- break;
- }
- }
-
- for (unsigned i = first; i < limit; ++i)
- m_boxes.append(lineLayoutBoxes[i]);
}
-unsigned SVGTextChunk::totalCharacters() const
+void SVGTextChunk::calculateLength(float& length, unsigned& characters) const
{
- unsigned characters = 0;
- for (auto* box : m_boxes) {
- for (auto& fragment : box->textFragments())
- characters += fragment.length;
- }
- return characters;
-}
+ SVGTextFragment* lastFragment = 0;
-float SVGTextChunk::totalLength() const
-{
- const SVGTextFragment* firstFragment = nullptr;
- const SVGTextFragment* lastFragment = nullptr;
-
- for (auto* box : m_boxes) {
- auto& fragments = box->textFragments();
- if (fragments.size()) {
- firstFragment = &(*fragments.begin());
- break;
- }
- }
-
- for (auto it = m_boxes.rbegin(), end = m_boxes.rend(); it != end; ++it) {
- auto& fragments = (*it)->textFragments();
- if (fragments.size()) {
- lastFragment = &(*fragments.rbegin());
- break;
- }
- }
+ unsigned boxCount = m_boxes.size();
+ for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
+ SVGInlineTextBox* textBox = m_boxes.at(boxPosition);
+ Vector<SVGTextFragment>& fragments = textBox->textFragments();
- ASSERT(!firstFragment == !lastFragment);
- if (!firstFragment)
- return 0;
+ unsigned size = fragments.size();
+ if (!size)
+ continue;
- if (m_chunkStyle & VerticalText)
- return (lastFragment->y + lastFragment->height) - firstFragment->y;
-
- return (lastFragment->x + lastFragment->width) - firstFragment->x;
-}
-
-float SVGTextChunk::totalAnchorShift() const
-{
- float length = totalLength();
- if (m_chunkStyle & MiddleAnchor)
- return -length / 2;
- if (m_chunkStyle & EndAnchor)
- return m_chunkStyle & RightToLeftText ? 0 : -length;
- return m_chunkStyle & RightToLeftText ? -length : 0;
-}
+ for (unsigned i = 0; i < size; ++i) {
+ SVGTextFragment& fragment = fragments.at(i);
+ characters += fragment.length;
-void SVGTextChunk::layout(HashMap<SVGInlineTextBox*, AffineTransform>& textBoxTransformations) const
-{
- if (hasDesiredTextLength()) {
- if (hasLengthAdjustSpacing())
- processTextLengthSpacingCorrection();
- else {
- ASSERT(hasLengthAdjustSpacingAndGlyphs());
- buildBoxTransformations(textBoxTransformations);
- }
- }
+ if (m_chunkStyle & VerticalText)
+ length += fragment.height;
+ else
+ length += fragment.width;
- if (hasTextAnchor())
- processTextAnchorCorrection();
-}
+ if (!lastFragment) {
+ lastFragment = &fragment;
+ continue;
+ }
-void SVGTextChunk::processTextLengthSpacingCorrection() const
-{
- float textLengthShift = (desiredTextLength() - totalLength()) / totalCharacters();
- bool isVerticalText = m_chunkStyle & VerticalText;
- unsigned atCharacter = 0;
-
- for (auto* box : m_boxes) {
- for (auto& fragment : box->textFragments()) {
- if (isVerticalText)
- fragment.y += textLengthShift * atCharacter;
+ // Resepect gap between chunks.
+ if (m_chunkStyle & VerticalText)
+ length += fragment.y - (lastFragment->y + lastFragment->height);
else
- fragment.x += textLengthShift * atCharacter;
-
- atCharacter += fragment.length;
- }
- }
-}
+ length += fragment.x - (lastFragment->x + lastFragment->width);
-void SVGTextChunk::buildBoxTransformations(HashMap<SVGInlineTextBox*, AffineTransform>& textBoxTransformations) const
-{
- AffineTransform spacingAndGlyphsTransform;
- bool foundFirstFragment = false;
-
- for (auto* box : m_boxes) {
- if (!foundFirstFragment) {
- if (!boxSpacingAndGlyphsTransform(box, spacingAndGlyphsTransform))
- continue;
- foundFirstFragment = true;
+ lastFragment = &fragment;
}
-
- textBoxTransformations.set(box, spacingAndGlyphsTransform);
}
}
-bool SVGTextChunk::boxSpacingAndGlyphsTransform(const SVGInlineTextBox* box, AffineTransform& spacingAndGlyphsTransform) const
-{
- auto& fragments = box->textFragments();
- if (fragments.isEmpty())
- return false;
-
- const SVGTextFragment& fragment = fragments.first();
- float scale = desiredTextLength() / totalLength();
-
- spacingAndGlyphsTransform.translate(fragment.x, fragment.y);
-
- if (m_chunkStyle & VerticalText)
- spacingAndGlyphsTransform.scaleNonUniform(1, scale);
- else
- spacingAndGlyphsTransform.scaleNonUniform(scale, 1);
-
- spacingAndGlyphsTransform.translate(-fragment.x, -fragment.y);
- return true;
-}
-
-void SVGTextChunk::processTextAnchorCorrection() const
+float SVGTextChunk::calculateTextAnchorShift(float length) const
{
- float textAnchorShift = totalAnchorShift();
- bool isVerticalText = m_chunkStyle & VerticalText;
-
- for (auto* box : m_boxes) {
- for (auto& fragment : box->textFragments()) {
- if (isVerticalText)
- fragment.y += textAnchorShift;
- else
- fragment.x += textAnchorShift;
- }
- }
+ if (m_chunkStyle & MiddleAnchor)
+ return -length / 2;
+ if (m_chunkStyle & EndAnchor)
+ return m_chunkStyle & RightToLeftText ? 0 : -length;
+ return m_chunkStyle & RightToLeftText ? -length : 0;
}
} // namespace WebCore
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextChunk.h b/Source/WebCore/rendering/svg/SVGTextChunk.h
index a0a4c4f9d..9618d9fb6 100644
--- a/Source/WebCore/rendering/svg/SVGTextChunk.h
+++ b/Source/WebCore/rendering/svg/SVGTextChunk.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2015 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
@@ -21,6 +20,7 @@
#ifndef SVGTextChunk_h
#define SVGTextChunk_h
+#if ENABLE(SVG)
#include "SVGRenderStyleDefs.h"
#include "SVGTextContentElement.h"
@@ -41,36 +41,31 @@ public:
LengthAdjustSpacingAndGlyphs = 1 << 6
};
- SVGTextChunk(const Vector<SVGInlineTextBox*>&, unsigned first, unsigned limit);
+ SVGTextChunk(unsigned chunkStyle, float desiredTextLength);
- unsigned totalCharacters() const;
- float totalLength() const;
- float totalAnchorShift() const;
- void layout(HashMap<SVGInlineTextBox*, AffineTransform>&) const;
-
-private:
- void processTextAnchorCorrection() const;
- void buildBoxTransformations(HashMap<SVGInlineTextBox*, AffineTransform>&) const;
- void processTextLengthSpacingCorrection() const;
+ void calculateLength(float& length, unsigned& characters) const;
+ float calculateTextAnchorShift(float length) const;
bool isVerticalText() const { return m_chunkStyle & VerticalText; }
float desiredTextLength() const { return m_desiredTextLength; }
+ Vector<SVGInlineTextBox*>& boxes() { return m_boxes; }
+ const Vector<SVGInlineTextBox*>& boxes() const { return m_boxes; }
+
bool hasDesiredTextLength() const { return m_desiredTextLength > 0 && ((m_chunkStyle & LengthAdjustSpacing) || (m_chunkStyle & LengthAdjustSpacingAndGlyphs)); }
- bool hasTextAnchor() const { return m_chunkStyle & RightToLeftText ? !(m_chunkStyle & EndAnchor) : (m_chunkStyle & (MiddleAnchor | EndAnchor)); }
+ bool hasTextAnchor() const { return m_chunkStyle & RightToLeftText ? !(m_chunkStyle & EndAnchor) : (m_chunkStyle & MiddleAnchor) || (m_chunkStyle & EndAnchor); }
bool hasLengthAdjustSpacing() const { return m_chunkStyle & LengthAdjustSpacing; }
bool hasLengthAdjustSpacingAndGlyphs() const { return m_chunkStyle & LengthAdjustSpacingAndGlyphs; }
- bool boxSpacingAndGlyphsTransform(const SVGInlineTextBox*, AffineTransform&) const;
-
private:
// Contains all SVGInlineTextBoxes this chunk spans.
Vector<SVGInlineTextBox*> m_boxes;
- unsigned m_chunkStyle { DefaultStyle };
- float m_desiredTextLength { 0 };
+ unsigned m_chunkStyle;
+ float m_desiredTextLength;
};
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextChunkBuilder.cpp b/Source/WebCore/rendering/svg/SVGTextChunkBuilder.cpp
index 68b2d4875..26ab67e25 100644
--- a/Source/WebCore/rendering/svg/SVGTextChunkBuilder.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextChunkBuilder.cpp
@@ -1,6 +1,5 @@
/*
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2015 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
@@ -19,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextChunkBuilder.h"
#include "SVGElement.h"
@@ -31,71 +32,229 @@ SVGTextChunkBuilder::SVGTextChunkBuilder()
{
}
-unsigned SVGTextChunkBuilder::totalCharacters() const
+void SVGTextChunkBuilder::transformationForTextBox(SVGInlineTextBox* textBox, AffineTransform& transform) const
{
- unsigned characters = 0;
- for (const auto& chunk : m_textChunks)
- characters += chunk.totalCharacters();
- return characters;
+ DEFINE_STATIC_LOCAL(const AffineTransform, s_identityTransform, ());
+ if (!m_textBoxTransformations.contains(textBox)) {
+ transform = s_identityTransform;
+ return;
+ }
+
+ transform = m_textBoxTransformations.get(textBox);
}
-float SVGTextChunkBuilder::totalLength() const
+void SVGTextChunkBuilder::buildTextChunks(Vector<SVGInlineTextBox*>& lineLayoutBoxes)
{
- float length = 0;
- for (const auto& chunk : m_textChunks)
- length += chunk.totalLength();
- return length;
+ if (lineLayoutBoxes.isEmpty())
+ return;
+
+ bool foundStart = false;
+ unsigned lastChunkStartPosition = 0;
+ unsigned boxPosition = 0;
+ unsigned boxCount = lineLayoutBoxes.size();
+ for (; boxPosition < boxCount; ++boxPosition) {
+ SVGInlineTextBox* textBox = lineLayoutBoxes[boxPosition];
+ if (!textBox->startsNewTextChunk())
+ continue;
+
+ if (!foundStart) {
+ lastChunkStartPosition = boxPosition;
+ foundStart = true;
+ } else {
+ ASSERT_WITH_SECURITY_IMPLICATION(boxPosition > lastChunkStartPosition);
+ addTextChunk(lineLayoutBoxes, lastChunkStartPosition, boxPosition - lastChunkStartPosition);
+ lastChunkStartPosition = boxPosition;
+ }
+ }
+
+ if (!foundStart)
+ return;
+
+ if (boxPosition - lastChunkStartPosition > 0)
+ addTextChunk(lineLayoutBoxes, lastChunkStartPosition, boxPosition - lastChunkStartPosition);
}
-float SVGTextChunkBuilder::totalAnchorShift() const
+void SVGTextChunkBuilder::layoutTextChunks(Vector<SVGInlineTextBox*>& lineLayoutBoxes)
{
- float anchorShift = 0;
- for (const auto& chunk : m_textChunks)
- anchorShift += chunk.totalAnchorShift();
- return anchorShift;
+ buildTextChunks(lineLayoutBoxes);
+ if (m_textChunks.isEmpty())
+ return;
+
+ unsigned chunkCount = m_textChunks.size();
+ for (unsigned i = 0; i < chunkCount; ++i)
+ processTextChunk(m_textChunks[i]);
+
+ m_textChunks.clear();
}
-AffineTransform SVGTextChunkBuilder::transformationForTextBox(SVGInlineTextBox* textBox) const
+void SVGTextChunkBuilder::addTextChunk(Vector<SVGInlineTextBox*>& lineLayoutBoxes, unsigned boxStart, unsigned boxCount)
{
- auto it = m_textBoxTransformations.find(textBox);
- return it == m_textBoxTransformations.end() ? AffineTransform() : it->value;
+ SVGInlineTextBox* textBox = lineLayoutBoxes[boxStart];
+ ASSERT(textBox);
+
+ const RenderStyle& style = textBox->renderer().style();
+
+ const SVGRenderStyle& svgStyle = style.svgStyle();
+
+ // Build chunk style flags.
+ unsigned chunkStyle = SVGTextChunk::DefaultStyle;
+
+ // Handle 'direction' property.
+ if (!style.isLeftToRightDirection())
+ chunkStyle |= SVGTextChunk::RightToLeftText;
+
+ // Handle 'writing-mode' property.
+ if (svgStyle.isVerticalWritingMode())
+ chunkStyle |= SVGTextChunk::VerticalText;
+
+ // Handle 'text-anchor' property.
+ switch (svgStyle.textAnchor()) {
+ case TA_START:
+ break;
+ case TA_MIDDLE:
+ chunkStyle |= SVGTextChunk::MiddleAnchor;
+ break;
+ case TA_END:
+ chunkStyle |= SVGTextChunk::EndAnchor;
+ break;
+ };
+
+ // Handle 'lengthAdjust' property.
+ float desiredTextLength = 0;
+ if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textBox->renderer().parent())) {
+ SVGLengthContext lengthContext(textContentElement);
+ desiredTextLength = textContentElement->specifiedTextLength().value(lengthContext);
+
+ switch (textContentElement->lengthAdjust()) {
+ case SVGLengthAdjustUnknown:
+ break;
+ case SVGLengthAdjustSpacing:
+ chunkStyle |= SVGTextChunk::LengthAdjustSpacing;
+ break;
+ case SVGLengthAdjustSpacingAndGlyphs:
+ chunkStyle |= SVGTextChunk::LengthAdjustSpacingAndGlyphs;
+ break;
+ };
+ }
+
+ SVGTextChunk chunk(chunkStyle, desiredTextLength);
+
+ Vector<SVGInlineTextBox*>& boxes = chunk.boxes();
+ for (unsigned i = boxStart; i < boxStart + boxCount; ++i)
+ boxes.append(lineLayoutBoxes[i]);
+
+ m_textChunks.append(chunk);
}
-void SVGTextChunkBuilder::buildTextChunks(const Vector<SVGInlineTextBox*>& lineLayoutBoxes)
+void SVGTextChunkBuilder::processTextChunk(const SVGTextChunk& chunk)
{
- if (lineLayoutBoxes.isEmpty())
+ bool processTextLength = chunk.hasDesiredTextLength();
+ bool processTextAnchor = chunk.hasTextAnchor();
+ if (!processTextAnchor && !processTextLength)
+ return;
+
+ const Vector<SVGInlineTextBox*>& boxes = chunk.boxes();
+ unsigned boxCount = boxes.size();
+ if (!boxCount)
return;
- unsigned limit = lineLayoutBoxes.size();
- unsigned first = limit;
+ // Calculate absolute length of whole text chunk (starting from text box 'start', spanning 'length' text boxes).
+ float chunkLength = 0;
+ unsigned chunkCharacters = 0;
+ chunk.calculateLength(chunkLength, chunkCharacters);
- for (unsigned i = 0; i < limit; ++i) {
- if (!lineLayoutBoxes[i]->startsNewTextChunk())
- continue;
+ bool isVerticalText = chunk.isVerticalText();
+ if (processTextLength) {
+ if (chunk.hasLengthAdjustSpacing()) {
+ float textLengthShift = (chunk.desiredTextLength() - chunkLength) / chunkCharacters;
+ unsigned atCharacter = 0;
+ for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
+ Vector<SVGTextFragment>& fragments = boxes[boxPosition]->textFragments();
+ if (fragments.isEmpty())
+ continue;
+ processTextLengthSpacingCorrection(isVerticalText, textLengthShift, fragments, atCharacter);
+ }
+ } else {
+ ASSERT(chunk.hasLengthAdjustSpacingAndGlyphs());
+ float textLengthScale = chunk.desiredTextLength() / chunkLength;
+ AffineTransform spacingAndGlyphsTransform;
+
+ bool foundFirstFragment = false;
+ for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
+ SVGInlineTextBox* textBox = boxes[boxPosition];
+ Vector<SVGTextFragment>& fragments = textBox->textFragments();
+ if (fragments.isEmpty())
+ continue;
+
+ if (!foundFirstFragment) {
+ foundFirstFragment = true;
+ buildSpacingAndGlyphsTransform(isVerticalText, textLengthScale, fragments.first(), spacingAndGlyphsTransform);
+ }
- if (first == limit)
- first = i;
- else {
- ASSERT_WITH_SECURITY_IMPLICATION(first != i);
- m_textChunks.append(SVGTextChunk(lineLayoutBoxes, first, i));
- first = i;
+ m_textBoxTransformations.set(textBox, spacingAndGlyphsTransform);
+ }
}
}
- if (first != limit)
- m_textChunks.append(SVGTextChunk(lineLayoutBoxes, first, limit));
+ if (!processTextAnchor)
+ return;
+
+ // If we previously applied a lengthAdjust="spacing" correction, we have to recalculate the chunk length, to be able to apply the text-anchor shift.
+ if (processTextLength && chunk.hasLengthAdjustSpacing()) {
+ chunkLength = 0;
+ chunkCharacters = 0;
+ chunk.calculateLength(chunkLength, chunkCharacters);
+ }
+
+ float textAnchorShift = chunk.calculateTextAnchorShift(chunkLength);
+ for (unsigned boxPosition = 0; boxPosition < boxCount; ++boxPosition) {
+ Vector<SVGTextFragment>& fragments = boxes[boxPosition]->textFragments();
+ if (fragments.isEmpty())
+ continue;
+ processTextAnchorCorrection(isVerticalText, textAnchorShift, fragments);
+ }
}
-void SVGTextChunkBuilder::layoutTextChunks(const Vector<SVGInlineTextBox*>& lineLayoutBoxes)
+void SVGTextChunkBuilder::processTextLengthSpacingCorrection(bool isVerticalText, float textLengthShift, Vector<SVGTextFragment>& fragments, unsigned& atCharacter)
{
- buildTextChunks(lineLayoutBoxes);
- if (m_textChunks.isEmpty())
- return;
+ unsigned fragmentCount = fragments.size();
+ for (unsigned i = 0; i < fragmentCount; ++i) {
+ SVGTextFragment& fragment = fragments[i];
- for (const auto& chunk : m_textChunks)
- chunk.layout(m_textBoxTransformations);
+ if (isVerticalText)
+ fragment.y += textLengthShift * atCharacter;
+ else
+ fragment.x += textLengthShift * atCharacter;
- m_textChunks.clear();
+ atCharacter += fragment.length;
+ }
}
+void SVGTextChunkBuilder::processTextAnchorCorrection(bool isVerticalText, float textAnchorShift, Vector<SVGTextFragment>& fragments)
+{
+ unsigned fragmentCount = fragments.size();
+ for (unsigned i = 0; i < fragmentCount; ++i) {
+ SVGTextFragment& fragment = fragments[i];
+
+ if (isVerticalText)
+ fragment.y += textAnchorShift;
+ else
+ fragment.x += textAnchorShift;
+ }
}
+
+void SVGTextChunkBuilder::buildSpacingAndGlyphsTransform(bool isVerticalText, float scale, const SVGTextFragment& fragment, AffineTransform& spacingAndGlyphsTransform)
+{
+ spacingAndGlyphsTransform.translate(fragment.x, fragment.y);
+
+ if (isVerticalText)
+ spacingAndGlyphsTransform.scaleNonUniform(1, scale);
+ else
+ spacingAndGlyphsTransform.scaleNonUniform(scale, 1);
+
+ spacingAndGlyphsTransform.translate(-fragment.x, -fragment.y);
+}
+
+}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextChunkBuilder.h b/Source/WebCore/rendering/svg/SVGTextChunkBuilder.h
index 6ecf08170..321f3915f 100644
--- a/Source/WebCore/rendering/svg/SVGTextChunkBuilder.h
+++ b/Source/WebCore/rendering/svg/SVGTextChunkBuilder.h
@@ -1,6 +1,5 @@
/*
* Copyright (C) Research In Motion Limited 2010. All rights reserved.
- * Copyright (C) 2015 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
@@ -21,6 +20,7 @@
#ifndef SVGTextChunkBuilder_h
#define SVGTextChunkBuilder_h
+#if ENABLE(SVG)
#include "SVGTextChunk.h"
#include <wtf/Vector.h>
@@ -41,13 +41,18 @@ public:
SVGTextChunkBuilder();
const Vector<SVGTextChunk>& textChunks() const { return m_textChunks; }
- unsigned totalCharacters() const;
- float totalLength() const;
- float totalAnchorShift() const;
- AffineTransform transformationForTextBox(SVGInlineTextBox*) const;
+ void transformationForTextBox(SVGInlineTextBox*, AffineTransform&) const;
- void buildTextChunks(const Vector<SVGInlineTextBox*>& lineLayoutBoxes);
- void layoutTextChunks(const Vector<SVGInlineTextBox*>& lineLayoutBoxes);
+ void buildTextChunks(Vector<SVGInlineTextBox*>& lineLayoutBoxes);
+ void layoutTextChunks(Vector<SVGInlineTextBox*>& lineLayoutBoxes);
+
+private:
+ void addTextChunk(Vector<SVGInlineTextBox*>& lineLayoutBoxes, unsigned boxPosition, unsigned boxCount);
+ void processTextChunk(const SVGTextChunk&);
+
+ void processTextLengthSpacingCorrection(bool isVerticalText, float textLengthShift, Vector<SVGTextFragment>&, unsigned& atCharacter);
+ void processTextAnchorCorrection(bool isVerticalText, float textAnchorShift, Vector<SVGTextFragment>&);
+ void buildSpacingAndGlyphsTransform(bool isVerticalText, float scale, const SVGTextFragment&, AffineTransform&);
private:
Vector<SVGTextChunk> m_textChunks;
@@ -56,4 +61,5 @@ private:
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextFragment.h b/Source/WebCore/rendering/svg/SVGTextFragment.h
index d70dae93e..a44d0fabc 100644
--- a/Source/WebCore/rendering/svg/SVGTextFragment.h
+++ b/Source/WebCore/rendering/svg/SVGTextFragment.h
@@ -20,6 +20,7 @@
#ifndef SVGTextFragment_h
#define SVGTextFragment_h
+#if ENABLE(SVG)
#include "AffineTransform.h"
namespace WebCore {
@@ -110,4 +111,5 @@ private:
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp
index 6441272a4..05d6cc332 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.cpp
@@ -18,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextLayoutAttributes.h"
#include <stdio.h>
@@ -72,3 +74,5 @@ void SVGTextLayoutAttributes::dump() const
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.h b/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.h
index 305db1eaf..00d138e53 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.h
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutAttributes.h
@@ -20,6 +20,7 @@
#ifndef SVGTextLayoutAttributes_h
#define SVGTextLayoutAttributes_h
+#if ENABLE(SVG)
#include "SVGTextMetrics.h"
#include <wtf/HashMap.h>
#include <wtf/Noncopyable.h>
@@ -75,4 +76,5 @@ inline SVGCharacterData::SVGCharacterData()
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
index 16e27cc1f..1dbb01fd9 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.cpp
@@ -18,9 +18,10 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextLayoutAttributesBuilder.h"
-#include "RenderSVGInline.h"
#include "RenderSVGInlineText.h"
#include "RenderSVGText.h"
#include "SVGTextPositioningElement.h"
@@ -34,7 +35,7 @@ SVGTextLayoutAttributesBuilder::SVGTextLayoutAttributesBuilder()
void SVGTextLayoutAttributesBuilder::buildLayoutAttributesForTextRenderer(RenderSVGInlineText& text)
{
- auto* textRoot = RenderSVGText::locateRenderSVGTextAncestor(text);
+ RenderSVGText* textRoot = RenderSVGText::locateRenderSVGTextAncestor(&text);
if (!textRoot)
return;
@@ -42,79 +43,82 @@ void SVGTextLayoutAttributesBuilder::buildLayoutAttributesForTextRenderer(Render
m_characterDataMap.clear();
m_textLength = 0;
- bool lastCharacterWasSpace = true;
- collectTextPositioningElements(*textRoot, lastCharacterWasSpace);
+ const UChar* lastCharacter = 0;
+ collectTextPositioningElements(textRoot, lastCharacter);
if (!m_textLength)
return;
- buildCharacterDataMap(*textRoot);
+ buildCharacterDataMap(textRoot);
}
- m_metricsBuilder.buildMetricsAndLayoutAttributes(*textRoot, &text, m_characterDataMap);
+ m_metricsBuilder.buildMetricsAndLayoutAttributes(textRoot, &text, m_characterDataMap);
}
-bool SVGTextLayoutAttributesBuilder::buildLayoutAttributesForForSubtree(RenderSVGText& textRoot)
+bool SVGTextLayoutAttributesBuilder::buildLayoutAttributesForForSubtree(RenderSVGText* textRoot)
{
+ ASSERT(textRoot);
+
m_characterDataMap.clear();
if (m_textPositions.isEmpty()) {
m_textLength = 0;
- bool lastCharacterWasSpace = true;
- collectTextPositioningElements(textRoot, lastCharacterWasSpace);
+ const UChar* lastCharacter = 0;
+ collectTextPositioningElements(textRoot, lastCharacter);
}
if (!m_textLength)
return false;
buildCharacterDataMap(textRoot);
- m_metricsBuilder.buildMetricsAndLayoutAttributes(textRoot, nullptr, m_characterDataMap);
+ m_metricsBuilder.buildMetricsAndLayoutAttributes(textRoot, 0, m_characterDataMap);
return true;
}
-void SVGTextLayoutAttributesBuilder::rebuildMetricsForTextRenderer(RenderSVGInlineText& text)
+void SVGTextLayoutAttributesBuilder::rebuildMetricsForTextRenderer(RenderSVGInlineText* text)
{
+ ASSERT(text);
m_metricsBuilder.measureTextRenderer(text);
}
-static inline void processRenderSVGInlineText(const RenderSVGInlineText& text, unsigned& atCharacter, bool& lastCharacterWasSpace)
+static inline void processRenderSVGInlineText(RenderSVGInlineText* text, unsigned& atCharacter, const UChar*& lastCharacter)
{
- if (text.style().whiteSpace() == PRE) {
- atCharacter += text.textLength();
+ if (text->style().whiteSpace() == PRE) {
+ atCharacter += text->textLength();
return;
}
- for (unsigned textPosition = 0, textLength = text.textLength(); textPosition < textLength; ++textPosition) {
- const UChar currentCharacter = text[textPosition];
- if (currentCharacter == ' ' && lastCharacterWasSpace)
+ const UChar* characters = text->deprecatedCharacters();
+ unsigned textLength = text->textLength();
+ for (unsigned textPosition = 0; textPosition < textLength; ++textPosition) {
+ const UChar* currentCharacter = characters + textPosition;
+ if (*currentCharacter == ' ' && (!lastCharacter || *lastCharacter == ' '))
continue;
- lastCharacterWasSpace = currentCharacter == ' ';
+ lastCharacter = currentCharacter;
++atCharacter;
}
}
-void SVGTextLayoutAttributesBuilder::collectTextPositioningElements(RenderBoxModelObject& start, bool& lastCharacterWasSpace)
+void SVGTextLayoutAttributesBuilder::collectTextPositioningElements(RenderObject* start, const UChar*& lastCharacter)
{
- ASSERT(!is<RenderSVGText>(start) || m_textPositions.isEmpty());
+ ASSERT(!start->isSVGText() || m_textPositions.isEmpty());
- for (RenderObject* child = start.firstChild(); child; child = child->nextSibling()) {
- if (is<RenderSVGInlineText>(*child)) {
- processRenderSVGInlineText(downcast<RenderSVGInlineText>(*child), m_textLength, lastCharacterWasSpace);
+ for (RenderObject* child = start->firstChildSlow(); child; child = child->nextSibling()) {
+ if (child->isSVGInlineText()) {
+ processRenderSVGInlineText(toRenderSVGInlineText(child), m_textLength, lastCharacter);
continue;
}
- if (!is<RenderSVGInline>(*child))
+ if (!child->isSVGInline())
continue;
- RenderSVGInline& inlineChild = downcast<RenderSVGInline>(*child);
- SVGTextPositioningElement* element = SVGTextPositioningElement::elementFromRenderer(inlineChild);
-
+ SVGTextPositioningElement* element = SVGTextPositioningElement::elementFromRenderer(child);
unsigned atPosition = m_textPositions.size();
if (element)
m_textPositions.append(TextPosition(element, m_textLength));
- collectTextPositioningElements(inlineChild, lastCharacterWasSpace);
+ collectTextPositioningElements(child, lastCharacter);
if (!element)
continue;
@@ -126,7 +130,7 @@ void SVGTextLayoutAttributesBuilder::collectTextPositioningElements(RenderBoxMod
}
}
-void SVGTextLayoutAttributesBuilder::buildCharacterDataMap(RenderSVGText& textRoot)
+void SVGTextLayoutAttributesBuilder::buildCharacterDataMap(RenderSVGText* textRoot)
{
SVGTextPositioningElement* outermostTextElement = SVGTextPositioningElement::elementFromRenderer(textRoot);
ASSERT(outermostTextElement);
@@ -228,3 +232,5 @@ void SVGTextLayoutAttributesBuilder::fillCharacterDataMap(const TextPosition& po
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.h b/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.h
index df39af8a1..5aa60e923 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.h
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutAttributesBuilder.h
@@ -20,11 +20,11 @@
#ifndef SVGTextLayoutAttributesBuilder_h
#define SVGTextLayoutAttributesBuilder_h
+#if ENABLE(SVG)
#include "SVGTextMetricsBuilder.h"
namespace WebCore {
-class RenderBoxModelObject;
class RenderObject;
class RenderSVGInlineText;
class RenderSVGText;
@@ -42,10 +42,10 @@ class SVGTextLayoutAttributesBuilder {
WTF_MAKE_NONCOPYABLE(SVGTextLayoutAttributesBuilder);
public:
SVGTextLayoutAttributesBuilder();
- bool buildLayoutAttributesForForSubtree(RenderSVGText&);
+ bool buildLayoutAttributesForForSubtree(RenderSVGText*);
void buildLayoutAttributesForTextRenderer(RenderSVGInlineText&);
- void rebuildMetricsForTextRenderer(RenderSVGInlineText&);
+ void rebuildMetricsForTextRenderer(RenderSVGInlineText*);
// Invoked whenever the underlying DOM tree changes, so that m_textPositions is rebuild.
void clearTextPositioningElements() { m_textPositions.clear(); }
@@ -65,8 +65,8 @@ private:
unsigned length;
};
- void buildCharacterDataMap(RenderSVGText&);
- void collectTextPositioningElements(RenderBoxModelObject&, bool& lastCharacterWasSpace);
+ void buildCharacterDataMap(RenderSVGText*);
+ void collectTextPositioningElements(RenderObject*, const UChar*& lastCharacter);
void fillCharacterDataMap(const TextPosition&);
private:
@@ -78,4 +78,5 @@ private:
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
index 0b1a3183a..aec25e146 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.cpp
@@ -18,9 +18,10 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextLayoutEngine.h"
-#include "PathTraversalState.h"
#include "RenderSVGTextPath.h"
#include "SVGElement.h"
#include "SVGInlineTextBox.h"
@@ -110,7 +111,7 @@ void SVGTextLayoutEngine::updateRelativePositionAdjustmentsIfNeeded(float dx, fl
m_dy = dy;
}
-void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox& textBox, Vector<SVGTextMetrics>& textMetricsValues)
+void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox* textBox, Vector<SVGTextMetrics>& textMetricsValues)
{
ASSERT(!m_currentTextFragment.length);
ASSERT(m_visualMetricsListOffset > 0);
@@ -137,7 +138,7 @@ void SVGTextLayoutEngine::recordTextFragment(SVGInlineTextBox& textBox, Vector<S
}
}
- textBox.textFragments().append(m_currentTextFragment);
+ textBox->textFragments().append(m_currentTextFragment);
m_currentTextFragment = SVGTextFragment();
}
@@ -161,39 +162,58 @@ bool SVGTextLayoutEngine::parentDefinesTextLength(RenderObject* parent) const
return false;
}
-void SVGTextLayoutEngine::beginTextPathLayout(RenderSVGTextPath& textPath, SVGTextLayoutEngine& lineLayout)
+void SVGTextLayoutEngine::beginTextPathLayout(RenderObject* object, SVGTextLayoutEngine& lineLayout)
{
+ ASSERT(object);
+
m_inPathLayout = true;
+ RenderSVGTextPath* textPath = toRenderSVGTextPath(object);
- m_textPath = textPath.layoutPath();
+ m_textPath = textPath->layoutPath();
if (m_textPath.isEmpty())
return;
-
- m_textPathStartOffset = textPath.startOffset();
+ m_textPathStartOffset = textPath->startOffset();
m_textPathLength = m_textPath.length();
if (m_textPathStartOffset > 0 && m_textPathStartOffset <= 1)
m_textPathStartOffset *= m_textPathLength;
+ float totalLength = 0;
+ unsigned totalCharacters = 0;
+
lineLayout.m_chunkLayoutBuilder.buildTextChunks(lineLayout.m_lineLayoutBoxes);
+ const Vector<SVGTextChunk>& textChunks = lineLayout.m_chunkLayoutBuilder.textChunks();
+
+ unsigned size = textChunks.size();
+ for (unsigned i = 0; i < size; ++i) {
+ const SVGTextChunk& chunk = textChunks.at(i);
+
+ float length = 0;
+ unsigned characters = 0;
+ chunk.calculateLength(length, characters);
+
+ // Handle text-anchor as additional start offset for text paths.
+ m_textPathStartOffset += chunk.calculateTextAnchorShift(length);
+
+ totalLength += length;
+ totalCharacters += characters;
+ }
- // Handle text-anchor as additional start offset for text paths.
- m_textPathStartOffset += lineLayout.m_chunkLayoutBuilder.totalAnchorShift();
m_textPathCurrentOffset = m_textPathStartOffset;
// Eventually handle textLength adjustments.
- auto* textContentElement = SVGTextContentElement::elementFromRenderer(&textPath);
- if (!textContentElement)
- return;
+ SVGLengthAdjustType lengthAdjust = SVGLengthAdjustUnknown;
+ float desiredTextLength = 0;
+
+ if (SVGTextContentElement* textContentElement = SVGTextContentElement::elementFromRenderer(textPath)) {
+ SVGLengthContext lengthContext(textContentElement);
+ lengthAdjust = textContentElement->lengthAdjust();
+ desiredTextLength = textContentElement->specifiedTextLength().value(lengthContext);
+ }
- SVGLengthContext lengthContext(textContentElement);
- float desiredTextLength = textContentElement->specifiedTextLength().value(lengthContext);
if (!desiredTextLength)
return;
- float totalLength = lineLayout.m_chunkLayoutBuilder.totalLength();
- unsigned totalCharacters = lineLayout.m_chunkLayoutBuilder.totalCharacters();
-
- if (textContentElement->lengthAdjust() == SVGLengthAdjustSpacing)
+ if (lengthAdjust == SVGLengthAdjustSpacing)
m_textPathSpacing = (desiredTextLength - totalLength) / totalCharacters;
else
m_textPathScaling = desiredTextLength / totalLength;
@@ -210,25 +230,27 @@ void SVGTextLayoutEngine::endTextPathLayout()
m_textPathScaling = 1;
}
-void SVGTextLayoutEngine::layoutInlineTextBox(SVGInlineTextBox& textBox)
+void SVGTextLayoutEngine::layoutInlineTextBox(SVGInlineTextBox* textBox)
{
- RenderSVGInlineText& text = textBox.renderer();
+ ASSERT(textBox);
+
+ RenderSVGInlineText& text = textBox->renderer();
ASSERT(text.parent());
ASSERT(text.parent()->element());
ASSERT(text.parent()->element()->isSVGElement());
const RenderStyle& style = text.style();
- textBox.clearTextFragments();
+ textBox->clearTextFragments();
m_isVerticalText = style.svgStyle().isVerticalWritingMode();
- layoutTextOnLineOrPath(textBox, text, style);
+ layoutTextOnLineOrPath(textBox, &text, &style);
if (m_inPathLayout) {
- m_pathLayoutBoxes.append(&textBox);
+ m_pathLayoutBoxes.append(textBox);
return;
}
- m_lineLayoutBoxes.append(&textBox);
+ m_lineLayoutBoxes.append(textBox);
}
#if DUMP_TEXT_FRAGMENTS > 0
@@ -270,7 +292,7 @@ void SVGTextLayoutEngine::finalizeTransformMatrices(Vector<SVGInlineTextBox*>& b
unsigned fragmentCount = fragments.size();
for (unsigned i = 0; i < fragmentCount; ++i) {
- textBoxTransformation = m_chunkLayoutBuilder.transformationForTextBox(textBox);
+ m_chunkLayoutBuilder.transformationForTextBox(textBox, textBoxTransformation);
if (textBoxTransformation.isIdentity())
continue;
ASSERT(fragments[i].lengthAdjustTransform.isIdentity());
@@ -358,12 +380,12 @@ bool SVGTextLayoutEngine::currentLogicalCharacterMetrics(SVGTextLayoutAttributes
return true;
}
-bool SVGTextLayoutEngine::currentVisualCharacterMetrics(const SVGInlineTextBox& textBox, Vector<SVGTextMetrics>& visualMetricsValues, SVGTextMetrics& visualMetrics)
+bool SVGTextLayoutEngine::currentVisualCharacterMetrics(SVGInlineTextBox* textBox, Vector<SVGTextMetrics>& visualMetricsValues, SVGTextMetrics& visualMetrics)
{
ASSERT(!visualMetricsValues.isEmpty());
unsigned textMetricsSize = visualMetricsValues.size();
- unsigned boxStart = textBox.start();
- unsigned boxLength = textBox.len();
+ unsigned boxStart = textBox->start();
+ unsigned boxLength = textBox->len();
if (m_visualMetricsListOffset == textMetricsSize)
return false;
@@ -398,28 +420,26 @@ void SVGTextLayoutEngine::advanceToNextVisualCharacter(const SVGTextMetrics& vis
m_visualCharacterOffset += visualMetrics.length();
}
-void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox& textBox, RenderSVGInlineText& text, const RenderStyle& style)
+void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox* textBox, RenderSVGInlineText* text, const RenderStyle* style)
{
if (m_inPathLayout && m_textPath.isEmpty())
return;
- RenderElement* textParent = text.parent();
- ASSERT(textParent);
- SVGElement* lengthContext = downcast<SVGElement>(textParent->element());
+ SVGElement* lengthContext = toSVGElement(text->parent()->element());
- bool definesTextLength = parentDefinesTextLength(textParent);
+ RenderObject* textParent = text->parent();
+ bool definesTextLength = textParent ? parentDefinesTextLength(textParent) : false;
- const SVGRenderStyle& svgStyle = style.svgStyle();
+ const SVGRenderStyle& svgStyle = style->svgStyle();
m_visualMetricsListOffset = 0;
m_visualCharacterOffset = 0;
- Vector<SVGTextMetrics>& visualMetricsValues = text.layoutAttributes()->textMetricsValues();
+ Vector<SVGTextMetrics>& visualMetricsValues = text->layoutAttributes()->textMetricsValues();
ASSERT(!visualMetricsValues.isEmpty());
- auto upconvertedCharacters = StringView(text.text()).upconvertedCharacters();
- const UChar* characters = upconvertedCharacters;
- const FontCascade& font = style.fontCascade();
+ const UChar* characters = text->deprecatedCharacters();
+ const Font& font = style->font();
SVGTextLayoutEngineSpacing spacingLayout(font);
SVGTextLayoutEngineBaseline baselineLayout(font);
@@ -428,7 +448,7 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox& textBox, Rend
bool applySpacingToNextCharacter = false;
float lastAngle = 0;
- float baselineShift = baselineLayout.calculateBaselineShift(svgStyle, lengthContext);
+ float baselineShift = baselineLayout.calculateBaselineShift(&svgStyle, lengthContext);
baselineShift -= baselineLayout.calculateAlignmentBaselineShift(m_isVerticalText, text);
// Main layout algorithm.
@@ -461,16 +481,16 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox& textBox, Rend
float x = data.x;
float y = data.y;
- // When we've advanced to the box start offset, determine using the original x/y values
- // whether this character starts a new text chunk before doing any further processing.
- if (m_visualCharacterOffset == textBox.start())
- textBox.setStartsNewTextChunk(logicalAttributes->context().characterStartsNewTextChunk(m_logicalCharacterOffset));
+ // When we've advanced to the box start offset, determine using the original x/y values,
+ // whether this character starts a new text chunk, before doing any further processing.
+ if (m_visualCharacterOffset == textBox->start())
+ textBox->setStartsNewTextChunk(logicalAttributes->context().characterStartsNewTextChunk(m_logicalCharacterOffset));
float angle = data.rotate == SVGTextLayoutAttributes::emptyValue() ? 0 : data.rotate;
// Calculate glyph orientation angle.
const UChar* currentCharacter = characters + m_visualCharacterOffset;
- float orientationAngle = baselineLayout.calculateGlyphOrientationAngle(m_isVerticalText, svgStyle, *currentCharacter);
+ float orientationAngle = baselineLayout.calculateGlyphOrientationAngle(m_isVerticalText, &svgStyle, *currentCharacter);
// Calculate glyph advance & x/y orientation shifts.
float xOrientationShift = 0;
@@ -533,15 +553,14 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox& textBox, Rend
if (textPathOffset > m_textPathLength)
break;
- bool success = false;
- auto traversalState(m_textPath.traversalStateAtLength(textPathOffset, success));
- ASSERT(success);
+ bool ok = false;
+ FloatPoint point = m_textPath.pointAtLength(textPathOffset, ok);
+ ASSERT(ok);
- FloatPoint point = traversalState.current();
x = point.x();
y = point.y();
-
- angle = traversalState.normalAngle();
+ angle = m_textPath.normalAngleAtLength(textPathOffset, ok);
+ ASSERT(ok);
// For vertical text on path, the actual angle has to be rotated 90 degrees anti-clockwise, not the orientation angle!
if (m_isVerticalText)
@@ -632,3 +651,5 @@ void SVGTextLayoutEngine::layoutTextOnLineOrPath(SVGInlineTextBox& textBox, Rend
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.h b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.h
index e0cbc943e..c4a926400 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngine.h
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngine.h
@@ -20,6 +20,7 @@
#ifndef SVGTextLayoutEngine_h
#define SVGTextLayoutEngine_h
+#if ENABLE(SVG)
#include "Path.h"
#include "SVGTextChunkBuilder.h"
#include "SVGTextFragment.h"
@@ -30,7 +31,6 @@ namespace WebCore {
class RenderObject;
class RenderStyle;
class RenderSVGInlineText;
-class RenderSVGTextPath;
class SVGElement;
class SVGInlineTextBox;
class SVGRenderStyle;
@@ -51,10 +51,10 @@ public:
Vector<SVGTextLayoutAttributes*>& layoutAttributes() { return m_layoutAttributes; }
SVGTextChunkBuilder& chunkLayoutBuilder() { return m_chunkLayoutBuilder; }
- void beginTextPathLayout(RenderSVGTextPath&, SVGTextLayoutEngine& lineLayout);
+ void beginTextPathLayout(RenderObject*, SVGTextLayoutEngine& lineLayout);
void endTextPathLayout();
- void layoutInlineTextBox(SVGInlineTextBox&);
+ void layoutInlineTextBox(SVGInlineTextBox*);
void finishLayout();
private:
@@ -62,15 +62,15 @@ private:
void updateCurrentTextPosition(float x, float y, float glyphAdvance);
void updateRelativePositionAdjustmentsIfNeeded(float dx, float dy);
- void recordTextFragment(SVGInlineTextBox&, Vector<SVGTextMetrics>&);
+ void recordTextFragment(SVGInlineTextBox*, Vector<SVGTextMetrics>&);
bool parentDefinesTextLength(RenderObject*) const;
- void layoutTextOnLineOrPath(SVGInlineTextBox&, RenderSVGInlineText&, const RenderStyle&);
+ void layoutTextOnLineOrPath(SVGInlineTextBox*, RenderSVGInlineText*, const RenderStyle*);
void finalizeTransformMatrices(Vector<SVGInlineTextBox*>&);
bool currentLogicalCharacterAttributes(SVGTextLayoutAttributes*&);
bool currentLogicalCharacterMetrics(SVGTextLayoutAttributes*&, SVGTextMetrics&);
- bool currentVisualCharacterMetrics(const SVGInlineTextBox&, Vector<SVGTextMetrics>&, SVGTextMetrics&);
+ bool currentVisualCharacterMetrics(SVGInlineTextBox*, Vector<SVGTextMetrics>&, SVGTextMetrics&);
void advanceToNextLogicalCharacter(const SVGTextMetrics&);
void advanceToNextVisualCharacter(const SVGTextMetrics&);
@@ -106,4 +106,5 @@ private:
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
index 378e529b0..0497a3456 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.cpp
@@ -18,9 +18,11 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextLayoutEngineBaseline.h"
-#include "FontCascade.h"
+#include "Font.h"
#include "RenderElement.h"
#include "SVGLengthContext.h"
#include "SVGRenderStyle.h"
@@ -28,34 +30,33 @@
namespace WebCore {
-SVGTextLayoutEngineBaseline::SVGTextLayoutEngineBaseline(const FontCascade& font)
+SVGTextLayoutEngineBaseline::SVGTextLayoutEngineBaseline(const Font& font)
: m_font(font)
{
}
-float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle& style, SVGElement* context) const
+float SVGTextLayoutEngineBaseline::calculateBaselineShift(const SVGRenderStyle* style, SVGElement* contextElement) const
{
- if (style.baselineShift() == BS_LENGTH) {
- SVGLength baselineShiftValueLength = style.baselineShiftValue();
+ if (style->baselineShift() == BS_LENGTH) {
+ SVGLength baselineShiftValueLength = style->baselineShiftValue();
if (baselineShiftValueLength.unitType() == LengthTypePercentage)
return baselineShiftValueLength.valueAsPercentage() * m_font.pixelSize();
- SVGLengthContext lengthContext(context);
+ SVGLengthContext lengthContext(contextElement);
return baselineShiftValueLength.value(lengthContext);
}
- switch (style.baselineShift()) {
+ switch (style->baselineShift()) {
case BS_BASELINE:
return 0;
case BS_SUB:
return -m_font.fontMetrics().floatHeight() / 2;
case BS_SUPER:
return m_font.fontMetrics().floatHeight() / 2;
- case BS_LENGTH:
- break;
+ default:
+ ASSERT_NOT_REACHED();
+ return 0;
}
- ASSERT_NOT_REACHED();
- return 0;
}
EAlignmentBaseline SVGTextLayoutEngineBaseline::dominantBaselineToAlignmentBaseline(bool isVerticalText, const RenderObject* textRenderer) const
@@ -103,12 +104,15 @@ EAlignmentBaseline SVGTextLayoutEngineBaseline::dominantBaselineToAlignmentBasel
}
}
-float SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift(bool isVerticalText, const RenderObject& textRenderer) const
+float SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift(bool isVerticalText, const RenderObject* textRenderer) const
{
- const RenderObject* textRendererParent = textRenderer.parent();
+ ASSERT(textRenderer);
+ ASSERT(textRenderer->parent());
+
+ const RenderObject* textRendererParent = textRenderer->parent();
ASSERT(textRendererParent);
- EAlignmentBaseline baseline = textRenderer.style().svgStyle().alignmentBaseline();
+ EAlignmentBaseline baseline = textRenderer->style().svgStyle().alignmentBaseline();
if (baseline == AB_AUTO) {
baseline = dominantBaselineToAlignmentBaseline(isVerticalText, textRendererParent);
ASSERT(baseline != AB_AUTO);
@@ -143,9 +147,11 @@ float SVGTextLayoutEngineBaseline::calculateAlignmentBaselineShift(bool isVertic
}
}
-float SVGTextLayoutEngineBaseline::calculateGlyphOrientationAngle(bool isVerticalText, const SVGRenderStyle& style, const UChar& character) const
+float SVGTextLayoutEngineBaseline::calculateGlyphOrientationAngle(bool isVerticalText, const SVGRenderStyle* style, const UChar& character) const
{
- switch (isVerticalText ? style.glyphOrientationVertical() : style.glyphOrientationHorizontal()) {
+ ASSERT(style);
+
+ switch (isVerticalText ? style->glyphOrientationVertical() : style->glyphOrientationHorizontal()) {
case GO_AUTO:
// Spec: Fullwidth ideographic and fullwidth Latin text will be set with a glyph-orientation of 0-degrees.
// Text which is not fullwidth will be set with a glyph-orientation of 90-degrees.
@@ -234,3 +240,5 @@ float SVGTextLayoutEngineBaseline::calculateGlyphAdvanceAndOrientation(bool isVe
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.h b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.h
index 4c1581be3..6794bf3f8 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.h
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineBaseline.h
@@ -20,12 +20,13 @@
#ifndef SVGTextLayoutEngineBaseline_h
#define SVGTextLayoutEngineBaseline_h
+#if ENABLE(SVG)
#include "SVGRenderStyleDefs.h"
#include <wtf/Noncopyable.h>
namespace WebCore {
-class FontCascade;
+class Font;
class RenderObject;
class SVGElement;
class SVGRenderStyle;
@@ -35,19 +36,20 @@ class SVGTextMetrics;
class SVGTextLayoutEngineBaseline {
WTF_MAKE_NONCOPYABLE(SVGTextLayoutEngineBaseline);
public:
- SVGTextLayoutEngineBaseline(const FontCascade&);
+ SVGTextLayoutEngineBaseline(const Font&);
- float calculateBaselineShift(const SVGRenderStyle&, SVGElement* context) const;
- float calculateAlignmentBaselineShift(bool isVerticalText, const RenderObject& textRenderer) const;
- float calculateGlyphOrientationAngle(bool isVerticalText, const SVGRenderStyle&, const UChar& character) const;
+ float calculateBaselineShift(const SVGRenderStyle*, SVGElement* lengthContext) const;
+ float calculateAlignmentBaselineShift(bool isVerticalText, const RenderObject* textRenderer) const;
+ float calculateGlyphOrientationAngle(bool isVerticalText, const SVGRenderStyle*, const UChar& character) const;
float calculateGlyphAdvanceAndOrientation(bool isVerticalText, SVGTextMetrics&, float angle, float& xOrientationShift, float& yOrientationShift) const;
private:
EAlignmentBaseline dominantBaselineToAlignmentBaseline(bool isVerticalText, const RenderObject* textRenderer) const;
- const FontCascade& m_font;
+ const Font& m_font;
};
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
index cb5d07496..f0107c4ab 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.cpp
@@ -18,9 +18,11 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextLayoutEngineSpacing.h"
-#include "FontCascade.h"
+#include "Font.h"
#include "SVGLengthContext.h"
#include "SVGRenderStyle.h"
@@ -32,7 +34,7 @@
namespace WebCore {
-SVGTextLayoutEngineSpacing::SVGTextLayoutEngineSpacing(const FontCascade& font)
+SVGTextLayoutEngineSpacing::SVGTextLayoutEngineSpacing(const Font& font)
: m_font(font)
, m_lastCharacter(0)
{
@@ -41,16 +43,16 @@ SVGTextLayoutEngineSpacing::SVGTextLayoutEngineSpacing(const FontCascade& font)
float SVGTextLayoutEngineSpacing::calculateSVGKerning(bool isVerticalText, const SVGTextMetrics::Glyph& currentGlyph)
{
#if ENABLE(SVG_FONTS)
- const Font& font = m_font.primaryFont();
- if (!font.isSVGFont()) {
+ const SimpleFontData* fontData = m_font.primaryFont();
+ if (!fontData->isSVGFont()) {
m_lastGlyph.isValid = false;
return 0;
}
- ASSERT(font.isCustomFont());
- ASSERT(font.isSVGFont());
+ ASSERT(fontData->isCustomFont());
+ ASSERT(fontData->isSVGFont());
- auto* svgFontData = static_cast<const SVGFontData*>(font.svgData());
+ const SVGFontData* svgFontData = static_cast<const SVGFontData*>(fontData->fontData());
SVGFontFaceElement* svgFontFace = svgFontData->svgFontFaceElement();
ASSERT(svgFontFace);
@@ -98,7 +100,7 @@ float SVGTextLayoutEngineSpacing::calculateCSSKerningAndSpacing(const SVGRenderS
float spacing = m_font.letterSpacing() + kerning;
if (currentCharacter && lastCharacter && m_font.wordSpacing()) {
- if (FontCascade::treatAsSpace(*currentCharacter) && !FontCascade::treatAsSpace(*lastCharacter))
+ if (Font::treatAsSpace(*currentCharacter) && !Font::treatAsSpace(*lastCharacter))
spacing += m_font.wordSpacing();
}
@@ -106,3 +108,5 @@ float SVGTextLayoutEngineSpacing::calculateCSSKerningAndSpacing(const SVGRenderS
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.h b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.h
index d9c18206a..71d470737 100644
--- a/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.h
+++ b/Source/WebCore/rendering/svg/SVGTextLayoutEngineSpacing.h
@@ -20,11 +20,12 @@
#ifndef SVGTextLayoutEngineSpacing_h
#define SVGTextLayoutEngineSpacing_h
+#if ENABLE(SVG)
#include "SVGTextMetrics.h"
namespace WebCore {
-class FontCascade;
+class Font;
class SVGRenderStyle;
class SVGElement;
@@ -32,13 +33,13 @@ class SVGElement;
class SVGTextLayoutEngineSpacing {
WTF_MAKE_NONCOPYABLE(SVGTextLayoutEngineSpacing);
public:
- SVGTextLayoutEngineSpacing(const FontCascade&);
+ SVGTextLayoutEngineSpacing(const Font&);
float calculateSVGKerning(bool isVerticalText, const SVGTextMetrics::Glyph& currentGlyph);
float calculateCSSKerningAndSpacing(const SVGRenderStyle*, SVGElement* lengthContext, const UChar* currentCharacter);
private:
- const FontCascade& m_font;
+ const Font& m_font;
const UChar* m_lastCharacter;
#if ENABLE(SVG_FONTS)
@@ -48,4 +49,5 @@ private:
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
index 27d4e4859..0e6446e31 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextMetrics.cpp
@@ -18,6 +18,8 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextMetrics.h"
#include "RenderSVGInlineText.h"
@@ -40,12 +42,14 @@ SVGTextMetrics::SVGTextMetrics(SVGTextMetrics::MetricsType)
{
}
-SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText& textRenderer, const TextRun& run)
+SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* textRenderer, const TextRun& run)
{
- float scalingFactor = textRenderer.scalingFactor();
+ ASSERT(textRenderer);
+
+ float scalingFactor = textRenderer->scalingFactor();
ASSERT(scalingFactor);
- const FontCascade& scaledFont = textRenderer.scaledFont();
+ const Font& scaledFont = textRenderer->scaledFont();
int length = 0;
// Calculate width/height using the scaled font, divide this result by the scalingFactor afterwards.
@@ -59,19 +63,20 @@ SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText& textRenderer, const TextRun&
m_length = static_cast<unsigned>(length);
}
-TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText& text, unsigned position, unsigned length)
+TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText* text, const UChar* characters, unsigned position, unsigned length)
{
- const RenderStyle& style = text.style();
+ const RenderStyle& style = text->style();
- TextRun run(StringView(text.text()).substring(position, length)
+ TextRun run(characters + position
+ , length
, 0 /* xPos, only relevant with allowTabs=true */
, 0 /* padding, only relevant for justified text, not relevant for SVG */
- , AllowTrailingExpansion
+ , TextRun::AllowTrailingExpansion
, style.direction()
, isOverride(style.unicodeBidi()) /* directionalOverride */);
- if (style.fontCascade().primaryFont().isSVGFont())
- run.setRenderingContext(SVGTextRunRenderingContext::create(text));
+ if (style.font().isSVGFont())
+ run.setRenderingContext(SVGTextRunRenderingContext::create(*text));
run.disableRoundingHacks();
@@ -79,27 +84,30 @@ TextRun SVGTextMetrics::constructTextRun(RenderSVGInlineText& text, unsigned pos
run.disableSpacing();
// Propagate the maximum length of the characters buffer to the TextRun, even when we're only processing a substring.
- run.setCharactersLength(text.textLength() - position);
+ run.setCharactersLength(text->textLength() - position);
ASSERT(run.charactersLength() >= run.length());
return run;
}
-SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText& text, unsigned position, unsigned length)
+SVGTextMetrics SVGTextMetrics::measureCharacterRange(RenderSVGInlineText* text, unsigned position, unsigned length)
{
- return SVGTextMetrics(text, constructTextRun(text, position, length));
+ ASSERT(text);
+ return SVGTextMetrics(text, constructTextRun(text, text->deprecatedCharacters(), position, length));
}
-SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText& text, unsigned position, unsigned length, float width, const String& glyphName)
+SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText* text, unsigned position, unsigned length, float width, const String& glyphName)
{
- bool needsContext = text.style().fontCascade().primaryFont().isSVGFont();
- float scalingFactor = text.scalingFactor();
+ ASSERT(text);
+
+ bool needsContext = text->style().font().isSVGFont();
+ float scalingFactor = text->scalingFactor();
ASSERT(scalingFactor);
m_width = width / scalingFactor;
- m_height = text.scaledFont().fontMetrics().floatHeight() / scalingFactor;
+ m_height = text->scaledFont().fontMetrics().floatHeight() / scalingFactor;
if (needsContext) {
m_glyph.isValid = true;
- m_glyph.unicodeString = text.text()->substring(position, length);
+ m_glyph.unicodeString = String(text->deprecatedCharacters() + position, length);
m_glyph.name = glyphName;
}
@@ -107,3 +115,5 @@ SVGTextMetrics::SVGTextMetrics(RenderSVGInlineText& text, unsigned position, uns
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextMetrics.h b/Source/WebCore/rendering/svg/SVGTextMetrics.h
index 61641a2cc..ba008c0ef 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetrics.h
+++ b/Source/WebCore/rendering/svg/SVGTextMetrics.h
@@ -20,6 +20,7 @@
#ifndef SVGTextMetrics_h
#define SVGTextMetrics_h
+#if ENABLE(SVG)
#include <wtf/text/WTFString.h>
namespace WebCore {
@@ -30,14 +31,16 @@ class TextRun;
class SVGTextMetrics {
public:
- enum MetricsType { SkippedSpaceMetrics };
+ enum MetricsType {
+ SkippedSpaceMetrics
+ };
SVGTextMetrics();
- explicit SVGTextMetrics(MetricsType);
- SVGTextMetrics(RenderSVGInlineText&, unsigned position, unsigned length, float width, const String& glyphName);
+ SVGTextMetrics(MetricsType);
+ SVGTextMetrics(RenderSVGInlineText*, unsigned position, unsigned length, float width, const String& glyphName);
- static SVGTextMetrics measureCharacterRange(RenderSVGInlineText&, unsigned position, unsigned length);
- static TextRun constructTextRun(RenderSVGInlineText&, unsigned position = 0, unsigned length = std::numeric_limits<unsigned>::max());
+ static SVGTextMetrics measureCharacterRange(RenderSVGInlineText*, unsigned position, unsigned length);
+ static TextRun constructTextRun(RenderSVGInlineText*, const UChar* characters, unsigned position, unsigned length);
bool isEmpty() const { return !m_width && !m_height && !m_glyph.isValid && m_length == 1; }
@@ -69,7 +72,7 @@ public:
const Glyph& glyph() const { return m_glyph; }
private:
- SVGTextMetrics(RenderSVGInlineText&, const TextRun&);
+ SVGTextMetrics(RenderSVGInlineText*, const TextRun&);
float m_width;
float m_height;
@@ -79,4 +82,5 @@ private:
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp b/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp
index 1447596dd..86009e6e9 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.cpp
@@ -18,9 +18,10 @@
*/
#include "config.h"
+
+#if ENABLE(SVG)
#include "SVGTextMetricsBuilder.h"
-#include "RenderSVGInline.h"
#include "RenderSVGInlineText.h"
#include "RenderSVGText.h"
#include "SVGTextRunRenderingContext.h"
@@ -29,7 +30,7 @@ namespace WebCore {
SVGTextMetricsBuilder::SVGTextMetricsBuilder()
: m_text(0)
- , m_run(StringView())
+ , m_run(static_cast<const UChar*>(0), 0)
, m_textPosition(0)
, m_isComplexText(false)
, m_totalWidth(0)
@@ -38,13 +39,13 @@ SVGTextMetricsBuilder::SVGTextMetricsBuilder()
inline bool SVGTextMetricsBuilder::currentCharacterStartsSurrogatePair() const
{
- return U16_IS_LEAD(m_run[m_textPosition]) && (m_textPosition + 1) < m_run.charactersLength() && U16_IS_TRAIL(m_run[m_textPosition + 1]);
+ return U16_IS_LEAD(m_run[m_textPosition]) && int(m_textPosition + 1) < m_run.charactersLength() && U16_IS_TRAIL(m_run[m_textPosition + 1]);
}
bool SVGTextMetricsBuilder::advance()
{
m_textPosition += m_currentMetrics.length();
- if (m_textPosition >= m_run.charactersLength())
+ if (int(m_textPosition) >= m_run.charactersLength())
return false;
if (m_isComplexText)
@@ -68,17 +69,17 @@ void SVGTextMetricsBuilder::advanceSimpleText()
m_totalWidth = m_simpleWidthIterator->runWidthSoFar();
#if ENABLE(SVG_FONTS)
- m_currentMetrics = SVGTextMetrics(*m_text, m_textPosition, metricsLength, currentWidth, m_simpleWidthIterator->lastGlyphName());
+ m_currentMetrics = SVGTextMetrics(m_text, m_textPosition, metricsLength, currentWidth, m_simpleWidthIterator->lastGlyphName());
#else
- m_currentMetrics = SVGTextMetrics(*m_text, m_textPosition, metricsLength, currentWidth, emptyString());
+ m_currentMetrics = SVGTextMetrics(m_text, m_textPosition, metricsLength, currentWidth, emptyString());
#endif
}
void SVGTextMetricsBuilder::advanceComplexText()
{
unsigned metricsLength = currentCharacterStartsSurrogatePair() ? 2 : 1;
- m_currentMetrics = SVGTextMetrics::measureCharacterRange(*m_text, m_textPosition, metricsLength);
- m_complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(*m_text, 0, m_textPosition + metricsLength);
+ m_currentMetrics = SVGTextMetrics::measureCharacterRange(m_text, m_textPosition, metricsLength);
+ m_complexStartToCurrentMetrics = SVGTextMetrics::measureCharacterRange(m_text, 0, m_textPosition + metricsLength);
ASSERT(m_currentMetrics.length() == metricsLength);
// Frequent case for Arabic text: when measuring a single character the arabic isolated form is taken
@@ -92,22 +93,22 @@ void SVGTextMetricsBuilder::advanceComplexText()
m_totalWidth = m_complexStartToCurrentMetrics.width();
}
-void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlineText& text)
+void SVGTextMetricsBuilder::initializeMeasurementWithTextRenderer(RenderSVGInlineText* text)
{
- m_text = &text;
+ m_text = text;
m_textPosition = 0;
m_currentMetrics = SVGTextMetrics();
m_complexStartToCurrentMetrics = SVGTextMetrics();
m_totalWidth = 0;
- const FontCascade& scaledFont = text.scaledFont();
- m_run = SVGTextMetrics::constructTextRun(text);
- m_isComplexText = scaledFont.codePath(m_run) == FontCascade::Complex;
+ const Font& scaledFont = text->scaledFont();
+ m_run = SVGTextMetrics::constructTextRun(text, text->deprecatedCharacters(), 0, text->textLength());
+ m_isComplexText = scaledFont.codePath(m_run) == Font::Complex;
if (m_isComplexText)
- m_simpleWidthIterator = nullptr;
+ m_simpleWidthIterator.clear();
else
- m_simpleWidthIterator = std::make_unique<WidthIterator>(&scaledFont, m_run);
+ m_simpleWidthIterator = adoptPtr(new WidthIterator(&scaledFont, m_run));
}
struct MeasureTextData {
@@ -121,15 +122,17 @@ struct MeasureTextData {
}
SVGCharacterDataMap* allCharactersMap;
- UChar lastCharacter;
+ const UChar* lastCharacter;
bool processRenderer;
unsigned valueListPosition;
unsigned skippedCharacters;
};
-void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText& text, MeasureTextData* data)
+void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text, MeasureTextData* data)
{
- SVGTextLayoutAttributes* attributes = text.layoutAttributes();
+ ASSERT(text);
+
+ SVGTextLayoutAttributes* attributes = text->layoutAttributes();
Vector<SVGTextMetrics>* textMetricsValues = &attributes->textMetricsValues();
if (data->processRenderer) {
if (data->allCharactersMap)
@@ -139,12 +142,12 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText& text, Measu
}
initializeMeasurementWithTextRenderer(text);
- bool preserveWhiteSpace = text.style().whiteSpace() == PRE;
+ bool preserveWhiteSpace = text->style().whiteSpace() == PRE;
int surrogatePairCharacters = 0;
while (advance()) {
- UChar currentCharacter = m_run[m_textPosition];
- if (currentCharacter == ' ' && !preserveWhiteSpace && (!data->lastCharacter || data->lastCharacter == ' ')) {
+ const UChar* currentCharacter = m_run.data16(m_textPosition);
+ if (*currentCharacter == ' ' && !preserveWhiteSpace && (!data->lastCharacter || *data->lastCharacter == ' ')) {
if (data->processRenderer)
textMetricsValues->append(SVGTextMetrics(SVGTextMetrics::SkippedSpaceMetrics));
if (data->allCharactersMap)
@@ -176,10 +179,10 @@ void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText& text, Measu
void SVGTextMetricsBuilder::walkTree(RenderElement& start, RenderSVGInlineText* stopAtLeaf, MeasureTextData* data)
{
- for (auto* child = start.firstChild(); child; child = child->nextSibling()) {
- if (is<RenderSVGInlineText>(*child)) {
- RenderSVGInlineText& text = downcast<RenderSVGInlineText>(*child);
- if (stopAtLeaf && stopAtLeaf != &text) {
+ for (auto child = start.firstChild(); child; child = child->nextSibling()) {
+ if (child->isSVGInlineText()) {
+ RenderSVGInlineText* text = toRenderSVGInlineText(child);
+ if (stopAtLeaf && stopAtLeaf != text) {
data->processRenderer = false;
measureTextRenderer(text, data);
continue;
@@ -193,27 +196,32 @@ void SVGTextMetricsBuilder::walkTree(RenderElement& start, RenderSVGInlineText*
continue;
}
- if (!is<RenderSVGInline>(*child))
+ if (!child->isSVGInline())
continue;
- walkTree(downcast<RenderSVGInline>(*child), stopAtLeaf, data);
+ walkTree(toRenderElement(*child), stopAtLeaf, data);
}
}
-void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText& text)
+void SVGTextMetricsBuilder::measureTextRenderer(RenderSVGInlineText* text)
{
- auto* textRoot = RenderSVGText::locateRenderSVGTextAncestor(text);
+ ASSERT(text);
+
+ RenderSVGText* textRoot = RenderSVGText::locateRenderSVGTextAncestor(text);
if (!textRoot)
return;
- MeasureTextData data(nullptr);
- walkTree(*textRoot, &text, &data);
+ MeasureTextData data(0);
+ walkTree(*textRoot, text, &data);
}
-void SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(RenderSVGText& textRoot, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap)
+void SVGTextMetricsBuilder::buildMetricsAndLayoutAttributes(RenderSVGText* textRoot, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap)
{
+ ASSERT(textRoot);
MeasureTextData data(&allCharactersMap);
- walkTree(textRoot, stopAtLeaf, &data);
+ walkTree(*textRoot, stopAtLeaf, &data);
}
}
+
+#endif // ENABLE(SVG)
diff --git a/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.h b/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.h
index 08e07eeb1..5e0d12951 100644
--- a/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.h
+++ b/Source/WebCore/rendering/svg/SVGTextMetricsBuilder.h
@@ -20,6 +20,7 @@
#ifndef SVGTextMetricsBuilder_h
#define SVGTextMetricsBuilder_h
+#if ENABLE(SVG)
#include "SVGTextLayoutAttributes.h"
#include "TextRun.h"
#include "WidthIterator.h"
@@ -35,8 +36,8 @@ class SVGTextMetricsBuilder {
WTF_MAKE_NONCOPYABLE(SVGTextMetricsBuilder);
public:
SVGTextMetricsBuilder();
- void measureTextRenderer(RenderSVGInlineText&);
- void buildMetricsAndLayoutAttributes(RenderSVGText&, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap);
+ void measureTextRenderer(RenderSVGInlineText*);
+ void buildMetricsAndLayoutAttributes(RenderSVGText*, RenderSVGInlineText* stopAtLeaf, SVGCharacterDataMap& allCharactersMap);
private:
bool advance();
@@ -44,9 +45,9 @@ private:
void advanceComplexText();
bool currentCharacterStartsSurrogatePair() const;
- void initializeMeasurementWithTextRenderer(RenderSVGInlineText&);
+ void initializeMeasurementWithTextRenderer(RenderSVGInlineText*);
void walkTree(RenderElement&, RenderSVGInlineText* stopAtLeaf, MeasureTextData*);
- void measureTextRenderer(RenderSVGInlineText&, MeasureTextData*);
+ void measureTextRenderer(RenderSVGInlineText*, MeasureTextData*);
RenderSVGInlineText* m_text;
TextRun m_run;
@@ -56,7 +57,7 @@ private:
float m_totalWidth;
// Simple text only.
- std::unique_ptr<WidthIterator> m_simpleWidthIterator;
+ OwnPtr<WidthIterator> m_simpleWidthIterator;
// Complex text only.
SVGTextMetrics m_complexStartToCurrentMetrics;
@@ -64,4 +65,5 @@ private:
} // namespace WebCore
+#endif // ENABLE(SVG)
#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextQuery.cpp b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
index ff3667717..f25dedcad 100644
--- a/Source/WebCore/rendering/svg/SVGTextQuery.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextQuery.cpp
@@ -20,11 +20,11 @@
#include "config.h"
#include "SVGTextQuery.h"
+#if ENABLE(SVG)
#include "FloatConversion.h"
#include "InlineFlowBox.h"
#include "RenderBlockFlow.h"
#include "RenderInline.h"
-#include "RenderSVGText.h"
#include "SVGInlineTextBox.h"
#include "VisiblePosition.h"
@@ -51,12 +51,12 @@ struct SVGTextQuery::Data {
static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer)
{
if (!renderer)
- return nullptr;
+ return 0;
- if (is<RenderBlockFlow>(*renderer)) {
+ if (renderer->isRenderBlockFlow()) {
// If we're given a block element, it has to be a RenderSVGText.
- ASSERT(is<RenderSVGText>(*renderer));
- RenderBlockFlow& renderBlock = downcast<RenderBlockFlow>(*renderer);
+ ASSERT(renderer->isSVGText());
+ RenderBlockFlow& renderBlock = toRenderBlockFlow(*renderer);
// RenderSVGText only ever contains a single line box.
auto flowBox = renderBlock.firstRootBox();
@@ -64,9 +64,9 @@ static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer)
return flowBox;
}
- if (is<RenderInline>(*renderer)) {
+ if (renderer->isRenderInline()) {
// We're given a RenderSVGInline or objects that derive from it (RenderSVGTSpan / RenderSVGTextPath)
- RenderInline& renderInline = downcast<RenderInline>(*renderer);
+ RenderInline& renderInline = toRenderInline(*renderer);
// RenderSVGInline only ever contains a single line box.
InlineFlowBox* flowBox = renderInline.firstLineBox();
@@ -75,7 +75,7 @@ static inline InlineFlowBox* flowBoxForRenderer(RenderObject* renderer)
}
ASSERT_NOT_REACHED();
- return nullptr;
+ return 0;
}
SVGTextQuery::SVGTextQuery(RenderObject* renderer)
@@ -89,17 +89,17 @@ void SVGTextQuery::collectTextBoxesInFlowBox(InlineFlowBox* flowBox)
return;
for (InlineBox* child = flowBox->firstChild(); child; child = child->nextOnLine()) {
- if (is<InlineFlowBox>(*child)) {
+ if (child->isInlineFlowBox()) {
// Skip generated content.
if (!child->renderer().node())
continue;
- collectTextBoxesInFlowBox(downcast<InlineFlowBox>(child));
+ collectTextBoxesInFlowBox(toInlineFlowBox(child));
continue;
}
- if (is<SVGInlineTextBox>(*child))
- m_textBoxes.append(downcast<SVGInlineTextBox>(child));
+ if (child->isSVGInlineTextBox())
+ m_textBoxes.append(toSVGInlineTextBox(child));
}
}
@@ -213,11 +213,15 @@ void SVGTextQuery::modifyStartEndPositionsRespectingLigatures(Data* queryData, i
return;
if (lastPositionOffset != -1 && lastPositionOffset - positionOffset > 1) {
- if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset))
+ if (alterStartPosition && startPosition > lastPositionOffset && startPosition < static_cast<int>(positionOffset)) {
startPosition = lastPositionOffset;
+ alterStartPosition = false;
+ }
- if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset))
+ if (alterEndPosition && endPosition > lastPositionOffset && endPosition < static_cast<int>(positionOffset)) {
endPosition = positionOffset;
+ alterEndPosition = false;
+ }
}
}
@@ -289,7 +293,7 @@ bool SVGTextQuery::subStringLengthCallback(Data* queryData, const SVGTextFragmen
if (!mapStartEndPositionsIntoFragmentCoordinates(queryData, fragment, startPosition, endPosition))
return false;
- SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset + startPosition, endPosition - startPosition);
+ SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset + startPosition, endPosition - startPosition);
data->subStringLength += queryData->isVerticalText ? metrics.height() : metrics.width();
return false;
}
@@ -327,7 +331,7 @@ bool SVGTextQuery::startPositionOfCharacterCallback(Data* queryData, const SVGTe
data->startPosition = FloatPoint(fragment.x, fragment.y);
if (startPosition) {
- SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset, startPosition);
+ SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset, startPosition);
if (queryData->isVerticalText)
data->startPosition.move(0, metrics.height());
else
@@ -375,7 +379,7 @@ bool SVGTextQuery::endPositionOfCharacterCallback(Data* queryData, const SVGText
data->endPosition = FloatPoint(fragment.x, fragment.y);
- SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset, startPosition + 1);
+ SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset, startPosition + 1);
if (queryData->isVerticalText)
data->endPosition.move(0, metrics.height());
else
@@ -462,14 +466,14 @@ static inline void calculateGlyphBoundaries(SVGTextQuery::Data* queryData, const
extent.setLocation(FloatPoint(fragment.x, fragment.y - queryData->textRenderer->scaledFont().fontMetrics().floatAscent() / scalingFactor));
if (startPosition) {
- SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset, startPosition);
+ SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset, startPosition);
if (queryData->isVerticalText)
extent.move(0, metrics.height());
else
extent.move(metrics.width(), 0);
}
- SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(*queryData->textRenderer, fragment.characterOffset + startPosition, 1);
+ SVGTextMetrics metrics = SVGTextMetrics::measureCharacterRange(queryData->textRenderer, fragment.characterOffset + startPosition, 1);
extent.setSize(FloatSize(metrics.width(), metrics.height()));
AffineTransform fragmentTransform;
@@ -547,3 +551,5 @@ int SVGTextQuery::characterNumberAtPosition(const SVGPoint& position) const
}
}
+
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextQuery.h b/Source/WebCore/rendering/svg/SVGTextQuery.h
index 721b2df8e..bf60a6da6 100644
--- a/Source/WebCore/rendering/svg/SVGTextQuery.h
+++ b/Source/WebCore/rendering/svg/SVGTextQuery.h
@@ -20,6 +20,7 @@
#ifndef SVGTextQuery_h
#define SVGTextQuery_h
+#if ENABLE(SVG)
#include "FloatRect.h"
#include "SVGPoint.h"
#include "SVGTextFragment.h"
@@ -72,3 +73,4 @@ private:
}
#endif
+#endif
diff --git a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
index dd3f28557..3b2561af8 100644
--- a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
+++ b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.cpp
@@ -37,22 +37,22 @@
namespace WebCore {
-static inline const SVGFontData* svgFontAndFontFaceElementForFontData(const Font* font, SVGFontFaceElement*& svgFontFaceElement, SVGFontElement*& svgFontElement)
+static inline const SVGFontData* svgFontAndFontFaceElementForFontData(const SimpleFontData* fontData, SVGFontFaceElement*& fontFace, SVGFontElement*& font)
{
- ASSERT(font);
- ASSERT(font->isCustomFont());
- ASSERT(font->isSVGFont());
+ ASSERT(fontData);
+ ASSERT(fontData->isCustomFont());
+ ASSERT(fontData->isSVGFont());
- auto* svgFontData = static_cast<const SVGFontData*>(font->svgData());
+ const SVGFontData* svgFontData = static_cast<const SVGFontData*>(fontData->fontData());
- svgFontFaceElement = svgFontData->svgFontFaceElement();
- ASSERT(svgFontFaceElement);
+ fontFace = svgFontData->svgFontFaceElement();
+ ASSERT(fontFace);
- svgFontElement = svgFontFaceElement->associatedFontElement();
+ font = fontFace->associatedFontElement();
return svgFontData;
}
-float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const FontCascade& font, const TextRun& run, int& charsConsumed, String& glyphName) const
+float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const Font& font, const TextRun& run, int& charsConsumed, String& glyphName) const
{
WidthIterator it(&font, run);
GlyphBuffer glyphBuffer;
@@ -61,21 +61,18 @@ float SVGTextRunRenderingContext::floatWidthUsingSVGFont(const FontCascade& font
return it.runWidthSoFar();
}
-bool SVGTextRunRenderingContext::applySVGKerning(const Font* font, WidthIterator& iterator, GlyphBuffer* glyphBuffer, int from) const
+bool SVGTextRunRenderingContext::applySVGKerning(const SimpleFontData* fontData, WidthIterator& iterator, GlyphBuffer* glyphBuffer, int from) const
{
ASSERT(glyphBuffer);
ASSERT(glyphBuffer->size() > 1);
SVGFontElement* fontElement = 0;
SVGFontFaceElement* fontFaceElement = 0;
- svgFontAndFontFaceElementForFontData(font, fontFaceElement, fontElement);
+ svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
if (!fontElement || !fontFaceElement)
return false;
- if (fontElement->horizontalKerningMapIsEmpty())
- return true;
-
- float scale = scaleEmToUnits(font->platformData().size(), fontFaceElement->unitsPerEm());
+ float scale = scaleEmToUnits(fontData->platformData().size(), fontFaceElement->unitsPerEm());
String lastGlyphName;
String lastUnicodeString;
@@ -104,166 +101,15 @@ bool SVGTextRunRenderingContext::applySVGKerning(const Font* font, WidthIterator
return true;
}
-class SVGGlyphToPathTranslator final : public GlyphToPathTranslator {
-public:
- SVGGlyphToPathTranslator(const TextRun* const, const GlyphBuffer&, const FloatPoint&, const SVGFontData&, SVGFontElement&, const int from, const int numGlyphs, float scale, bool isVerticalText);
-private:
- virtual bool containsMorePaths() override
- {
- return m_index != m_stoppingPoint;
- }
-
- virtual Path path() override;
- virtual std::pair<float, float> extents() override;
- virtual GlyphUnderlineType underlineType() override;
- virtual void advance() override;
- void moveToNextValidGlyph();
- AffineTransform transform();
-
- const TextRun* const m_textRun;
- const GlyphBuffer& m_glyphBuffer;
- const SVGFontData& m_svgFontData;
- FloatPoint m_currentPoint;
- FloatPoint m_glyphOrigin;
- SVGGlyph m_svgGlyph;
- int m_index;
- Glyph m_glyph;
- SVGFontElement& m_fontElement;
- const float m_stoppingPoint;
- const float m_scale;
- const bool m_isVerticalText;
-};
-
-SVGGlyphToPathTranslator::SVGGlyphToPathTranslator(const TextRun* const textRun, const GlyphBuffer& glyphBuffer, const FloatPoint& point, const SVGFontData& svgFontData, SVGFontElement& fontElement, const int from, const int numGlyphs, float scale, bool isVerticalText)
- : m_textRun(textRun)
- , m_glyphBuffer(glyphBuffer)
- , m_svgFontData(svgFontData)
- , m_currentPoint(point)
- , m_glyphOrigin(m_svgFontData.horizontalOriginX() * scale, m_svgFontData.horizontalOriginY() * scale)
- , m_index(from)
- , m_glyph(glyphBuffer.glyphAt(m_index))
- , m_fontElement(fontElement)
- , m_stoppingPoint(numGlyphs + from)
- , m_scale(scale)
- , m_isVerticalText(isVerticalText)
-{
- ASSERT(glyphBuffer.size() > m_index);
- if (m_glyph) {
- m_svgGlyph = m_fontElement.svgGlyphForGlyph(m_glyph);
- ASSERT(!m_svgGlyph.isPartOfLigature);
- ASSERT(m_svgGlyph.tableEntry == m_glyph);
- SVGGlyphElement::inheritUnspecifiedAttributes(m_svgGlyph, &m_svgFontData);
- }
- moveToNextValidGlyph();
-}
-
-AffineTransform SVGGlyphToPathTranslator::transform()
-{
- AffineTransform glyphPathTransform;
- glyphPathTransform.translate(m_currentPoint.x() + m_glyphOrigin.x(), m_currentPoint.y() + m_glyphOrigin.y());
- glyphPathTransform.scale(m_scale, -m_scale);
- return glyphPathTransform;
-}
-
-Path SVGGlyphToPathTranslator::path()
-{
- Path glyphPath = m_svgGlyph.pathData;
- glyphPath.transform(transform());
- return glyphPath;
-}
-
-std::pair<float, float> SVGGlyphToPathTranslator::extents()
-{
- AffineTransform glyphPathTransform = transform();
- FloatPoint beginning = glyphPathTransform.mapPoint(m_currentPoint);
- FloatSize end = glyphPathTransform.mapSize(FloatSize(m_glyphBuffer.advanceAt(m_index)));
- return std::make_pair(beginning.x(), beginning.x() + end.width());
-}
-
-auto SVGGlyphToPathTranslator::underlineType() -> GlyphUnderlineType
-{
- ASSERT(m_textRun);
- return computeUnderlineType(*m_textRun, m_glyphBuffer, m_index);
-}
-
-void SVGGlyphToPathTranslator::moveToNextValidGlyph()
-{
- if (m_glyph && !m_svgGlyph.pathData.isEmpty())
- return;
- advance();
-}
-
-void SVGGlyphToPathTranslator::advance()
-{
- do {
- if (m_glyph) {
- float advance = m_glyphBuffer.advanceAt(m_index).width();
- if (m_isVerticalText)
- m_currentPoint.move(0, advance);
- else
- m_currentPoint.move(advance, 0);
- }
-
- ++m_index;
- if (m_index >= m_stoppingPoint || !m_glyphBuffer.fontAt(m_index)->isSVGFont())
- break;
- m_glyph = m_glyphBuffer.glyphAt(m_index);
- if (!m_glyph)
- continue;
- m_svgGlyph = m_fontElement.svgGlyphForGlyph(m_glyph);
- ASSERT(!m_svgGlyph.isPartOfLigature);
- ASSERT(m_svgGlyph.tableEntry == m_glyph);
- SVGGlyphElement::inheritUnspecifiedAttributes(m_svgGlyph, &m_svgFontData);
- } while ((!m_glyph || m_svgGlyph.pathData.isEmpty()) && m_index < m_stoppingPoint);
-
- if (containsMorePaths() && m_isVerticalText) {
- m_glyphOrigin.setX(m_svgGlyph.verticalOriginX * m_scale);
- m_glyphOrigin.setY(m_svgGlyph.verticalOriginY * m_scale);
- }
-}
-
-class DummyGlyphToPathTranslator final : public GlyphToPathTranslator {
- virtual bool containsMorePaths() override
- {
- return false;
- }
- virtual Path path() override
- {
- return Path();
- }
- virtual std::pair<float, float> extents() override
- {
- return std::make_pair(0.f, 0.f);
- }
- virtual GlyphUnderlineType underlineType() override
- {
- return GlyphUnderlineType::DrawOverGlyph;
- }
- virtual void advance() override
- {
- }
-};
-
-std::unique_ptr<GlyphToPathTranslator> SVGTextRunRenderingContext::createGlyphToPathTranslator(const Font& font, const TextRun* textRun, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
+void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const SimpleFontData* fontData, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
{
- SVGFontElement* fontElement = nullptr;
- SVGFontFaceElement* fontFaceElement = nullptr;
+ SVGFontElement* fontElement = 0;
+ SVGFontFaceElement* fontFaceElement = 0;
- const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(&font, fontFaceElement, fontElement);
+ const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
if (!fontElement || !fontFaceElement)
- return std::make_unique<DummyGlyphToPathTranslator>();
-
- auto& elementRenderer = is<RenderElement>(renderer()) ? downcast<RenderElement>(renderer()) : *renderer().parent();
- RenderStyle& style = elementRenderer.style();
- bool isVerticalText = style.svgStyle().isVerticalWritingMode();
-
- float scale = scaleEmToUnits(font.platformData().size(), fontFaceElement->unitsPerEm());
-
- return std::make_unique<SVGGlyphToPathTranslator>(textRun, glyphBuffer, point, *svgFontData, *fontElement, from, numGlyphs, scale, isVerticalText);
-}
+ return;
-void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const Font* font, const GlyphBuffer& glyphBuffer, int from, int numGlyphs, const FloatPoint& point) const
-{
auto activePaintingResource = this->activePaintingResource();
if (!activePaintingResource) {
// TODO: We're only supporting simple filled HTML text so far.
@@ -272,80 +118,135 @@ void SVGTextRunRenderingContext::drawSVGGlyphs(GraphicsContext* context, const F
activePaintingResource = solidPaintingResource;
}
- auto& elementRenderer = is<RenderElement>(renderer()) ? downcast<RenderElement>(renderer()) : *renderer().parent();
+ auto& elementRenderer = renderer().isRenderElement() ? toRenderElement(renderer()) : *renderer().parent();
RenderStyle& style = elementRenderer.style();
+ bool isVerticalText = style.svgStyle().isVerticalWritingMode();
+ float scale = scaleEmToUnits(fontData->platformData().size(), fontFaceElement->unitsPerEm());
ASSERT(activePaintingResource);
+ FloatPoint glyphOrigin;
+ glyphOrigin.setX(svgFontData->horizontalOriginX() * scale);
+ glyphOrigin.setY(svgFontData->horizontalOriginY() * scale);
+
+ FloatPoint currentPoint = point;
RenderSVGResourceMode resourceMode = context->textDrawingMode() == TextModeStroke ? ApplyToStrokeMode : ApplyToFillMode;
- for (auto translator = createGlyphToPathTranslator(*font, nullptr, glyphBuffer, from, numGlyphs, point); translator->containsMorePaths(); translator->advance()) {
- Path glyphPath = translator->path();
+ for (int i = 0; i < numGlyphs; ++i) {
+ Glyph glyph = glyphBuffer.glyphAt(from + i);
+ if (!glyph)
+ continue;
+
+ float advance = glyphBuffer.advanceAt(from + i).width();
+ SVGGlyph svgGlyph = fontElement->svgGlyphForGlyph(glyph);
+ ASSERT(!svgGlyph.isPartOfLigature);
+ ASSERT(svgGlyph.tableEntry == glyph);
+
+ SVGGlyphElement::inheritUnspecifiedAttributes(svgGlyph, svgFontData);
+
+ // FIXME: Support arbitary SVG content as glyph (currently limited to <glyph d="..."> situations).
+ if (svgGlyph.pathData.isEmpty()) {
+ if (isVerticalText)
+ currentPoint.move(0, advance);
+ else
+ currentPoint.move(advance, 0);
+ continue;
+ }
+
+ if (isVerticalText) {
+ glyphOrigin.setX(svgGlyph.verticalOriginX * scale);
+ glyphOrigin.setY(svgGlyph.verticalOriginY * scale);
+ }
+
+ AffineTransform glyphPathTransform;
+ glyphPathTransform.translate(currentPoint.x() + glyphOrigin.x(), currentPoint.y() + glyphOrigin.y());
+ glyphPathTransform.scale(scale, -scale);
+
+ Path glyphPath = svgGlyph.pathData;
+ glyphPath.transform(glyphPathTransform);
+
if (activePaintingResource->applyResource(elementRenderer, style, context, resourceMode)) {
float strokeThickness = context->strokeThickness();
- if (is<RenderSVGInlineText>(renderer()))
- context->setStrokeThickness(strokeThickness * downcast<RenderSVGInlineText>(renderer()).scalingFactor());
- activePaintingResource->postApplyResource(elementRenderer, context, resourceMode, &glyphPath, nullptr);
+ if (renderer().isSVGInlineText())
+ context->setStrokeThickness(strokeThickness * toRenderSVGInlineText(renderer()).scalingFactor());
+ activePaintingResource->postApplyResource(elementRenderer, context, resourceMode, &glyphPath, 0);
context->setStrokeThickness(strokeThickness);
}
+
+ if (isVerticalText)
+ currentPoint.move(0, advance);
+ else
+ currentPoint.move(advance, 0);
}
}
-static GlyphData missingGlyphForFont(const FontCascade& font)
+GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const Font& font, WidthIterator& iterator, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength)
{
- const Font& primaryFont = font.primaryFont();
- if (!primaryFont.isSVGFont())
- return GlyphData();
- SVGFontElement* fontElement;
- SVGFontFaceElement* fontFaceElement;
- svgFontAndFontFaceElementForFontData(&primaryFont, fontFaceElement, fontElement);
- return GlyphData(fontElement->missingGlyph(), &primaryFont);
-}
+ const SimpleFontData* primaryFont = font.primaryFont();
+ ASSERT(primaryFont);
-GlyphData SVGTextRunRenderingContext::glyphDataForCharacter(const FontCascade& font, WidthIterator& iterator, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength, String& normalizedSpacesStringCache)
-{
- GlyphData glyphData = font.glyphDataForCharacter(character, mirror, AutoVariant);
- if (!glyphData.glyph)
- return missingGlyphForFont(font);
+ std::pair<GlyphData, GlyphPage*> pair = font.glyphDataAndPageForCharacter(character, mirror, AutoVariant);
+ GlyphData glyphData = pair.first;
- ASSERT(glyphData.font);
+ // Check if we have the missing glyph data, in which case we can just return.
+ GlyphData missingGlyphData = primaryFont->missingGlyphData();
+ if (glyphData.glyph == missingGlyphData.glyph && glyphData.fontData == missingGlyphData.fontData) {
+ ASSERT(glyphData.fontData);
+ return glyphData;
+ }
+
+ // Save data fromt he font fallback list because we may modify it later. Do this before the
+ // potential change to glyphData.fontData below.
+ FontGlyphs* glyph = font.glyphs();
+ ASSERT(glyph);
+ FontGlyphs::GlyphPagesStateSaver glyphPagesSaver(*glyph);
// Characters enclosed by an <altGlyph> element, may not be registered in the GlyphPage.
- if (!glyphData.font->isSVGFont()) {
- auto& elementRenderer = is<RenderElement>(renderer()) ? downcast<RenderElement>(renderer()) : *renderer().parent();
+ const SimpleFontData* originalFontData = glyphData.fontData;
+ if (glyphData.fontData && !glyphData.fontData->isSVGFont()) {
+ auto& elementRenderer = renderer().isRenderElement() ? toRenderElement(renderer()) : *renderer().parent();
if (Element* parentRendererElement = elementRenderer.element()) {
- if (is<SVGAltGlyphElement>(*parentRendererElement))
- glyphData.font = &font.primaryFont();
+ if (parentRendererElement->hasTagName(SVGNames::altGlyphTag))
+ glyphData.fontData = primaryFont;
}
}
- if (!glyphData.font->isSVGFont())
- return glyphData;
+ const SimpleFontData* fontData = glyphData.fontData;
+ if (fontData) {
+ if (!fontData->isSVGFont())
+ return glyphData;
- SVGFontElement* fontElement = nullptr;
- SVGFontFaceElement* fontFaceElement = nullptr;
- const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(glyphData.font, fontFaceElement, fontElement);
- if (!svgFontData)
- return glyphData;
+ SVGFontElement* fontElement = 0;
+ SVGFontFaceElement* fontFaceElement = 0;
- // If we got here, we're dealing with a glyph defined in a SVG Font.
- // The returned glyph by glyphDataForCharacter() is a glyph stored in the SVG Font glyph table.
- // This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its
- // arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that.
- if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength, normalizedSpacesStringCache))
- return glyphData;
+ const SVGFontData* svgFontData = svgFontAndFontFaceElementForFontData(fontData, fontFaceElement, fontElement);
+ if (!fontElement || !fontFaceElement)
+ return glyphData;
+
+ // If we got here, we're dealing with a glyph defined in a SVG Font.
+ // The returned glyph by glyphDataAndPageForCharacter() is a glyph stored in the SVG Font glyph table.
+ // This doesn't necessarily mean the glyph is suitable for rendering/measuring in this context, its
+ // arabic-form/orientation/... may not match, we have to apply SVG Glyph selection to discover that.
+ if (svgFontData->applySVGGlyphSelection(iterator, glyphData, mirror, currentCharacter, advanceLength))
+ return glyphData;
+ }
+
+ GlyphPage* page = pair.second;
+ ASSERT(page);
- GlyphData missingGlyphData = missingGlyphForFont(font);
- if (missingGlyphData.glyph)
- return missingGlyphData;
+ // No suitable glyph found that is compatible with the requirments (same language, arabic-form, orientation etc.)
+ // Even though our GlyphPage contains an entry for eg. glyph "a", it's not compatible. So we have to temporarily
+ // remove the glyph data information from the GlyphPage, and retry the lookup, which handles font fallbacks correctly.
+ page->setGlyphDataForCharacter(character, 0, 0);
- // SVG font context sensitive selection failed and there is no defined missing glyph. Drop down to a default font.
- // The behavior does not seem to be specified. For simplicity we don't try to resolve font fallbacks context-sensitively.
- FontDescription fallbackDescription = font.fontDescription();
- fallbackDescription.setFamilies(Vector<AtomicString> { sansSerifFamily });
- FontCascade fallbackFont(fallbackDescription, font.letterSpacing(), font.wordSpacing());
- fallbackFont.update(font.fontSelector());
+ // Assure that the font fallback glyph selection worked, aka. the fallbackGlyphData font data is not the same as before.
+ GlyphData fallbackGlyphData = font.glyphDataForCharacter(character, mirror);
+ ASSERT(fallbackGlyphData.fontData != fontData);
- return fallbackFont.glyphDataForCharacter(character, mirror, AutoVariant);
+ // Restore original state of the SVG Font glyph table and the current font fallback list,
+ // to assure the next lookup of the same glyph won't immediately return the fallback glyph.
+ page->setGlyphDataForCharacter(character, glyphData.glyph, originalFontData);
+ ASSERT(fallbackGlyphData.fontData);
+ return fallbackGlyphData;
}
}
diff --git a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h
index 501b9c8ff..e1270c19e 100644
--- a/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h
+++ b/Source/WebCore/rendering/svg/SVGTextRunRenderingContext.h
@@ -21,7 +21,7 @@
#ifndef SVGTextRunRenderingContext_h
#define SVGTextRunRenderingContext_h
-#include "FontCascade.h"
+#include "Font.h"
#include "TextRun.h"
namespace WebCore {
@@ -31,7 +31,7 @@ class RenderSVGResource;
class SVGTextRunRenderingContext final : public TextRun::RenderingContext {
public:
- static Ref<SVGTextRunRenderingContext> create(RenderObject& renderer)
+ static PassRef<SVGTextRunRenderingContext> create(RenderObject& renderer)
{
return adoptRef(*new SVGTextRunRenderingContext(renderer));
}
@@ -42,10 +42,10 @@ public:
RenderSVGResource* activePaintingResource() const { return m_activePaintingResource; }
void setActivePaintingResource(RenderSVGResource* object) { m_activePaintingResource = object; }
- virtual GlyphData glyphDataForCharacter(const FontCascade&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength, String& normalizedSpacesStringCache) override;
- virtual void drawSVGGlyphs(GraphicsContext*, const Font*, const GlyphBuffer&, int from, int to, const FloatPoint&) const override;
- virtual float floatWidthUsingSVGFont(const FontCascade&, const TextRun&, int& charsConsumed, String& glyphName) const override;
- virtual bool applySVGKerning(const Font*, WidthIterator&, GlyphBuffer*, int from) const override;
+ virtual GlyphData glyphDataForCharacter(const Font&, WidthIterator&, UChar32 character, bool mirror, int currentCharacter, unsigned& advanceLength) override;
+ virtual void drawSVGGlyphs(GraphicsContext*, const SimpleFontData*, const GlyphBuffer&, int from, int to, const FloatPoint&) const override;
+ virtual float floatWidthUsingSVGFont(const Font&, const TextRun&, int& charsConsumed, String& glyphName) const override;
+ virtual bool applySVGKerning(const SimpleFontData*, WidthIterator&, GlyphBuffer*, int from) const override;
#endif
private:
@@ -59,10 +59,6 @@ private:
virtual ~SVGTextRunRenderingContext() { }
-#if ENABLE(SVG_FONTS)
- virtual std::unique_ptr<GlyphToPathTranslator> createGlyphToPathTranslator(const Font&, const TextRun*, const GlyphBuffer&, int from, int numGlyphs, const FloatPoint&) const override;
-#endif
-
RenderObject& m_renderer;
#if ENABLE(SVG_FONTS)