Replace PassRef with Ref/Ref&& across the board.
[WebKit-https.git] / Source / WebCore / rendering / style / SVGRenderStyle.cpp
1 /*
2     Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3                   2004, 2005, 2010 Rob Buis <buis@kde.org>
4     Copyright (C) Research In Motion Limited 2010. All rights reserved.
5
6     Based on khtml code by:
7     Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
8     Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
9     Copyright (C) 2002-2003 Dirk Mueller (mueller@kde.org)
10     Copyright (C) 2002 Apple Inc.
11
12     This library is free software; you can redistribute it and/or
13     modify it under the terms of the GNU Library General Public
14     License as published by the Free Software Foundation; either
15     version 2 of the License, or (at your option) any later version.
16
17     This library is distributed in the hope that it will be useful,
18     but WITHOUT ANY WARRANTY; without even the implied warranty of
19     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20     Library General Public License for more details.
21
22     You should have received a copy of the GNU Library General Public License
23     along with this library; see the file COPYING.LIB.  If not, write to
24     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
25     Boston, MA 02110-1301, USA.
26 */
27
28 #include "config.h"
29 #include "SVGRenderStyle.h"
30
31 #include "CSSPrimitiveValue.h"
32 #include "CSSValueList.h"
33 #include "IntRect.h"
34 #include "NodeRenderStyle.h"
35 #include "SVGElement.h"
36 #include <wtf/NeverDestroyed.h>
37
38 namespace WebCore {
39
40 static const SVGRenderStyle& defaultSVGStyle()
41 {
42     static NeverDestroyed<DataRef<SVGRenderStyle>> style(SVGRenderStyle::createDefaultStyle());
43     return *style.get().get();
44 }
45
46 Ref<SVGRenderStyle> SVGRenderStyle::createDefaultStyle()
47 {
48     return adoptRef(*new SVGRenderStyle(CreateDefault));
49 }
50
51 SVGRenderStyle::SVGRenderStyle()
52     : fill(defaultSVGStyle().fill)
53     , stroke(defaultSVGStyle().stroke)
54     , text(defaultSVGStyle().text)
55     , inheritedResources(defaultSVGStyle().inheritedResources)
56     , stops(defaultSVGStyle().stops)
57     , misc(defaultSVGStyle().misc)
58     , shadowSVG(defaultSVGStyle().shadowSVG)
59     , layout(defaultSVGStyle().layout)
60     , resources(defaultSVGStyle().resources)
61 {
62     setBitDefaults();
63 }
64
65 SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
66     : fill(StyleFillData::create())
67     , stroke(StyleStrokeData::create())
68     , text(StyleTextData::create())
69     , inheritedResources(StyleInheritedResourceData::create())
70     , stops(StyleStopData::create())
71     , misc(StyleMiscData::create())
72     , shadowSVG(StyleShadowSVGData::create())
73     , layout(StyleLayoutData::create())
74     , resources(StyleResourceData::create())
75 {
76     setBitDefaults();
77 }
78
79 inline SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
80     : RefCounted<SVGRenderStyle>()
81     , svg_inherited_flags(other.svg_inherited_flags)
82     , svg_noninherited_flags(other.svg_noninherited_flags)
83     , fill(other.fill)
84     , stroke(other.stroke)
85     , text(other.text)
86     , inheritedResources(other.inheritedResources)
87     , stops(other.stops)
88     , misc(other.misc)
89     , shadowSVG(other.shadowSVG)
90     , layout(other.layout)
91     , resources(other.resources)
92 {
93 }
94
95 Ref<SVGRenderStyle> SVGRenderStyle::copy() const
96 {
97     return adoptRef(*new SVGRenderStyle(*this));
98 }
99
100 SVGRenderStyle::~SVGRenderStyle()
101 {
102 }
103
104 bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const
105 {
106     return fill == other.fill
107         && stroke == other.stroke
108         && text == other.text
109         && stops == other.stops
110         && misc == other.misc
111         && shadowSVG == other.shadowSVG
112         && layout == other.layout
113         && inheritedResources == other.inheritedResources
114         && resources == other.resources
115         && svg_inherited_flags == other.svg_inherited_flags
116         && svg_noninherited_flags == other.svg_noninherited_flags;
117 }
118
119 bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const
120 {
121     return fill != other->fill
122         || stroke != other->stroke
123         || text != other->text
124         || inheritedResources != other->inheritedResources
125         || svg_inherited_flags != other->svg_inherited_flags;
126 }
127
128 void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
129 {
130     if (!svgInheritParent)
131         return;
132
133     fill = svgInheritParent->fill;
134     stroke = svgInheritParent->stroke;
135     text = svgInheritParent->text;
136     inheritedResources = svgInheritParent->inheritedResources;
137
138     svg_inherited_flags = svgInheritParent->svg_inherited_flags;
139 }
140
141 void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other)
142 {
143     svg_noninherited_flags = other->svg_noninherited_flags;
144     stops = other->stops;
145     misc = other->misc;
146     shadowSVG = other->shadowSVG;
147     layout = other->layout;
148     resources = other->resources;
149 }
150
151 Vector<PaintType> SVGRenderStyle::paintTypesForPaintOrder() const
152 {
153     Vector<PaintType, 3> paintOrder;
154     switch (this->paintOrder()) {
155     case PaintOrderNormal:
156         FALLTHROUGH;
157     case PaintOrderFill:
158         paintOrder.append(PaintTypeFill);
159         paintOrder.append(PaintTypeStroke);
160         paintOrder.append(PaintTypeMarkers);
161         break;
162     case PaintOrderFillMarkers:
163         paintOrder.append(PaintTypeFill);
164         paintOrder.append(PaintTypeMarkers);
165         paintOrder.append(PaintTypeStroke);
166         break;
167     case PaintOrderStroke:
168         paintOrder.append(PaintTypeStroke);
169         paintOrder.append(PaintTypeFill);
170         paintOrder.append(PaintTypeMarkers);
171         break;
172     case PaintOrderStrokeMarkers:
173         paintOrder.append(PaintTypeStroke);
174         paintOrder.append(PaintTypeMarkers);
175         paintOrder.append(PaintTypeFill);
176         break;
177     case PaintOrderMarkers:
178         paintOrder.append(PaintTypeMarkers);
179         paintOrder.append(PaintTypeFill);
180         paintOrder.append(PaintTypeStroke);
181         break;
182     case PaintOrderMarkersStroke:
183         paintOrder.append(PaintTypeMarkers);
184         paintOrder.append(PaintTypeStroke);
185         paintOrder.append(PaintTypeFill);
186         break;
187     };
188     return paintOrder;
189 }
190
191 StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
192 {
193     // NOTE: All comparisions that may return StyleDifferenceLayout have to go before those who return StyleDifferenceRepaint
194
195     // If kerning changes, we need a relayout, to force SVGCharacterData to be recalculated in the SVGRootInlineBox.
196     if (text != other->text)
197         return StyleDifferenceLayout;
198
199     // If resources change, we need a relayout, as the presence of resources influences the repaint rect.
200     if (resources != other->resources)
201         return StyleDifferenceLayout;
202
203     // If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath.
204     if (inheritedResources != other->inheritedResources)
205         return StyleDifferenceLayout;
206
207     // All text related properties influence layout.
208     if (svg_inherited_flags._textAnchor != other->svg_inherited_flags._textAnchor
209         || svg_inherited_flags._writingMode != other->svg_inherited_flags._writingMode
210         || svg_inherited_flags._glyphOrientationHorizontal != other->svg_inherited_flags._glyphOrientationHorizontal
211         || svg_inherited_flags._glyphOrientationVertical != other->svg_inherited_flags._glyphOrientationVertical
212         || svg_noninherited_flags.f._alignmentBaseline != other->svg_noninherited_flags.f._alignmentBaseline
213         || svg_noninherited_flags.f._dominantBaseline != other->svg_noninherited_flags.f._dominantBaseline
214         || svg_noninherited_flags.f._baselineShift != other->svg_noninherited_flags.f._baselineShift)
215         return StyleDifferenceLayout;
216
217     // Text related properties influence layout.
218     bool miscNotEqual = misc != other->misc;
219     if (miscNotEqual && misc->baselineShiftValue != other->misc->baselineShiftValue)
220         return StyleDifferenceLayout;
221
222     // These properties affect the cached stroke bounding box rects.
223     if (svg_inherited_flags._capStyle != other->svg_inherited_flags._capStyle
224         || svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle)
225         return StyleDifferenceLayout;
226
227     // Shadow changes require relayouts, as they affect the repaint rects.
228     if (shadowSVG != other->shadowSVG)
229         return StyleDifferenceLayout;
230
231     // The x or y properties require relayout.
232     if (layout != other->layout)
233         return StyleDifferenceLayout; 
234
235     // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
236     if (stroke != other->stroke) {
237         if (stroke->width != other->stroke->width
238             || stroke->paintType != other->stroke->paintType
239             || stroke->paintColor != other->stroke->paintColor
240             || stroke->paintUri != other->stroke->paintUri
241             || stroke->miterLimit != other->stroke->miterLimit
242             || stroke->dashArray != other->stroke->dashArray
243             || stroke->dashOffset != other->stroke->dashOffset
244             || stroke->visitedLinkPaintColor != other->stroke->visitedLinkPaintColor
245             || stroke->visitedLinkPaintUri != other->stroke->visitedLinkPaintUri
246             || stroke->visitedLinkPaintType != other->stroke->visitedLinkPaintType)
247             return StyleDifferenceLayout;
248
249         // Only the stroke-opacity case remains, where we only need a repaint.
250         ASSERT(stroke->opacity != other->stroke->opacity);
251         return StyleDifferenceRepaint;
252     }
253
254     // vector-effect changes require a re-layout.
255     if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect)
256         return StyleDifferenceLayout;
257
258     // NOTE: All comparisions below may only return StyleDifferenceRepaint
259
260     // Painting related properties only need repaints. 
261     if (miscNotEqual) {
262         if (misc->floodColor != other->misc->floodColor
263             || misc->floodOpacity != other->misc->floodOpacity
264             || misc->lightingColor != other->misc->lightingColor)
265             return StyleDifferenceRepaint;
266     }
267
268     // If fill changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains.
269     if (fill->paintType != other->fill->paintType || fill->paintColor != other->fill->paintColor
270         || fill->paintUri != other->fill->paintUri || fill->opacity != other->fill->opacity)
271         return StyleDifferenceRepaint;
272
273     // If gradient stops change, we just need to repaint. Style updates are already handled through RenderSVGGradientSTop.
274     if (stops != other->stops)
275         return StyleDifferenceRepaint;
276
277     // Changes of these flags only cause repaints.
278     if (svg_inherited_flags._colorRendering != other->svg_inherited_flags._colorRendering
279         || svg_inherited_flags._shapeRendering != other->svg_inherited_flags._shapeRendering
280         || svg_inherited_flags._clipRule != other->svg_inherited_flags._clipRule
281         || svg_inherited_flags._fillRule != other->svg_inherited_flags._fillRule
282         || svg_inherited_flags._colorInterpolation != other->svg_inherited_flags._colorInterpolation
283         || svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._colorInterpolationFilters)
284         return StyleDifferenceRepaint;
285
286     if (svg_noninherited_flags.f.bufferedRendering != other->svg_noninherited_flags.f.bufferedRendering)
287         return StyleDifferenceRepaint;
288
289     if (svg_noninherited_flags.f.maskType != other->svg_noninherited_flags.f.maskType)
290         return StyleDifferenceRepaint;
291
292     return StyleDifferenceEqual;
293 }
294
295 }