Upstream version 9.38.198.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / 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 Computer, 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
30 #include "core/rendering/style/SVGRenderStyle.h"
31
32 namespace blink {
33
34 SVGRenderStyle::SVGRenderStyle()
35 {
36     static SVGRenderStyle* defaultStyle = new SVGRenderStyle(CreateDefault);
37
38     fill = defaultStyle->fill;
39     stroke = defaultStyle->stroke;
40     stops = defaultStyle->stops;
41     misc = defaultStyle->misc;
42     inheritedResources = defaultStyle->inheritedResources;
43     resources = defaultStyle->resources;
44
45     setBitDefaults();
46 }
47
48 SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
49 {
50     setBitDefaults();
51
52     fill.init();
53     stroke.init();
54     stops.init();
55     misc.init();
56     inheritedResources.init();
57     resources.init();
58 }
59
60 SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
61     : RefCounted<SVGRenderStyle>()
62 {
63     fill = other.fill;
64     stroke = other.stroke;
65     stops = other.stops;
66     misc = other.misc;
67     inheritedResources = other.inheritedResources;
68     resources = other.resources;
69
70     svg_inherited_flags = other.svg_inherited_flags;
71     svg_noninherited_flags = other.svg_noninherited_flags;
72 }
73
74 SVGRenderStyle::~SVGRenderStyle()
75 {
76 }
77
78 bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const
79 {
80     return fill == other.fill
81         && stroke == other.stroke
82         && stops == other.stops
83         && misc == other.misc
84         && inheritedResources == other.inheritedResources
85         && resources == other.resources
86         && svg_inherited_flags == other.svg_inherited_flags
87         && svg_noninherited_flags == other.svg_noninherited_flags;
88 }
89
90 bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const
91 {
92     return fill != other->fill
93         || stroke != other->stroke
94         || inheritedResources != other->inheritedResources
95         || svg_inherited_flags != other->svg_inherited_flags;
96 }
97
98 void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
99 {
100     if (!svgInheritParent)
101         return;
102
103     fill = svgInheritParent->fill;
104     stroke = svgInheritParent->stroke;
105     inheritedResources = svgInheritParent->inheritedResources;
106
107     svg_inherited_flags = svgInheritParent->svg_inherited_flags;
108 }
109
110 void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other)
111 {
112     svg_noninherited_flags = other->svg_noninherited_flags;
113     stops = other->stops;
114     misc = other->misc;
115     resources = other->resources;
116 }
117
118 StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const
119 {
120     StyleDifference styleDifference;
121
122     if (diffNeedsLayoutAndPaintInvalidation(other)) {
123         styleDifference.setNeedsFullLayout();
124         styleDifference.setNeedsPaintInvalidationObject();
125     } else if (diffNeedsPaintInvalidation(other)) {
126         styleDifference.setNeedsPaintInvalidationObject();
127     }
128
129     return styleDifference;
130 }
131
132 bool SVGRenderStyle::diffNeedsLayoutAndPaintInvalidation(const SVGRenderStyle* other) const
133 {
134     // If resources change, we need a relayout, as the presence of resources influences the paint invalidation rect.
135     if (resources != other->resources)
136         return true;
137
138     // If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath.
139     if (inheritedResources != other->inheritedResources)
140         return true;
141
142     // All text related properties influence layout.
143     if (svg_inherited_flags._textAnchor != other->svg_inherited_flags._textAnchor
144         || svg_inherited_flags._writingMode != other->svg_inherited_flags._writingMode
145         || svg_inherited_flags._glyphOrientationHorizontal != other->svg_inherited_flags._glyphOrientationHorizontal
146         || svg_inherited_flags._glyphOrientationVertical != other->svg_inherited_flags._glyphOrientationVertical
147         || svg_noninherited_flags.f._alignmentBaseline != other->svg_noninherited_flags.f._alignmentBaseline
148         || svg_noninherited_flags.f._dominantBaseline != other->svg_noninherited_flags.f._dominantBaseline
149         || svg_noninherited_flags.f._baselineShift != other->svg_noninherited_flags.f._baselineShift)
150         return true;
151
152     // Text related properties influence layout.
153     if (misc->baselineShiftValue != other->misc->baselineShiftValue)
154         return true;
155
156     // These properties affect the cached stroke bounding box rects.
157     if (svg_inherited_flags._capStyle != other->svg_inherited_flags._capStyle
158         || svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle)
159         return true;
160
161     // vector-effect changes require a re-layout.
162     if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect)
163         return true;
164
165     // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated.
166     if (stroke.get() != other->stroke.get()) {
167         if (stroke->width != other->stroke->width
168             || stroke->paintType != other->stroke->paintType
169             || stroke->paintColor != other->stroke->paintColor
170             || stroke->paintUri != other->stroke->paintUri
171             || stroke->miterLimit != other->stroke->miterLimit
172             || stroke->dashArray != other->stroke->dashArray
173             || stroke->dashOffset != other->stroke->dashOffset
174             || stroke->visitedLinkPaintColor != other->stroke->visitedLinkPaintColor
175             || stroke->visitedLinkPaintUri != other->stroke->visitedLinkPaintUri
176             || stroke->visitedLinkPaintType != other->stroke->visitedLinkPaintType)
177             return true;
178     }
179
180     return false;
181 }
182
183 bool SVGRenderStyle::diffNeedsPaintInvalidation(const SVGRenderStyle* other) const
184 {
185     if (stroke->opacity != other->stroke->opacity)
186         return true;
187
188     // Painting related properties only need paint invalidation.
189     if (misc.get() != other->misc.get()) {
190         if (misc->floodColor != other->misc->floodColor
191             || misc->floodOpacity != other->misc->floodOpacity
192             || misc->lightingColor != other->misc->lightingColor)
193             return true;
194     }
195
196     // If fill changes, we just need to issue paint invalidations. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains.
197     if (fill.get() != other->fill.get()) {
198         if (fill->paintType != other->fill->paintType
199             || fill->paintColor != other->fill->paintColor
200             || fill->paintUri != other->fill->paintUri
201             || fill->opacity != other->fill->opacity)
202             return true;
203     }
204
205     // If gradient stops change, we just need to issue paint invalidations. Style updates are already handled through RenderSVGGradientSTop.
206     if (stops != other->stops)
207         return true;
208
209     // Changes of these flags only cause paint invalidations.
210     if (svg_inherited_flags._colorRendering != other->svg_inherited_flags._colorRendering
211         || svg_inherited_flags._shapeRendering != other->svg_inherited_flags._shapeRendering
212         || svg_inherited_flags._clipRule != other->svg_inherited_flags._clipRule
213         || svg_inherited_flags._fillRule != other->svg_inherited_flags._fillRule
214         || svg_inherited_flags._colorInterpolation != other->svg_inherited_flags._colorInterpolation
215         || svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._colorInterpolationFilters
216         || svg_inherited_flags._paintOrder != other->svg_inherited_flags._paintOrder)
217         return true;
218
219     if (svg_noninherited_flags.f.bufferedRendering != other->svg_noninherited_flags.f.bufferedRendering)
220         return true;
221
222     if (svg_noninherited_flags.f.maskType != other->svg_noninherited_flags.f.maskType)
223         return true;
224
225     return false;
226 }
227
228 EPaintOrderType SVGRenderStyle::paintOrderType(unsigned index) const
229 {
230     ASSERT(index < ((1 << kPaintOrderBitwidth)-1));
231     unsigned pt = (paintOrder() >> (kPaintOrderBitwidth*index)) & ((1u << kPaintOrderBitwidth) - 1);
232     return (EPaintOrderType)pt;
233 }
234
235 }