Use "= default" to denote default constructor or destructor
[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();
44 }
45
46 Ref<SVGRenderStyle> SVGRenderStyle::createDefaultStyle()
47 {
48     return adoptRef(*new SVGRenderStyle(CreateDefault));
49 }
50
51 SVGRenderStyle::SVGRenderStyle()
52     : m_fillData(defaultSVGStyle().m_fillData)
53     , m_strokeData(defaultSVGStyle().m_strokeData)
54     , m_textData(defaultSVGStyle().m_textData)
55     , m_inheritedResourceData(defaultSVGStyle().m_inheritedResourceData)
56     , m_stopData(defaultSVGStyle().m_stopData)
57     , m_miscData(defaultSVGStyle().m_miscData)
58     , m_shadowData(defaultSVGStyle().m_shadowData)
59     , m_layoutData(defaultSVGStyle().m_layoutData)
60     , m_nonInheritedResourceData(defaultSVGStyle().m_nonInheritedResourceData)
61 {
62     setBitDefaults();
63 }
64
65 SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
66     : m_fillData(StyleFillData::create())
67     , m_strokeData(StyleStrokeData::create())
68     , m_textData(StyleTextData::create())
69     , m_inheritedResourceData(StyleInheritedResourceData::create())
70     , m_stopData(StyleStopData::create())
71     , m_miscData(StyleMiscData::create())
72     , m_shadowData(StyleShadowSVGData::create())
73     , m_layoutData(StyleLayoutData::create())
74     , m_nonInheritedResourceData(StyleResourceData::create())
75 {
76     setBitDefaults();
77 }
78
79 inline SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
80     : RefCounted<SVGRenderStyle>()
81     , m_inheritedFlags(other.m_inheritedFlags)
82     , m_nonInheritedFlags(other.m_nonInheritedFlags)
83     , m_fillData(other.m_fillData)
84     , m_strokeData(other.m_strokeData)
85     , m_textData(other.m_textData)
86     , m_inheritedResourceData(other.m_inheritedResourceData)
87     , m_stopData(other.m_stopData)
88     , m_miscData(other.m_miscData)
89     , m_shadowData(other.m_shadowData)
90     , m_layoutData(other.m_layoutData)
91     , m_nonInheritedResourceData(other.m_nonInheritedResourceData)
92 {
93 }
94
95 Ref<SVGRenderStyle> SVGRenderStyle::copy() const
96 {
97     return adoptRef(*new SVGRenderStyle(*this));
98 }
99
100 SVGRenderStyle::~SVGRenderStyle() = default;
101
102 bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const
103 {
104     return m_fillData == other.m_fillData
105         && m_strokeData == other.m_strokeData
106         && m_textData == other.m_textData
107         && m_stopData == other.m_stopData
108         && m_miscData == other.m_miscData
109         && m_shadowData == other.m_shadowData
110         && m_layoutData == other.m_layoutData
111         && m_inheritedResourceData == other.m_inheritedResourceData
112         && m_nonInheritedResourceData == other.m_nonInheritedResourceData
113         && m_inheritedFlags == other.m_inheritedFlags
114         && m_nonInheritedFlags == other.m_nonInheritedFlags;
115 }
116
117 bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle& other) const
118 {
119     return m_fillData != other.m_fillData
120         || m_strokeData != other.m_strokeData
121         || m_textData != other.m_textData
122         || m_inheritedResourceData != other.m_inheritedResourceData
123         || m_inheritedFlags != other.m_inheritedFlags;
124 }
125
126 void SVGRenderStyle::inheritFrom(const SVGRenderStyle& other)
127 {
128     m_fillData = other.m_fillData;
129     m_strokeData = other.m_strokeData;
130     m_textData = other.m_textData;
131     m_inheritedResourceData = other.m_inheritedResourceData;
132
133     m_inheritedFlags = other.m_inheritedFlags;
134 }
135
136 void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle& other)
137 {
138     m_nonInheritedFlags = other.m_nonInheritedFlags;
139     m_stopData = other.m_stopData;
140     m_miscData = other.m_miscData;
141     m_shadowData = other.m_shadowData;
142     m_layoutData = other.m_layoutData;
143     m_nonInheritedResourceData = other.m_nonInheritedResourceData;
144 }
145
146 StyleDifference SVGRenderStyle::diff(const SVGRenderStyle& other) const
147 {
148     // NOTE: All comparisions that may return StyleDifferenceLayout have to go before those who return StyleDifferenceRepaint
149
150     // If kerning changes, we need a relayout, to force SVGCharacterData to be recalculated in the SVGRootInlineBox.
151     if (m_textData != other.m_textData)
152         return StyleDifferenceLayout;
153
154     // If resources change, we need a relayout, as the presence of resources influences the repaint rect.
155     if (m_nonInheritedResourceData != other.m_nonInheritedResourceData)
156         return StyleDifferenceLayout;
157
158     // If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath.
159     if (m_inheritedResourceData != other.m_inheritedResourceData)
160         return StyleDifferenceLayout;
161
162     // All text related properties influence layout.
163     if (m_inheritedFlags.textAnchor != other.m_inheritedFlags.textAnchor
164         || m_inheritedFlags.glyphOrientationHorizontal != other.m_inheritedFlags.glyphOrientationHorizontal
165         || m_inheritedFlags.glyphOrientationVertical != other.m_inheritedFlags.glyphOrientationVertical
166         || m_nonInheritedFlags.flagBits.alignmentBaseline != other.m_nonInheritedFlags.flagBits.alignmentBaseline
167         || m_nonInheritedFlags.flagBits.dominantBaseline != other.m_nonInheritedFlags.flagBits.dominantBaseline
168         || m_nonInheritedFlags.flagBits.baselineShift != other.m_nonInheritedFlags.flagBits.baselineShift)
169         return StyleDifferenceLayout;
170
171     // Text related properties influence layout.
172     bool miscNotEqual = m_miscData != other.m_miscData;
173     if (miscNotEqual && m_miscData->baselineShiftValue != other.m_miscData->baselineShiftValue)
174         return StyleDifferenceLayout;
175
176     // Shadow changes require relayouts, as they affect the repaint rects.
177     if (m_shadowData != other.m_shadowData)
178         return StyleDifferenceLayout;
179
180     // The x or y properties require relayout.
181     if (m_layoutData != other.m_layoutData)
182         return StyleDifferenceLayout; 
183
184     // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
185     if (m_strokeData != other.m_strokeData) {
186         if (m_strokeData->paintType != other.m_strokeData->paintType
187             || m_strokeData->paintColor != other.m_strokeData->paintColor
188             || m_strokeData->paintUri != other.m_strokeData->paintUri
189             || m_strokeData->dashArray != other.m_strokeData->dashArray
190             || m_strokeData->dashOffset != other.m_strokeData->dashOffset
191             || m_strokeData->visitedLinkPaintColor != other.m_strokeData->visitedLinkPaintColor
192             || m_strokeData->visitedLinkPaintUri != other.m_strokeData->visitedLinkPaintUri
193             || m_strokeData->visitedLinkPaintType != other.m_strokeData->visitedLinkPaintType)
194             return StyleDifferenceLayout;
195
196         // Only the stroke-opacity case remains, where we only need a repaint.
197         ASSERT(m_strokeData->opacity != other.m_strokeData->opacity);
198         return StyleDifferenceRepaint;
199     }
200
201     // vector-effect changes require a re-layout.
202     if (m_nonInheritedFlags.flagBits.vectorEffect != other.m_nonInheritedFlags.flagBits.vectorEffect)
203         return StyleDifferenceLayout;
204
205     // NOTE: All comparisions below may only return StyleDifferenceRepaint
206
207     // Painting related properties only need repaints. 
208     if (miscNotEqual) {
209         if (m_miscData->floodColor != other.m_miscData->floodColor
210             || m_miscData->floodOpacity != other.m_miscData->floodOpacity
211             || m_miscData->lightingColor != other.m_miscData->lightingColor)
212             return StyleDifferenceRepaint;
213     }
214
215     // If fill data changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains.
216     if (m_fillData->paintType != other.m_fillData->paintType || m_fillData->paintColor != other.m_fillData->paintColor
217         || m_fillData->paintUri != other.m_fillData->paintUri || m_fillData->opacity != other.m_fillData->opacity)
218         return StyleDifferenceRepaint;
219
220     // If gradient stops change, we just need to repaint. Style updates are already handled through RenderSVGGradientSTop.
221     if (m_stopData != other.m_stopData)
222         return StyleDifferenceRepaint;
223
224     // Changes of these flags only cause repaints.
225     if (m_inheritedFlags.colorRendering != other.m_inheritedFlags.colorRendering
226         || m_inheritedFlags.shapeRendering != other.m_inheritedFlags.shapeRendering
227         || m_inheritedFlags.clipRule != other.m_inheritedFlags.clipRule
228         || m_inheritedFlags.fillRule != other.m_inheritedFlags.fillRule
229         || m_inheritedFlags.colorInterpolation != other.m_inheritedFlags.colorInterpolation
230         || m_inheritedFlags.colorInterpolationFilters != other.m_inheritedFlags.colorInterpolationFilters)
231         return StyleDifferenceRepaint;
232
233     if (m_nonInheritedFlags.flagBits.bufferedRendering != other.m_nonInheritedFlags.flagBits.bufferedRendering)
234         return StyleDifferenceRepaint;
235
236     if (m_nonInheritedFlags.flagBits.maskType != other.m_nonInheritedFlags.flagBits.maskType)
237         return StyleDifferenceRepaint;
238
239     return StyleDifferenceEqual;
240 }
241
242 }