1/*
2 * Copyright (C) 2006 Oliver Hunt <ojh16@student.canterbury.ac.nz>
3 * Copyright (C) 2006 Apple Inc. All rights reserved.
4 * Copyright (C) Research In Motion Limited 2010. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22#include "config.h"
23#include "RenderSVGInline.h"
24
25#include "RenderSVGInlineText.h"
26#include "RenderSVGResource.h"
27#include "RenderSVGText.h"
28#include "SVGInlineFlowBox.h"
29#include "SVGResourcesCache.h"
30#include <wtf/IsoMallocInlines.h>
31
32namespace WebCore {
33
34WTF_MAKE_ISO_ALLOCATED_IMPL(RenderSVGInline);
35
36RenderSVGInline::RenderSVGInline(SVGGraphicsElement& element, RenderStyle&& style)
37 : RenderInline(element, WTFMove(style))
38{
39 setAlwaysCreateLineBoxes();
40}
41
42std::unique_ptr<InlineFlowBox> RenderSVGInline::createInlineFlowBox()
43{
44 auto box = std::make_unique<SVGInlineFlowBox>(*this);
45 box->setHasVirtualLogicalHeight();
46 return box;
47}
48
49FloatRect RenderSVGInline::objectBoundingBox() const
50{
51 if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
52 return textAncestor->objectBoundingBox();
53
54 return FloatRect();
55}
56
57FloatRect RenderSVGInline::strokeBoundingBox() const
58{
59 if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
60 return textAncestor->strokeBoundingBox();
61
62 return FloatRect();
63}
64
65FloatRect RenderSVGInline::repaintRectInLocalCoordinates() const
66{
67 if (auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this))
68 return textAncestor->repaintRectInLocalCoordinates();
69
70 return FloatRect();
71}
72
73LayoutRect RenderSVGInline::clippedOverflowRectForRepaint(const RenderLayerModelObject* repaintContainer) const
74{
75 return SVGRenderSupport::clippedOverflowRectForRepaint(*this, repaintContainer);
76}
77
78Optional<FloatRect> RenderSVGInline::computeFloatVisibleRectInContainer(const FloatRect& rect, const RenderLayerModelObject* container, VisibleRectContext context) const
79{
80 return SVGRenderSupport::computeFloatVisibleRectInContainer(*this, rect, container, context);
81}
82
83void RenderSVGInline::mapLocalToContainer(const RenderLayerModelObject* repaintContainer, TransformState& transformState, MapCoordinatesFlags, bool* wasFixed) const
84{
85 SVGRenderSupport::mapLocalToContainer(*this, repaintContainer, transformState, wasFixed);
86}
87
88const RenderObject* RenderSVGInline::pushMappingToContainer(const RenderLayerModelObject* ancestorToStopAt, RenderGeometryMap& geometryMap) const
89{
90 return SVGRenderSupport::pushMappingToContainer(*this, ancestorToStopAt, geometryMap);
91}
92
93void RenderSVGInline::absoluteQuads(Vector<FloatQuad>& quads, bool* wasFixed) const
94{
95 auto* textAncestor = RenderSVGText::locateRenderSVGTextAncestor(*this);
96 if (!textAncestor)
97 return;
98
99 FloatRect textBoundingBox = textAncestor->strokeBoundingBox();
100 for (InlineFlowBox* box = firstLineBox(); box; box = box->nextLineBox())
101 quads.append(localToAbsoluteQuad(FloatRect(textBoundingBox.x() + box->x(), textBoundingBox.y() + box->y(), box->logicalWidth(), box->logicalHeight()), UseTransforms, wasFixed));
102}
103
104void RenderSVGInline::willBeDestroyed()
105{
106 SVGResourcesCache::clientDestroyed(*this);
107 RenderInline::willBeDestroyed();
108}
109
110void RenderSVGInline::styleDidChange(StyleDifference diff, const RenderStyle* oldStyle)
111{
112 if (diff == StyleDifference::Layout)
113 setNeedsBoundariesUpdate();
114 RenderInline::styleDidChange(diff, oldStyle);
115 SVGResourcesCache::clientStyleChanged(*this, diff, style());
116}
117
118void RenderSVGInline::updateFromStyle()
119{
120 RenderInline::updateFromStyle();
121
122 // SVG text layout code expects us to be an inline-level element.
123 setInline(true);
124}
125
126}
127