Implement stroke-miterlimit.
[WebKit-https.git] / Source / WebCore / rendering / style / SVGRenderStyle.h
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 "GraphicsTypes.h"
28 #include "Path.h"
29 #include "RenderStyleConstants.h"
30 #include "SVGRenderStyleDefs.h"
31
32 namespace WebCore {
33
34 class SVGRenderStyle : public RefCounted<SVGRenderStyle> {
35 public:
36     static Ref<SVGRenderStyle> createDefaultStyle();
37     static Ref<SVGRenderStyle> create() { return adoptRef(*new SVGRenderStyle); }
38     Ref<SVGRenderStyle> copy() const;
39     ~SVGRenderStyle();
40
41     bool inheritedNotEqual(const SVGRenderStyle&) const;
42     void inheritFrom(const SVGRenderStyle&);
43     void copyNonInheritedFrom(const SVGRenderStyle&);
44
45     StyleDifference diff(const SVGRenderStyle&) const;
46
47     bool operator==(const SVGRenderStyle&) const;
48     bool operator!=(const SVGRenderStyle& other) const { return !(*this == other); }
49
50     // Initial values for all the properties
51     static EAlignmentBaseline initialAlignmentBaseline() { return AB_AUTO; }
52     static EDominantBaseline initialDominantBaseline() { return DB_AUTO; }
53     static EBaselineShift initialBaselineShift() { return BS_BASELINE; }
54     static EVectorEffect initialVectorEffect() { return VE_NONE; }
55     static EBufferedRendering initialBufferedRendering() { return BR_AUTO; }
56     static WindRule initialClipRule() { return RULE_NONZERO; }
57     static EColorInterpolation initialColorInterpolation() { return CI_SRGB; }
58     static EColorInterpolation initialColorInterpolationFilters() { return CI_LINEARRGB; }
59     static EColorRendering initialColorRendering() { return CR_AUTO; }
60     static WindRule initialFillRule() { return RULE_NONZERO; }
61     static EShapeRendering initialShapeRendering() { return SR_AUTO; }
62     static ETextAnchor initialTextAnchor() { return TA_START; }
63     static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; }
64     static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; }
65     static float initialFillOpacity() { return 1; }
66     static SVGPaintType initialFillPaintType() { return SVG_PAINTTYPE_RGBCOLOR; }
67     static Color initialFillPaintColor() { return Color::black; }
68     static String initialFillPaintUri() { return String(); }
69     static float initialStrokeOpacity() { return 1; }
70     static SVGPaintType initialStrokePaintType() { return SVG_PAINTTYPE_NONE; }
71     static Color initialStrokePaintColor() { return Color(); }
72     static String initialStrokePaintUri() { return String(); }
73     static Vector<SVGLengthValue> initialStrokeDashArray() { return { }; }
74     static float initialStopOpacity() { return 1; }
75     static Color initialStopColor() { return Color(0, 0, 0); }
76     static float initialFloodOpacity() { return 1; }
77     static Color initialFloodColor() { return Color(0, 0, 0); }
78     static Color initialLightingColor() { return Color(255, 255, 255); }
79     static ShadowData* initialShadow() { return nullptr; }
80     static String initialClipperResource() { return String(); }
81     static String initialMaskerResource() { return String(); }
82     static String initialMarkerStartResource() { return String(); }
83     static String initialMarkerMidResource() { return String(); }
84     static String initialMarkerEndResource() { return String(); }
85     static EMaskType initialMaskType() { return MT_LUMINANCE; }
86     static SVGLengthValue initialBaselineShiftValue();
87     static SVGLengthValue initialKerning();
88
89     // SVG CSS Property setters
90     void setAlignmentBaseline(EAlignmentBaseline val) { m_nonInheritedFlags.flagBits.alignmentBaseline = val; }
91     void setDominantBaseline(EDominantBaseline val) { m_nonInheritedFlags.flagBits.dominantBaseline = val; }
92     void setBaselineShift(EBaselineShift val) { m_nonInheritedFlags.flagBits.baselineShift = val; }
93     void setVectorEffect(EVectorEffect val) { m_nonInheritedFlags.flagBits.vectorEffect = val; }
94     void setBufferedRendering(EBufferedRendering val) { m_nonInheritedFlags.flagBits.bufferedRendering = val; }
95     void setClipRule(WindRule val) { m_inheritedFlags.clipRule = val; }
96     void setColorInterpolation(EColorInterpolation val) { m_inheritedFlags.colorInterpolation = val; }
97     void setColorInterpolationFilters(EColorInterpolation val) { m_inheritedFlags.colorInterpolationFilters = val; }
98     void setColorRendering(EColorRendering val) { m_inheritedFlags.colorRendering = val; }
99     void setFillRule(WindRule val) { m_inheritedFlags.fillRule = val; }
100     void setShapeRendering(EShapeRendering val) { m_inheritedFlags.shapeRendering = val; }
101     void setTextAnchor(ETextAnchor val) { m_inheritedFlags.textAnchor = val; }
102     void setGlyphOrientationHorizontal(EGlyphOrientation val) { m_inheritedFlags.glyphOrientationHorizontal = val; }
103     void setGlyphOrientationVertical(EGlyphOrientation val) { m_inheritedFlags.glyphOrientationVertical = val; }
104     void setMaskType(EMaskType val) { m_nonInheritedFlags.flagBits.maskType = val; }
105     void setCx(const Length&);
106     void setCy(const Length&);
107     void setR(const Length&);
108     void setRx(const Length&);
109     void setRy(const Length&);
110     void setX(const Length&);
111     void setY(const Length&);
112     void setFillOpacity(float);
113     void setFillPaint(SVGPaintType, const Color&, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false);
114     void setStrokeOpacity(float);
115     void setStrokePaint(SVGPaintType, const Color&, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false);
116
117     void setStrokeDashArray(const Vector<SVGLengthValue>&);
118     void setStrokeDashOffset(const Length&);
119     void setKerning(const SVGLengthValue&);
120     void setStopOpacity(float);
121     void setStopColor(const Color&);
122     void setFloodOpacity(float);
123     void setFloodColor(const Color&);
124     void setLightingColor(const Color&);
125     void setBaselineShiftValue(const SVGLengthValue&);
126
127     void setShadow(std::unique_ptr<ShadowData>&& data) { m_shadowData.access().shadow = WTFMove(data); }
128
129     // Setters for non-inherited resources
130     void setClipperResource(const String&);
131     void setMaskerResource(const String&);
132
133     // Setters for inherited resources
134     void setMarkerStartResource(const String&);
135     void setMarkerMidResource(const String&);
136     void setMarkerEndResource(const String&);
137
138     // Read accessors for all the properties
139     EAlignmentBaseline alignmentBaseline() const { return (EAlignmentBaseline) m_nonInheritedFlags.flagBits.alignmentBaseline; }
140     EDominantBaseline dominantBaseline() const { return (EDominantBaseline) m_nonInheritedFlags.flagBits.dominantBaseline; }
141     EBaselineShift baselineShift() const { return (EBaselineShift) m_nonInheritedFlags.flagBits.baselineShift; }
142     EVectorEffect vectorEffect() const { return (EVectorEffect) m_nonInheritedFlags.flagBits.vectorEffect; }
143     EBufferedRendering bufferedRendering() const { return (EBufferedRendering) m_nonInheritedFlags.flagBits.bufferedRendering; }
144     WindRule clipRule() const { return (WindRule) m_inheritedFlags.clipRule; }
145     EColorInterpolation colorInterpolation() const { return (EColorInterpolation) m_inheritedFlags.colorInterpolation; }
146     EColorInterpolation colorInterpolationFilters() const { return (EColorInterpolation) m_inheritedFlags.colorInterpolationFilters; }
147     EColorRendering colorRendering() const { return (EColorRendering) m_inheritedFlags.colorRendering; }
148     WindRule fillRule() const { return (WindRule) m_inheritedFlags.fillRule; }
149     EShapeRendering shapeRendering() const { return (EShapeRendering) m_inheritedFlags.shapeRendering; }
150     ETextAnchor textAnchor() const { return (ETextAnchor) m_inheritedFlags.textAnchor; }
151     EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) m_inheritedFlags.glyphOrientationHorizontal; }
152     EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) m_inheritedFlags.glyphOrientationVertical; }
153     float fillOpacity() const { return m_fillData->opacity; }
154     const SVGPaintType& fillPaintType() const { return m_fillData->paintType; }
155     const Color& fillPaintColor() const { return m_fillData->paintColor; }
156     const String& fillPaintUri() const { return m_fillData->paintUri; }    
157     float strokeOpacity() const { return m_strokeData->opacity; }
158     const SVGPaintType& strokePaintType() const { return m_strokeData->paintType; }
159     const Color& strokePaintColor() const { return m_strokeData->paintColor; }
160     const String& strokePaintUri() const { return m_strokeData->paintUri; }
161     Vector<SVGLengthValue> strokeDashArray() const { return m_strokeData->dashArray; }
162     const Length& strokeDashOffset() const { return m_strokeData->dashOffset; }
163     SVGLengthValue kerning() const { return m_textData->kerning; }
164     float stopOpacity() const { return m_stopData->opacity; }
165     const Color& stopColor() const { return m_stopData->color; }
166     float floodOpacity() const { return m_miscData->floodOpacity; }
167     const Color& floodColor() const { return m_miscData->floodColor; }
168     const Color& lightingColor() const { return m_miscData->lightingColor; }
169     SVGLengthValue baselineShiftValue() const { return m_miscData->baselineShiftValue; }
170     ShadowData* shadow() const { return m_shadowData->shadow.get(); }
171     const Length& cx() const { return m_layoutData->cx; }
172     const Length& cy() const { return m_layoutData->cy; }
173     const Length& r() const { return m_layoutData->r; }
174     const Length& rx() const { return m_layoutData->rx; }
175     const Length& ry() const { return m_layoutData->ry; }
176     const Length& x() const { return m_layoutData->x; }
177     const Length& y() const { return m_layoutData->y; }
178     const String& clipperResource() const { return m_nonInheritedResourceData->clipper; }
179     const String& maskerResource() const { return m_nonInheritedResourceData->masker; }
180     const String& markerStartResource() const { return m_inheritedResourceData->markerStart; }
181     const String& markerMidResource() const { return m_inheritedResourceData->markerMid; }
182     const String& markerEndResource() const { return m_inheritedResourceData->markerEnd; }
183     EMaskType maskType() const { return (EMaskType) m_nonInheritedFlags.flagBits.maskType; }
184
185     const SVGPaintType& visitedLinkFillPaintType() const { return m_fillData->visitedLinkPaintType; }
186     const Color& visitedLinkFillPaintColor() const { return m_fillData->visitedLinkPaintColor; }
187     const String& visitedLinkFillPaintUri() const { return m_fillData->visitedLinkPaintUri; }
188     const SVGPaintType& visitedLinkStrokePaintType() const { return m_strokeData->visitedLinkPaintType; }
189     const Color& visitedLinkStrokePaintColor() const { return m_strokeData->visitedLinkPaintColor; }
190     const String& visitedLinkStrokePaintUri() const { return m_strokeData->visitedLinkPaintUri; }
191
192     // convenience
193     bool hasClipper() const { return !clipperResource().isEmpty(); }
194     bool hasMasker() const { return !maskerResource().isEmpty(); }
195     bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); }
196     bool hasStroke() const { return strokePaintType() != SVG_PAINTTYPE_NONE; }
197     bool hasFill() const { return fillPaintType() != SVG_PAINTTYPE_NONE; }
198     bool isolatesBlending() const { return hasMasker() || shadow(); }
199
200 private:
201     SVGRenderStyle();
202     SVGRenderStyle(const SVGRenderStyle&);
203
204     enum CreateDefaultType { CreateDefault };
205     SVGRenderStyle(CreateDefaultType); // Used to create the default style.
206
207     void setBitDefaults();
208
209     struct InheritedFlags {
210         bool operator==(const InheritedFlags&) const;
211         bool operator!=(const InheritedFlags& other) const { return !(*this == other); }
212
213         unsigned colorRendering : 2; // EColorRendering
214         unsigned shapeRendering : 2; // EShapeRendering
215         unsigned clipRule : 1; // WindRule
216         unsigned fillRule : 1; // WindRule
217         unsigned textAnchor : 2; // ETextAnchor
218         unsigned colorInterpolation : 2; // EColorInterpolation
219         unsigned colorInterpolationFilters : 2; // EColorInterpolation
220         unsigned glyphOrientationHorizontal : 3; // EGlyphOrientation
221         unsigned glyphOrientationVertical : 3; // EGlyphOrientation
222     };
223
224     struct NonInheritedFlags {
225         // 32 bit non-inherited, don't add to the struct, or the operator will break.
226         bool operator==(const NonInheritedFlags& other) const { return flags == other.flags; }
227         bool operator!=(const NonInheritedFlags& other) const { return flags != other.flags; }
228
229         union {
230             struct {
231                 unsigned alignmentBaseline : 4; // EAlignmentBaseline
232                 unsigned dominantBaseline : 4; // EDominantBaseline
233                 unsigned baselineShift : 2; // EBaselineShift
234                 unsigned vectorEffect: 1; // EVectorEffect
235                 unsigned bufferedRendering: 2; // EBufferedRendering
236                 unsigned maskType: 1; // EMaskType
237                 // 18 bits unused
238             } flagBits;
239             uint32_t flags;
240         };
241     };
242
243     InheritedFlags m_inheritedFlags;
244     NonInheritedFlags m_nonInheritedFlags;
245
246     // inherited attributes
247     DataRef<StyleFillData> m_fillData;
248     DataRef<StyleStrokeData> m_strokeData;
249     DataRef<StyleTextData> m_textData;
250     DataRef<StyleInheritedResourceData> m_inheritedResourceData;
251
252     // non-inherited attributes
253     DataRef<StyleStopData> m_stopData;
254     DataRef<StyleMiscData> m_miscData;
255     DataRef<StyleShadowSVGData> m_shadowData;
256     DataRef<StyleLayoutData> m_layoutData;
257     DataRef<StyleResourceData> m_nonInheritedResourceData;
258 };
259
260 inline SVGLengthValue SVGRenderStyle::initialBaselineShiftValue()
261 {
262     SVGLengthValue length;
263     length.newValueSpecifiedUnits(LengthTypeNumber, 0);
264     return length;
265 }
266
267 inline SVGLengthValue SVGRenderStyle::initialKerning()
268 {
269     SVGLengthValue length;
270     length.newValueSpecifiedUnits(LengthTypeNumber, 0);
271     return length;
272 }
273
274 inline void SVGRenderStyle::setCx(const Length& length)
275 {
276     if (!(m_layoutData->cx == length))
277         m_layoutData.access().cx = length;
278 }
279
280 inline void SVGRenderStyle::setCy(const Length& length)
281 {
282     if (!(m_layoutData->cy == length))
283         m_layoutData.access().cy = length;
284 }
285
286 inline void SVGRenderStyle::setR(const Length& length)
287 {
288     if (!(m_layoutData->r == length))
289         m_layoutData.access().r = length;
290 }
291
292 inline void SVGRenderStyle::setRx(const Length& length)
293 {
294     if (!(m_layoutData->rx == length))
295         m_layoutData.access().rx = length;
296 }
297
298 inline void SVGRenderStyle::setRy(const Length& length)
299 {
300     if (!(m_layoutData->ry == length))
301         m_layoutData.access().ry = length;
302 }
303
304 inline void SVGRenderStyle::setX(const Length& length)
305 {
306     if (!(m_layoutData->x == length))
307         m_layoutData.access().x = length;
308 }
309
310 inline void SVGRenderStyle::setY(const Length& length)
311 {
312     if (!(m_layoutData->y == length))
313         m_layoutData.access().y = length;
314 }
315
316 inline void SVGRenderStyle::setFillOpacity(float opacity)
317 {
318     if (!(m_fillData->opacity == opacity))
319         m_fillData.access().opacity = opacity;
320 }
321
322 inline void SVGRenderStyle::setFillPaint(SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle, bool applyToVisitedLinkStyle)
323 {
324     if (applyToRegularStyle) {
325         if (!(m_fillData->paintType == type))
326             m_fillData.access().paintType = type;
327         if (!(m_fillData->paintColor == color))
328             m_fillData.access().paintColor = color;
329         if (!(m_fillData->paintUri == uri))
330             m_fillData.access().paintUri = uri;
331     }
332     if (applyToVisitedLinkStyle) {
333         if (!(m_fillData->visitedLinkPaintType == type))
334             m_fillData.access().visitedLinkPaintType = type;
335         if (!(m_fillData->visitedLinkPaintColor == color))
336             m_fillData.access().visitedLinkPaintColor = color;
337         if (!(m_fillData->visitedLinkPaintUri == uri))
338             m_fillData.access().visitedLinkPaintUri = uri;
339     }
340 }
341
342 inline void SVGRenderStyle::setStrokeOpacity(float opacity)
343 {
344     if (!(m_strokeData->opacity == opacity))
345         m_strokeData.access().opacity = opacity;
346 }
347
348 inline void SVGRenderStyle::setStrokePaint(SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle, bool applyToVisitedLinkStyle)
349 {
350     if (applyToRegularStyle) {
351         if (!(m_strokeData->paintType == type))
352             m_strokeData.access().paintType = type;
353         if (!(m_strokeData->paintColor == color))
354             m_strokeData.access().paintColor = color;
355         if (!(m_strokeData->paintUri == uri))
356             m_strokeData.access().paintUri = uri;
357     }
358     if (applyToVisitedLinkStyle) {
359         if (!(m_strokeData->visitedLinkPaintType == type))
360             m_strokeData.access().visitedLinkPaintType = type;
361         if (!(m_strokeData->visitedLinkPaintColor == color))
362             m_strokeData.access().visitedLinkPaintColor = color;
363         if (!(m_strokeData->visitedLinkPaintUri == uri))
364             m_strokeData.access().visitedLinkPaintUri = uri;
365     }
366 }
367
368 inline void SVGRenderStyle::setStrokeDashArray(const Vector<SVGLengthValue>& array)
369 {
370     if (!(m_strokeData->dashArray == array))
371         m_strokeData.access().dashArray = array;
372 }
373
374 inline void SVGRenderStyle::setStrokeDashOffset(const Length& offset)
375 {
376     if (!(m_strokeData->dashOffset == offset))
377         m_strokeData.access().dashOffset = offset;
378 }
379
380 inline void SVGRenderStyle::setKerning(const SVGLengthValue& kerning)
381 {
382     if (!(m_textData->kerning == kerning))
383         m_textData.access().kerning = kerning;
384 }
385
386 inline void SVGRenderStyle::setStopOpacity(float opacity)
387 {
388     if (!(m_stopData->opacity == opacity))
389         m_stopData.access().opacity = opacity;
390 }
391
392 inline void SVGRenderStyle::setStopColor(const Color& color)
393 {
394     if (!(m_stopData->color == color))
395         m_stopData.access().color = color;
396 }
397
398 inline void SVGRenderStyle::setFloodOpacity(float opacity)
399 {
400     if (!(m_miscData->floodOpacity == opacity))
401         m_miscData.access().floodOpacity = opacity;
402 }
403
404 inline void SVGRenderStyle::setFloodColor(const Color& color)
405 {
406     if (!(m_miscData->floodColor == color))
407         m_miscData.access().floodColor = color;
408 }
409
410 inline void SVGRenderStyle::setLightingColor(const Color& color)
411 {
412     if (!(m_miscData->lightingColor == color))
413         m_miscData.access().lightingColor = color;
414 }
415
416 inline void SVGRenderStyle::setBaselineShiftValue(const SVGLengthValue& shiftValue)
417 {
418     if (!(m_miscData->baselineShiftValue == shiftValue))
419         m_miscData.access().baselineShiftValue = shiftValue;
420 }
421
422 inline void SVGRenderStyle::setClipperResource(const String& resource)
423 {
424     if (!(m_nonInheritedResourceData->clipper == resource))
425         m_nonInheritedResourceData.access().clipper = resource;
426 }
427
428 inline void SVGRenderStyle::setMaskerResource(const String& resource)
429 {
430     if (!(m_nonInheritedResourceData->masker == resource))
431         m_nonInheritedResourceData.access().masker = resource;
432 }
433
434 inline void SVGRenderStyle::setMarkerStartResource(const String& resource)
435 {
436     if (!(m_inheritedResourceData->markerStart == resource))
437         m_inheritedResourceData.access().markerStart = resource;
438 }
439
440 inline void SVGRenderStyle::setMarkerMidResource(const String& resource)
441 {
442     if (!(m_inheritedResourceData->markerMid == resource))
443         m_inheritedResourceData.access().markerMid = resource;
444 }
445
446 inline void SVGRenderStyle::setMarkerEndResource(const String& resource)
447 {
448     if (!(m_inheritedResourceData->markerEnd == resource))
449         m_inheritedResourceData.access().markerEnd = resource;
450 }
451
452 inline void SVGRenderStyle::setBitDefaults()
453 {
454     m_inheritedFlags.clipRule = initialClipRule();
455     m_inheritedFlags.colorRendering = initialColorRendering();
456     m_inheritedFlags.fillRule = initialFillRule();
457     m_inheritedFlags.shapeRendering = initialShapeRendering();
458     m_inheritedFlags.textAnchor = initialTextAnchor();
459     m_inheritedFlags.colorInterpolation = initialColorInterpolation();
460     m_inheritedFlags.colorInterpolationFilters = initialColorInterpolationFilters();
461     m_inheritedFlags.glyphOrientationHorizontal = initialGlyphOrientationHorizontal();
462     m_inheritedFlags.glyphOrientationVertical = initialGlyphOrientationVertical();
463
464     m_nonInheritedFlags.flags = 0;
465     m_nonInheritedFlags.flagBits.alignmentBaseline = initialAlignmentBaseline();
466     m_nonInheritedFlags.flagBits.dominantBaseline = initialDominantBaseline();
467     m_nonInheritedFlags.flagBits.baselineShift = initialBaselineShift();
468     m_nonInheritedFlags.flagBits.vectorEffect = initialVectorEffect();
469     m_nonInheritedFlags.flagBits.bufferedRendering = initialBufferedRendering();
470     m_nonInheritedFlags.flagBits.maskType = initialMaskType();
471 }
472
473 inline bool SVGRenderStyle::InheritedFlags::operator==(const InheritedFlags& other) const
474 {
475     return colorRendering == other.colorRendering
476         && shapeRendering == other.shapeRendering
477         && clipRule == other.clipRule
478         && fillRule == other.fillRule
479         && textAnchor == other.textAnchor
480         && colorInterpolation == other.colorInterpolation
481         && colorInterpolationFilters == other.colorInterpolationFilters
482         && glyphOrientationHorizontal == other.glyphOrientationHorizontal
483         && glyphOrientationVertical == other.glyphOrientationVertical;
484 }
485
486 } // namespace WebCore