1/*
2 Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3 2004, 2005 Rob Buis <buis@kde.org>
4 Copyright (C) 2005-2017 Apple Inc. All rights reserved.
5 Copyright (C) Research In Motion Limited 2010. All rights reserved.
6 Copyright (C) 2014 Adobe Systems Incorporated. All rights reserved.
7
8 This library is free software; you can redistribute it and/or
9 modify it under the terms of the GNU Library General Public
10 License as published by the Free Software Foundation; either
11 version 2 of the License, or (at your option) any later version.
12
13 This library is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 Library General Public License for more details.
17
18 You should have received a copy of the GNU Library General Public License
19 along with this library; see the file COPYING.LIB. If not, write to
20 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
21 Boston, MA 02110-1301, USA.
22*/
23
24#pragma once
25
26#include "DataRef.h"
27#include "RenderStyleConstants.h"
28#include "SVGRenderStyleDefs.h"
29#include "WindRule.h"
30
31namespace WebCore {
32
33class SVGRenderStyle : public RefCounted<SVGRenderStyle> {
34public:
35 static Ref<SVGRenderStyle> createDefaultStyle();
36 static Ref<SVGRenderStyle> create() { return adoptRef(*new SVGRenderStyle); }
37 Ref<SVGRenderStyle> copy() const;
38 ~SVGRenderStyle();
39
40 bool inheritedNotEqual(const SVGRenderStyle&) const;
41 void inheritFrom(const SVGRenderStyle&);
42 void copyNonInheritedFrom(const SVGRenderStyle&);
43
44 StyleDifference diff(const SVGRenderStyle&) const;
45
46 bool operator==(const SVGRenderStyle&) const;
47 bool operator!=(const SVGRenderStyle& other) const { return !(*this == other); }
48
49 // Initial values for all the properties
50 static AlignmentBaseline initialAlignmentBaseline() { return AlignmentBaseline::Auto; }
51 static DominantBaseline initialDominantBaseline() { return DominantBaseline::Auto; }
52 static BaselineShift initialBaselineShift() { return BaselineShift::Baseline; }
53 static VectorEffect initialVectorEffect() { return VectorEffect::None; }
54 static BufferedRendering initialBufferedRendering() { return BufferedRendering::Auto; }
55 static WindRule initialClipRule() { return WindRule::NonZero; }
56 static ColorInterpolation initialColorInterpolation() { return ColorInterpolation::SRGB; }
57 static ColorInterpolation initialColorInterpolationFilters() { return ColorInterpolation::LinearRGB; }
58 static ColorRendering initialColorRendering() { return ColorRendering::Auto; }
59 static WindRule initialFillRule() { return WindRule::NonZero; }
60 static ShapeRendering initialShapeRendering() { return ShapeRendering::Auto; }
61 static TextAnchor initialTextAnchor() { return TextAnchor::Start; }
62 static GlyphOrientation initialGlyphOrientationHorizontal() { return GlyphOrientation::Degrees0; }
63 static GlyphOrientation initialGlyphOrientationVertical() { return GlyphOrientation::Auto; }
64 static float initialFillOpacity() { return 1; }
65 static SVGPaintType initialFillPaintType() { return SVGPaintType::RGBColor; }
66 static Color initialFillPaintColor() { return Color::black; }
67 static String initialFillPaintUri() { return String(); }
68 static float initialStrokeOpacity() { return 1; }
69 static SVGPaintType initialStrokePaintType() { return SVGPaintType::None; }
70 static Color initialStrokePaintColor() { return Color(); }
71 static String initialStrokePaintUri() { return String(); }
72 static Vector<SVGLengthValue> initialStrokeDashArray() { return { }; }
73 static float initialStopOpacity() { return 1; }
74 static Color initialStopColor() { return Color(0, 0, 0); }
75 static float initialFloodOpacity() { return 1; }
76 static Color initialFloodColor() { return Color(0, 0, 0); }
77 static Color initialLightingColor() { return Color(255, 255, 255); }
78 static ShadowData* initialShadow() { return nullptr; }
79 static String initialClipperResource() { return String(); }
80 static String initialMaskerResource() { return String(); }
81 static String initialMarkerStartResource() { return String(); }
82 static String initialMarkerMidResource() { return String(); }
83 static String initialMarkerEndResource() { return String(); }
84 static MaskType initialMaskType() { return MaskType::Luminance; }
85 static SVGLengthValue initialBaselineShiftValue();
86 static SVGLengthValue initialKerning();
87
88 // SVG CSS Property setters
89 void setAlignmentBaseline(AlignmentBaseline val) { m_nonInheritedFlags.flagBits.alignmentBaseline = static_cast<unsigned>(val); }
90 void setDominantBaseline(DominantBaseline val) { m_nonInheritedFlags.flagBits.dominantBaseline = static_cast<unsigned>(val); }
91 void setBaselineShift(BaselineShift val) { m_nonInheritedFlags.flagBits.baselineShift = static_cast<unsigned>(val); }
92 void setVectorEffect(VectorEffect val) { m_nonInheritedFlags.flagBits.vectorEffect = static_cast<unsigned>(val); }
93 void setBufferedRendering(BufferedRendering val) { m_nonInheritedFlags.flagBits.bufferedRendering = static_cast<unsigned>(val); }
94 void setClipRule(WindRule val) { m_inheritedFlags.clipRule = static_cast<unsigned>(val); }
95 void setColorInterpolation(ColorInterpolation val) { m_inheritedFlags.colorInterpolation = static_cast<unsigned>(val); }
96 void setColorInterpolationFilters(ColorInterpolation val) { m_inheritedFlags.colorInterpolationFilters = static_cast<unsigned>(val); }
97 void setColorRendering(ColorRendering val) { m_inheritedFlags.colorRendering = static_cast<unsigned>(val); }
98 void setFillRule(WindRule val) { m_inheritedFlags.fillRule = static_cast<unsigned>(val); }
99 void setShapeRendering(ShapeRendering val) { m_inheritedFlags.shapeRendering = static_cast<unsigned>(val); }
100 void setTextAnchor(TextAnchor val) { m_inheritedFlags.textAnchor = static_cast<unsigned>(val); }
101 void setGlyphOrientationHorizontal(GlyphOrientation val) { m_inheritedFlags.glyphOrientationHorizontal = static_cast<unsigned>(val); }
102 void setGlyphOrientationVertical(GlyphOrientation val) { m_inheritedFlags.glyphOrientationVertical = static_cast<unsigned>(val); }
103 void setMaskType(MaskType val) { m_nonInheritedFlags.flagBits.maskType = static_cast<unsigned>(val); }
104 void setCx(const Length&);
105 void setCy(const Length&);
106 void setR(const Length&);
107 void setRx(const Length&);
108 void setRy(const Length&);
109 void setX(const Length&);
110 void setY(const Length&);
111 void setFillOpacity(float);
112 void setFillPaint(SVGPaintType, const Color&, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false);
113 void setStrokeOpacity(float);
114 void setStrokePaint(SVGPaintType, const Color&, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false);
115
116 void setStrokeDashArray(const Vector<SVGLengthValue>&);
117 void setStrokeDashOffset(const Length&);
118 void setKerning(const SVGLengthValue&);
119 void setStopOpacity(float);
120 void setStopColor(const Color&);
121 void setFloodOpacity(float);
122 void setFloodColor(const Color&);
123 void setLightingColor(const Color&);
124 void setBaselineShiftValue(const SVGLengthValue&);
125
126 void setShadow(std::unique_ptr<ShadowData>&& data) { m_shadowData.access().shadow = WTFMove(data); }
127
128 // Setters for non-inherited resources
129 void setClipperResource(const String&);
130 void setMaskerResource(const String&);
131
132 // Setters for inherited resources
133 void setMarkerStartResource(const String&);
134 void setMarkerMidResource(const String&);
135 void setMarkerEndResource(const String&);
136
137 // Read accessors for all the properties
138 AlignmentBaseline alignmentBaseline() const { return static_cast<AlignmentBaseline>(m_nonInheritedFlags.flagBits.alignmentBaseline); }
139 DominantBaseline dominantBaseline() const { return static_cast<DominantBaseline>(m_nonInheritedFlags.flagBits.dominantBaseline); }
140 BaselineShift baselineShift() const { return static_cast<BaselineShift>(m_nonInheritedFlags.flagBits.baselineShift); }
141 VectorEffect vectorEffect() const { return static_cast<VectorEffect>(m_nonInheritedFlags.flagBits.vectorEffect); }
142 BufferedRendering bufferedRendering() const { return static_cast<BufferedRendering>(m_nonInheritedFlags.flagBits.bufferedRendering); }
143 WindRule clipRule() const { return static_cast<WindRule>(m_inheritedFlags.clipRule); }
144 ColorInterpolation colorInterpolation() const { return static_cast<ColorInterpolation>(m_inheritedFlags.colorInterpolation); }
145 ColorInterpolation colorInterpolationFilters() const { return static_cast<ColorInterpolation>(m_inheritedFlags.colorInterpolationFilters); }
146 ColorRendering colorRendering() const { return static_cast<ColorRendering>(m_inheritedFlags.colorRendering); }
147 WindRule fillRule() const { return static_cast<WindRule>(m_inheritedFlags.fillRule); }
148 ShapeRendering shapeRendering() const { return static_cast<ShapeRendering>(m_inheritedFlags.shapeRendering); }
149 TextAnchor textAnchor() const { return static_cast<TextAnchor>(m_inheritedFlags.textAnchor); }
150 GlyphOrientation glyphOrientationHorizontal() const { return static_cast<GlyphOrientation>(m_inheritedFlags.glyphOrientationHorizontal); }
151 GlyphOrientation glyphOrientationVertical() const { return static_cast<GlyphOrientation>(m_inheritedFlags.glyphOrientationVertical); }
152 float fillOpacity() const { return m_fillData->opacity; }
153 SVGPaintType fillPaintType() const { return static_cast<SVGPaintType>(m_fillData->paintType); }
154 const Color& fillPaintColor() const { return m_fillData->paintColor; }
155 const String& fillPaintUri() const { return m_fillData->paintUri; }
156 float strokeOpacity() const { return m_strokeData->opacity; }
157 SVGPaintType strokePaintType() const { return static_cast<SVGPaintType>(m_strokeData->paintType); }
158 const Color& strokePaintColor() const { return m_strokeData->paintColor; }
159 const String& strokePaintUri() const { return m_strokeData->paintUri; }
160 Vector<SVGLengthValue> strokeDashArray() const { return m_strokeData->dashArray; }
161 const Length& strokeDashOffset() const { return m_strokeData->dashOffset; }
162 SVGLengthValue kerning() const { return m_textData->kerning; }
163 float stopOpacity() const { return m_stopData->opacity; }
164 const Color& stopColor() const { return m_stopData->color; }
165 float floodOpacity() const { return m_miscData->floodOpacity; }
166 const Color& floodColor() const { return m_miscData->floodColor; }
167 const Color& lightingColor() const { return m_miscData->lightingColor; }
168 SVGLengthValue baselineShiftValue() const { return m_miscData->baselineShiftValue; }
169 ShadowData* shadow() const { return m_shadowData->shadow.get(); }
170 const Length& cx() const { return m_layoutData->cx; }
171 const Length& cy() const { return m_layoutData->cy; }
172 const Length& r() const { return m_layoutData->r; }
173 const Length& rx() const { return m_layoutData->rx; }
174 const Length& ry() const { return m_layoutData->ry; }
175 const Length& x() const { return m_layoutData->x; }
176 const Length& y() const { return m_layoutData->y; }
177 const String& clipperResource() const { return m_nonInheritedResourceData->clipper; }
178 const String& maskerResource() const { return m_nonInheritedResourceData->masker; }
179 const String& markerStartResource() const { return m_inheritedResourceData->markerStart; }
180 const String& markerMidResource() const { return m_inheritedResourceData->markerMid; }
181 const String& markerEndResource() const { return m_inheritedResourceData->markerEnd; }
182 MaskType maskType() const { return static_cast<MaskType>(m_nonInheritedFlags.flagBits.maskType); }
183
184 SVGPaintType visitedLinkFillPaintType() const { return static_cast<SVGPaintType>(m_fillData->visitedLinkPaintType); }
185 const Color& visitedLinkFillPaintColor() const { return m_fillData->visitedLinkPaintColor; }
186 const String& visitedLinkFillPaintUri() const { return m_fillData->visitedLinkPaintUri; }
187 SVGPaintType visitedLinkStrokePaintType() const { return static_cast<SVGPaintType>(m_strokeData->visitedLinkPaintType); }
188 const Color& visitedLinkStrokePaintColor() const { return m_strokeData->visitedLinkPaintColor; }
189 const String& visitedLinkStrokePaintUri() const { return m_strokeData->visitedLinkPaintUri; }
190
191 // convenience
192 bool hasClipper() const { return !clipperResource().isEmpty(); }
193 bool hasMasker() const { return !maskerResource().isEmpty(); }
194 bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); }
195 bool hasStroke() const { return strokePaintType() != SVGPaintType::None; }
196 bool hasFill() const { return fillPaintType() != SVGPaintType::None; }
197 bool isolatesBlending() const { return hasMasker() || shadow(); }
198
199private:
200 SVGRenderStyle();
201 SVGRenderStyle(const SVGRenderStyle&);
202
203 enum CreateDefaultType { CreateDefault };
204 SVGRenderStyle(CreateDefaultType); // Used to create the default style.
205
206 void setBitDefaults();
207
208 struct InheritedFlags {
209 bool operator==(const InheritedFlags&) const;
210 bool operator!=(const InheritedFlags& other) const { return !(*this == other); }
211
212 unsigned colorRendering : 2; // ColorRendering
213 unsigned shapeRendering : 2; // ShapeRendering
214 unsigned clipRule : 1; // WindRule
215 unsigned fillRule : 1; // WindRule
216 unsigned textAnchor : 2; // TextAnchor
217 unsigned colorInterpolation : 2; // ColorInterpolation
218 unsigned colorInterpolationFilters : 2; // ColorInterpolation
219 unsigned glyphOrientationHorizontal : 3; // GlyphOrientation
220 unsigned glyphOrientationVertical : 3; // GlyphOrientation
221 };
222
223 struct NonInheritedFlags {
224 // 32 bit non-inherited, don't add to the struct, or the operator will break.
225 bool operator==(const NonInheritedFlags& other) const { return flags == other.flags; }
226 bool operator!=(const NonInheritedFlags& other) const { return flags != other.flags; }
227
228 union {
229 struct {
230 unsigned alignmentBaseline : 4; // AlignmentBaseline
231 unsigned dominantBaseline : 4; // DominantBaseline
232 unsigned baselineShift : 2; // BaselineShift
233 unsigned vectorEffect: 1; // VectorEffect
234 unsigned bufferedRendering: 2; // BufferedRendering
235 unsigned maskType: 1; // MaskType
236 // 18 bits unused
237 } flagBits;
238 uint32_t flags;
239 };
240 };
241
242 InheritedFlags m_inheritedFlags;
243 NonInheritedFlags m_nonInheritedFlags;
244
245 // inherited attributes
246 DataRef<StyleFillData> m_fillData;
247 DataRef<StyleStrokeData> m_strokeData;
248 DataRef<StyleTextData> m_textData;
249 DataRef<StyleInheritedResourceData> m_inheritedResourceData;
250
251 // non-inherited attributes
252 DataRef<StyleStopData> m_stopData;
253 DataRef<StyleMiscData> m_miscData;
254 DataRef<StyleShadowSVGData> m_shadowData;
255 DataRef<StyleLayoutData> m_layoutData;
256 DataRef<StyleResourceData> m_nonInheritedResourceData;
257};
258
259inline SVGLengthValue SVGRenderStyle::initialBaselineShiftValue()
260{
261 SVGLengthValue length;
262 length.newValueSpecifiedUnits(LengthTypeNumber, 0);
263 return length;
264}
265
266inline SVGLengthValue SVGRenderStyle::initialKerning()
267{
268 SVGLengthValue length;
269 length.newValueSpecifiedUnits(LengthTypeNumber, 0);
270 return length;
271}
272
273inline void SVGRenderStyle::setCx(const Length& length)
274{
275 if (!(m_layoutData->cx == length))
276 m_layoutData.access().cx = length;
277}
278
279inline void SVGRenderStyle::setCy(const Length& length)
280{
281 if (!(m_layoutData->cy == length))
282 m_layoutData.access().cy = length;
283}
284
285inline void SVGRenderStyle::setR(const Length& length)
286{
287 if (!(m_layoutData->r == length))
288 m_layoutData.access().r = length;
289}
290
291inline void SVGRenderStyle::setRx(const Length& length)
292{
293 if (!(m_layoutData->rx == length))
294 m_layoutData.access().rx = length;
295}
296
297inline void SVGRenderStyle::setRy(const Length& length)
298{
299 if (!(m_layoutData->ry == length))
300 m_layoutData.access().ry = length;
301}
302
303inline void SVGRenderStyle::setX(const Length& length)
304{
305 if (!(m_layoutData->x == length))
306 m_layoutData.access().x = length;
307}
308
309inline void SVGRenderStyle::setY(const Length& length)
310{
311 if (!(m_layoutData->y == length))
312 m_layoutData.access().y = length;
313}
314
315inline void SVGRenderStyle::setFillOpacity(float opacity)
316{
317 if (!(m_fillData->opacity == opacity))
318 m_fillData.access().opacity = opacity;
319}
320
321inline void SVGRenderStyle::setFillPaint(SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle, bool applyToVisitedLinkStyle)
322{
323 if (applyToRegularStyle) {
324 if (!(m_fillData->paintType == type))
325 m_fillData.access().paintType = type;
326 if (!(m_fillData->paintColor == color))
327 m_fillData.access().paintColor = color;
328 if (!(m_fillData->paintUri == uri))
329 m_fillData.access().paintUri = uri;
330 }
331 if (applyToVisitedLinkStyle) {
332 if (!(m_fillData->visitedLinkPaintType == type))
333 m_fillData.access().visitedLinkPaintType = type;
334 if (!(m_fillData->visitedLinkPaintColor == color))
335 m_fillData.access().visitedLinkPaintColor = color;
336 if (!(m_fillData->visitedLinkPaintUri == uri))
337 m_fillData.access().visitedLinkPaintUri = uri;
338 }
339}
340
341inline void SVGRenderStyle::setStrokeOpacity(float opacity)
342{
343 if (!(m_strokeData->opacity == opacity))
344 m_strokeData.access().opacity = opacity;
345}
346
347inline void SVGRenderStyle::setStrokePaint(SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle, bool applyToVisitedLinkStyle)
348{
349 if (applyToRegularStyle) {
350 if (!(m_strokeData->paintType == type))
351 m_strokeData.access().paintType = type;
352 if (!(m_strokeData->paintColor == color))
353 m_strokeData.access().paintColor = color;
354 if (!(m_strokeData->paintUri == uri))
355 m_strokeData.access().paintUri = uri;
356 }
357 if (applyToVisitedLinkStyle) {
358 if (!(m_strokeData->visitedLinkPaintType == type))
359 m_strokeData.access().visitedLinkPaintType = type;
360 if (!(m_strokeData->visitedLinkPaintColor == color))
361 m_strokeData.access().visitedLinkPaintColor = color;
362 if (!(m_strokeData->visitedLinkPaintUri == uri))
363 m_strokeData.access().visitedLinkPaintUri = uri;
364 }
365}
366
367inline void SVGRenderStyle::setStrokeDashArray(const Vector<SVGLengthValue>& array)
368{
369 if (!(m_strokeData->dashArray == array))
370 m_strokeData.access().dashArray = array;
371}
372
373inline void SVGRenderStyle::setStrokeDashOffset(const Length& offset)
374{
375 if (!(m_strokeData->dashOffset == offset))
376 m_strokeData.access().dashOffset = offset;
377}
378
379inline void SVGRenderStyle::setKerning(const SVGLengthValue& kerning)
380{
381 if (!(m_textData->kerning == kerning))
382 m_textData.access().kerning = kerning;
383}
384
385inline void SVGRenderStyle::setStopOpacity(float opacity)
386{
387 if (!(m_stopData->opacity == opacity))
388 m_stopData.access().opacity = opacity;
389}
390
391inline void SVGRenderStyle::setStopColor(const Color& color)
392{
393 if (!(m_stopData->color == color))
394 m_stopData.access().color = color;
395}
396
397inline void SVGRenderStyle::setFloodOpacity(float opacity)
398{
399 if (!(m_miscData->floodOpacity == opacity))
400 m_miscData.access().floodOpacity = opacity;
401}
402
403inline void SVGRenderStyle::setFloodColor(const Color& color)
404{
405 if (!(m_miscData->floodColor == color))
406 m_miscData.access().floodColor = color;
407}
408
409inline void SVGRenderStyle::setLightingColor(const Color& color)
410{
411 if (!(m_miscData->lightingColor == color))
412 m_miscData.access().lightingColor = color;
413}
414
415inline void SVGRenderStyle::setBaselineShiftValue(const SVGLengthValue& shiftValue)
416{
417 if (!(m_miscData->baselineShiftValue == shiftValue))
418 m_miscData.access().baselineShiftValue = shiftValue;
419}
420
421inline void SVGRenderStyle::setClipperResource(const String& resource)
422{
423 if (!(m_nonInheritedResourceData->clipper == resource))
424 m_nonInheritedResourceData.access().clipper = resource;
425}
426
427inline void SVGRenderStyle::setMaskerResource(const String& resource)
428{
429 if (!(m_nonInheritedResourceData->masker == resource))
430 m_nonInheritedResourceData.access().masker = resource;
431}
432
433inline void SVGRenderStyle::setMarkerStartResource(const String& resource)
434{
435 if (!(m_inheritedResourceData->markerStart == resource))
436 m_inheritedResourceData.access().markerStart = resource;
437}
438
439inline void SVGRenderStyle::setMarkerMidResource(const String& resource)
440{
441 if (!(m_inheritedResourceData->markerMid == resource))
442 m_inheritedResourceData.access().markerMid = resource;
443}
444
445inline void SVGRenderStyle::setMarkerEndResource(const String& resource)
446{
447 if (!(m_inheritedResourceData->markerEnd == resource))
448 m_inheritedResourceData.access().markerEnd = resource;
449}
450
451inline void SVGRenderStyle::setBitDefaults()
452{
453 m_inheritedFlags.clipRule = static_cast<unsigned>(initialClipRule());
454 m_inheritedFlags.colorRendering = static_cast<unsigned>(initialColorRendering());
455 m_inheritedFlags.fillRule = static_cast<unsigned>(initialFillRule());
456 m_inheritedFlags.shapeRendering = static_cast<unsigned>(initialShapeRendering());
457 m_inheritedFlags.textAnchor = static_cast<unsigned>(initialTextAnchor());
458 m_inheritedFlags.colorInterpolation = static_cast<unsigned>(initialColorInterpolation());
459 m_inheritedFlags.colorInterpolationFilters = static_cast<unsigned>(initialColorInterpolationFilters());
460 m_inheritedFlags.glyphOrientationHorizontal = static_cast<unsigned>(initialGlyphOrientationHorizontal());
461 m_inheritedFlags.glyphOrientationVertical = static_cast<unsigned>(initialGlyphOrientationVertical());
462
463 m_nonInheritedFlags.flags = 0;
464 m_nonInheritedFlags.flagBits.alignmentBaseline = static_cast<unsigned>(initialAlignmentBaseline());
465 m_nonInheritedFlags.flagBits.dominantBaseline = static_cast<unsigned>(initialDominantBaseline());
466 m_nonInheritedFlags.flagBits.baselineShift = static_cast<unsigned>(initialBaselineShift());
467 m_nonInheritedFlags.flagBits.vectorEffect = static_cast<unsigned>(initialVectorEffect());
468 m_nonInheritedFlags.flagBits.bufferedRendering = static_cast<unsigned>(initialBufferedRendering());
469 m_nonInheritedFlags.flagBits.maskType = static_cast<unsigned>(initialMaskType());
470}
471
472inline bool SVGRenderStyle::InheritedFlags::operator==(const InheritedFlags& other) const
473{
474 return colorRendering == other.colorRendering
475 && shapeRendering == other.shapeRendering
476 && clipRule == other.clipRule
477 && fillRule == other.fillRule
478 && textAnchor == other.textAnchor
479 && colorInterpolation == other.colorInterpolation
480 && colorInterpolationFilters == other.colorInterpolationFilters
481 && glyphOrientationHorizontal == other.glyphOrientationHorizontal
482 && glyphOrientationVertical == other.glyphOrientationVertical;
483}
484
485} // namespace WebCore
486