• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SVGRenderStyle()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 
SVGRenderStyle(CreateDefaultType)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 
SVGRenderStyle(const SVGRenderStyle & other)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 
~SVGRenderStyle()74 SVGRenderStyle::~SVGRenderStyle()
75 {
76 }
77 
operator ==(const SVGRenderStyle & other) const78 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 
inheritedNotEqual(const SVGRenderStyle * other) const90 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 
inheritFrom(const SVGRenderStyle * svgInheritParent)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 
copyNonInheritedFrom(const SVGRenderStyle * other)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 
diff(const SVGRenderStyle * other) const118 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 
diffNeedsLayoutAndPaintInvalidation(const SVGRenderStyle * other) const132 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 
diffNeedsPaintInvalidation(const SVGRenderStyle * other) const183 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 
paintOrderType(unsigned index) const228 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 }
236