1 /*
2     Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3                   2004, 2005 Rob Buis <buis@kde.org>
4     Copyright (C) 2005, 2006 Apple Computer, Inc.
5     Copyright (C) Research In Motion Limited 2010. All rights reserved.
6 
7     This library is free software; you can redistribute it and/or
8     modify it under the terms of the GNU Library General Public
9     License as published by the Free Software Foundation; either
10     version 2 of the License, or (at your option) any later version.
11 
12     This library is distributed in the hope that it will be useful,
13     but WITHOUT ANY WARRANTY; without even the implied warranty of
14     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15     Library General Public License for more details.
16 
17     You should have received a copy of the GNU Library General Public License
18     along with this library; see the file COPYING.LIB.  If not, write to
19     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20     Boston, MA 02110-1301, USA.
21 */
22 
23 #ifndef SVGRenderStyle_h
24 #define SVGRenderStyle_h
25 
26 #if ENABLE(SVG)
27 #include "CSSValueList.h"
28 #include "DataRef.h"
29 #include "GraphicsTypes.h"
30 #include "Path.h"
31 #include "RenderStyleConstants.h"
32 #include "SVGPaint.h"
33 #include "SVGRenderStyleDefs.h"
34 
35 namespace WebCore {
36 
37 class FloatRect;
38 class IntRect;
39 class RenderObject;
40 
41 class SVGRenderStyle : public RefCounted<SVGRenderStyle> {
42 public:
create()43     static PassRefPtr<SVGRenderStyle> create() { return adoptRef(new SVGRenderStyle); }
copy()44     PassRefPtr<SVGRenderStyle> copy() const { return adoptRef(new SVGRenderStyle(*this));}
45     ~SVGRenderStyle();
46 
47     bool inheritedNotEqual(const SVGRenderStyle*) const;
48     void inheritFrom(const SVGRenderStyle*);
49 
50     StyleDifference diff(const SVGRenderStyle*) const;
51 
52     bool operator==(const SVGRenderStyle&) const;
53     bool operator!=(const SVGRenderStyle& o) const { return !(*this == o); }
54 
55     // Initial values for all the properties
initialAlignmentBaseline()56     static EAlignmentBaseline initialAlignmentBaseline() { return AB_AUTO; }
initialDominantBaseline()57     static EDominantBaseline initialDominantBaseline() { return DB_AUTO; }
initialBaselineShift()58     static EBaselineShift initialBaselineShift() { return BS_BASELINE; }
initialVectorEffect()59     static EVectorEffect initialVectorEffect() { return VE_NONE; }
initialCapStyle()60     static LineCap initialCapStyle() { return ButtCap; }
initialClipRule()61     static WindRule initialClipRule() { return RULE_NONZERO; }
initialColorInterpolation()62     static EColorInterpolation initialColorInterpolation() { return CI_SRGB; }
initialColorInterpolationFilters()63     static EColorInterpolation initialColorInterpolationFilters() { return CI_LINEARRGB; }
initialColorRendering()64     static EColorRendering initialColorRendering() { return CR_AUTO; }
initialFillRule()65     static WindRule initialFillRule() { return RULE_NONZERO; }
initialImageRendering()66     static EImageRendering initialImageRendering() { return IR_AUTO; }
initialJoinStyle()67     static LineJoin initialJoinStyle() { return MiterJoin; }
initialShapeRendering()68     static EShapeRendering initialShapeRendering() { return SR_AUTO; }
initialTextAnchor()69     static ETextAnchor initialTextAnchor() { return TA_START; }
initialWritingMode()70     static SVGWritingMode initialWritingMode() { return WM_LRTB; }
initialGlyphOrientationHorizontal()71     static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; }
initialGlyphOrientationVertical()72     static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; }
initialFillOpacity()73     static float initialFillOpacity() { return 1; }
initialFillPaintType()74     static SVGPaint::SVGPaintType initialFillPaintType() { return SVGPaint::SVG_PAINTTYPE_RGBCOLOR; }
initialFillPaintColor()75     static Color initialFillPaintColor() { return Color::black; }
initialFillPaintUri()76     static String initialFillPaintUri() { return String(); }
initialStrokeOpacity()77     static float initialStrokeOpacity() { return 1; }
initialStrokePaintType()78     static SVGPaint::SVGPaintType initialStrokePaintType() { return SVGPaint::SVG_PAINTTYPE_NONE; }
initialStrokePaintColor()79     static Color initialStrokePaintColor() { return Color(); }
initialStrokePaintUri()80     static String initialStrokePaintUri() { return String(); }
initialStrokeDashArray()81     static Vector<SVGLength> initialStrokeDashArray() { return Vector<SVGLength>(); }
initialStrokeMiterLimit()82     static float initialStrokeMiterLimit() { return 4; }
initialStopOpacity()83     static float initialStopOpacity() { return 1; }
initialStopColor()84     static Color initialStopColor() { return Color(0, 0, 0); }
initialFloodOpacity()85     static float initialFloodOpacity() { return 1; }
initialFloodColor()86     static Color initialFloodColor() { return Color(0, 0, 0); }
initialLightingColor()87     static Color initialLightingColor() { return Color(255, 255, 255); }
initialShadow()88     static ShadowData* initialShadow() { return 0; }
initialClipperResource()89     static String initialClipperResource() { return String(); }
initialFilterResource()90     static String initialFilterResource() { return String(); }
initialMaskerResource()91     static String initialMaskerResource() { return String(); }
initialMarkerStartResource()92     static String initialMarkerStartResource() { return String(); }
initialMarkerMidResource()93     static String initialMarkerMidResource() { return String(); }
initialMarkerEndResource()94     static String initialMarkerEndResource() { return String(); }
95 
initialBaselineShiftValue()96     static SVGLength initialBaselineShiftValue()
97     {
98         SVGLength length;
99         ExceptionCode ec = 0;
100         length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec);
101         ASSERT(!ec);
102         return length;
103     }
104 
initialKerning()105     static SVGLength initialKerning()
106     {
107         SVGLength length;
108         ExceptionCode ec = 0;
109         length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec);
110         ASSERT(!ec);
111         return length;
112     }
113 
initialStrokeDashOffset()114     static SVGLength initialStrokeDashOffset()
115     {
116         SVGLength length;
117         ExceptionCode ec = 0;
118         length.newValueSpecifiedUnits(LengthTypeNumber, 0, ec);
119         ASSERT(!ec);
120         return length;
121     }
122 
initialStrokeWidth()123     static SVGLength initialStrokeWidth()
124     {
125         SVGLength length;
126         ExceptionCode ec = 0;
127         length.newValueSpecifiedUnits(LengthTypeNumber, 1, ec);
128         ASSERT(!ec);
129         return length;
130     }
131 
132     // SVG CSS Property setters
setAlignmentBaseline(EAlignmentBaseline val)133     void setAlignmentBaseline(EAlignmentBaseline val) { svg_noninherited_flags.f._alignmentBaseline = val; }
setDominantBaseline(EDominantBaseline val)134     void setDominantBaseline(EDominantBaseline val) { svg_noninherited_flags.f._dominantBaseline = val; }
setBaselineShift(EBaselineShift val)135     void setBaselineShift(EBaselineShift val) { svg_noninherited_flags.f._baselineShift = val; }
setVectorEffect(EVectorEffect val)136     void setVectorEffect(EVectorEffect val) { svg_noninherited_flags.f._vectorEffect = val; }
setCapStyle(LineCap val)137     void setCapStyle(LineCap val) { svg_inherited_flags._capStyle = val; }
setClipRule(WindRule val)138     void setClipRule(WindRule val) { svg_inherited_flags._clipRule = val; }
setColorInterpolation(EColorInterpolation val)139     void setColorInterpolation(EColorInterpolation val) { svg_inherited_flags._colorInterpolation = val; }
setColorInterpolationFilters(EColorInterpolation val)140     void setColorInterpolationFilters(EColorInterpolation val) { svg_inherited_flags._colorInterpolationFilters = val; }
setColorRendering(EColorRendering val)141     void setColorRendering(EColorRendering val) { svg_inherited_flags._colorRendering = val; }
setFillRule(WindRule val)142     void setFillRule(WindRule val) { svg_inherited_flags._fillRule = val; }
setImageRendering(EImageRendering val)143     void setImageRendering(EImageRendering val) { svg_inherited_flags._imageRendering = val; }
setJoinStyle(LineJoin val)144     void setJoinStyle(LineJoin val) { svg_inherited_flags._joinStyle = val; }
setShapeRendering(EShapeRendering val)145     void setShapeRendering(EShapeRendering val) { svg_inherited_flags._shapeRendering = val; }
setTextAnchor(ETextAnchor val)146     void setTextAnchor(ETextAnchor val) { svg_inherited_flags._textAnchor = val; }
setWritingMode(SVGWritingMode val)147     void setWritingMode(SVGWritingMode val) { svg_inherited_flags._writingMode = val; }
setGlyphOrientationHorizontal(EGlyphOrientation val)148     void setGlyphOrientationHorizontal(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationHorizontal = val; }
setGlyphOrientationVertical(EGlyphOrientation val)149     void setGlyphOrientationVertical(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationVertical = val; }
150 
setFillOpacity(float obj)151     void setFillOpacity(float obj)
152     {
153         if (!(fill->opacity == obj))
154             fill.access()->opacity = obj;
155     }
156 
setFillPaint(SVGPaint::SVGPaintType type,const Color & color,const String & uri)157     void setFillPaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri)
158     {
159         if (!(fill->paintType == type))
160             fill.access()->paintType = type;
161         if (!(fill->paintColor == color))
162             fill.access()->paintColor = color;
163         if (!(fill->paintUri == uri))
164             fill.access()->paintUri = uri;
165     }
166 
setStrokeOpacity(float obj)167     void setStrokeOpacity(float obj)
168     {
169         if (!(stroke->opacity == obj))
170             stroke.access()->opacity = obj;
171     }
172 
setStrokePaint(SVGPaint::SVGPaintType type,const Color & color,const String & uri)173     void setStrokePaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri)
174     {
175         if (!(stroke->paintType == type))
176             stroke.access()->paintType = type;
177         if (!(stroke->paintColor == color))
178             stroke.access()->paintColor = color;
179         if (!(stroke->paintUri == uri))
180             stroke.access()->paintUri = uri;
181     }
182 
setStrokeDashArray(const Vector<SVGLength> & obj)183     void setStrokeDashArray(const Vector<SVGLength>& obj)
184     {
185         if (!(stroke->dashArray == obj))
186             stroke.access()->dashArray = obj;
187     }
188 
setStrokeMiterLimit(float obj)189     void setStrokeMiterLimit(float obj)
190     {
191         if (!(stroke->miterLimit == obj))
192             stroke.access()->miterLimit = obj;
193     }
194 
setStrokeWidth(const SVGLength & obj)195     void setStrokeWidth(const SVGLength& obj)
196     {
197         if (!(stroke->width == obj))
198             stroke.access()->width = obj;
199     }
200 
setStrokeDashOffset(const SVGLength & obj)201     void setStrokeDashOffset(const SVGLength& obj)
202     {
203         if (!(stroke->dashOffset == obj))
204             stroke.access()->dashOffset = obj;
205     }
206 
setKerning(const SVGLength & obj)207     void setKerning(const SVGLength& obj)
208     {
209         if (!(text->kerning == obj))
210             text.access()->kerning = obj;
211     }
212 
setStopOpacity(float obj)213     void setStopOpacity(float obj)
214     {
215         if (!(stops->opacity == obj))
216             stops.access()->opacity = obj;
217     }
218 
setStopColor(const Color & obj)219     void setStopColor(const Color& obj)
220     {
221         if (!(stops->color == obj))
222             stops.access()->color = obj;
223     }
224 
setFloodOpacity(float obj)225     void setFloodOpacity(float obj)
226     {
227         if (!(misc->floodOpacity == obj))
228             misc.access()->floodOpacity = obj;
229     }
230 
setFloodColor(const Color & obj)231     void setFloodColor(const Color& obj)
232     {
233         if (!(misc->floodColor == obj))
234             misc.access()->floodColor = obj;
235     }
236 
setLightingColor(const Color & obj)237     void setLightingColor(const Color& obj)
238     {
239         if (!(misc->lightingColor == obj))
240             misc.access()->lightingColor = obj;
241     }
242 
setBaselineShiftValue(const SVGLength & obj)243     void setBaselineShiftValue(const SVGLength& obj)
244     {
245         if (!(misc->baselineShiftValue == obj))
246             misc.access()->baselineShiftValue = obj;
247     }
248 
setShadow(PassOwnPtr<ShadowData> obj)249     void setShadow(PassOwnPtr<ShadowData> obj) { shadowSVG.access()->shadow = obj; }
250 
251     // Setters for non-inherited resources
setClipperResource(const String & obj)252     void setClipperResource(const String& obj)
253     {
254         if (!(resources->clipper == obj))
255             resources.access()->clipper = obj;
256     }
257 
setFilterResource(const String & obj)258     void setFilterResource(const String& obj)
259     {
260         if (!(resources->filter == obj))
261             resources.access()->filter = obj;
262     }
263 
setMaskerResource(const String & obj)264     void setMaskerResource(const String& obj)
265     {
266         if (!(resources->masker == obj))
267             resources.access()->masker = obj;
268     }
269 
270     // Setters for inherited resources
setMarkerStartResource(const String & obj)271     void setMarkerStartResource(const String& obj)
272     {
273         if (!(inheritedResources->markerStart == obj))
274             inheritedResources.access()->markerStart = obj;
275     }
276 
setMarkerMidResource(const String & obj)277     void setMarkerMidResource(const String& obj)
278     {
279         if (!(inheritedResources->markerMid == obj))
280             inheritedResources.access()->markerMid = obj;
281     }
282 
setMarkerEndResource(const String & obj)283     void setMarkerEndResource(const String& obj)
284     {
285         if (!(inheritedResources->markerEnd == obj))
286             inheritedResources.access()->markerEnd = obj;
287     }
288 
289     // Read accessors for all the properties
alignmentBaseline()290     EAlignmentBaseline alignmentBaseline() const { return (EAlignmentBaseline) svg_noninherited_flags.f._alignmentBaseline; }
dominantBaseline()291     EDominantBaseline dominantBaseline() const { return (EDominantBaseline) svg_noninherited_flags.f._dominantBaseline; }
baselineShift()292     EBaselineShift baselineShift() const { return (EBaselineShift) svg_noninherited_flags.f._baselineShift; }
vectorEffect()293     EVectorEffect vectorEffect() const { return (EVectorEffect) svg_noninherited_flags.f._vectorEffect; }
capStyle()294     LineCap capStyle() const { return (LineCap) svg_inherited_flags._capStyle; }
clipRule()295     WindRule clipRule() const { return (WindRule) svg_inherited_flags._clipRule; }
colorInterpolation()296     EColorInterpolation colorInterpolation() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolation; }
colorInterpolationFilters()297     EColorInterpolation colorInterpolationFilters() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolationFilters; }
colorRendering()298     EColorRendering colorRendering() const { return (EColorRendering) svg_inherited_flags._colorRendering; }
fillRule()299     WindRule fillRule() const { return (WindRule) svg_inherited_flags._fillRule; }
imageRendering()300     EImageRendering imageRendering() const { return (EImageRendering) svg_inherited_flags._imageRendering; }
joinStyle()301     LineJoin joinStyle() const { return (LineJoin) svg_inherited_flags._joinStyle; }
shapeRendering()302     EShapeRendering shapeRendering() const { return (EShapeRendering) svg_inherited_flags._shapeRendering; }
textAnchor()303     ETextAnchor textAnchor() const { return (ETextAnchor) svg_inherited_flags._textAnchor; }
writingMode()304     SVGWritingMode writingMode() const { return (SVGWritingMode) svg_inherited_flags._writingMode; }
glyphOrientationHorizontal()305     EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationHorizontal; }
glyphOrientationVertical()306     EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationVertical; }
fillOpacity()307     float fillOpacity() const { return fill->opacity; }
fillPaintType()308     const SVGPaint::SVGPaintType& fillPaintType() const { return fill->paintType; }
fillPaintColor()309     const Color& fillPaintColor() const { return fill->paintColor; }
fillPaintUri()310     const String& fillPaintUri() const { return fill->paintUri; }
strokeOpacity()311     float strokeOpacity() const { return stroke->opacity; }
strokePaintType()312     const SVGPaint::SVGPaintType& strokePaintType() const { return stroke->paintType; }
strokePaintColor()313     const Color& strokePaintColor() const { return stroke->paintColor; }
strokePaintUri()314     const String& strokePaintUri() const { return stroke->paintUri; }
strokeDashArray()315     Vector<SVGLength> strokeDashArray() const { return stroke->dashArray; }
strokeMiterLimit()316     float strokeMiterLimit() const { return stroke->miterLimit; }
strokeWidth()317     SVGLength strokeWidth() const { return stroke->width; }
strokeDashOffset()318     SVGLength strokeDashOffset() const { return stroke->dashOffset; }
kerning()319     SVGLength kerning() const { return text->kerning; }
stopOpacity()320     float stopOpacity() const { return stops->opacity; }
stopColor()321     Color stopColor() const { return stops->color; }
floodOpacity()322     float floodOpacity() const { return misc->floodOpacity; }
floodColor()323     Color floodColor() const { return misc->floodColor; }
lightingColor()324     Color lightingColor() const { return misc->lightingColor; }
baselineShiftValue()325     SVGLength baselineShiftValue() const { return misc->baselineShiftValue; }
shadow()326     ShadowData* shadow() const { return shadowSVG->shadow.get(); }
clipperResource()327     String clipperResource() const { return resources->clipper; }
filterResource()328     String filterResource() const { return resources->filter; }
maskerResource()329     String maskerResource() const { return resources->masker; }
markerStartResource()330     String markerStartResource() const { return inheritedResources->markerStart; }
markerMidResource()331     String markerMidResource() const { return inheritedResources->markerMid; }
markerEndResource()332     String markerEndResource() const { return inheritedResources->markerEnd; }
333 
334     // convenience
hasClipper()335     bool hasClipper() const { return !clipperResource().isEmpty(); }
hasMasker()336     bool hasMasker() const { return !maskerResource().isEmpty(); }
hasFilter()337     bool hasFilter() const { return !filterResource().isEmpty(); }
hasMarkers()338     bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); }
hasStroke()339     bool hasStroke() const { return strokePaintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
hasFill()340     bool hasFill() const { return fillPaintType() != SVGPaint::SVG_PAINTTYPE_NONE; }
isVerticalWritingMode()341     bool isVerticalWritingMode() const { return writingMode() == WM_TBRL || writingMode() == WM_TB; }
342 
343 protected:
344     // inherit
345     struct InheritedFlags {
346         bool operator==(const InheritedFlags& other) const
347         {
348             return (_colorRendering == other._colorRendering)
349                 && (_imageRendering == other._imageRendering)
350                 && (_shapeRendering == other._shapeRendering)
351                 && (_clipRule == other._clipRule)
352                 && (_fillRule == other._fillRule)
353                 && (_capStyle == other._capStyle)
354                 && (_joinStyle == other._joinStyle)
355                 && (_textAnchor == other._textAnchor)
356                 && (_colorInterpolation == other._colorInterpolation)
357                 && (_colorInterpolationFilters == other._colorInterpolationFilters)
358                 && (_writingMode == other._writingMode)
359                 && (_glyphOrientationHorizontal == other._glyphOrientationHorizontal)
360                 && (_glyphOrientationVertical == other._glyphOrientationVertical);
361         }
362 
363         bool operator!=(const InheritedFlags& other) const
364         {
365             return !(*this == other);
366         }
367 
368         unsigned _colorRendering : 2; // EColorRendering
369         unsigned _imageRendering : 2; // EImageRendering
370         unsigned _shapeRendering : 2; // EShapeRendering
371         unsigned _clipRule : 1; // WindRule
372         unsigned _fillRule : 1; // WindRule
373         unsigned _capStyle : 2; // LineCap
374         unsigned _joinStyle : 2; // LineJoin
375         unsigned _textAnchor : 2; // ETextAnchor
376         unsigned _colorInterpolation : 2; // EColorInterpolation
377         unsigned _colorInterpolationFilters : 2; // EColorInterpolation
378         unsigned _writingMode : 3; // SVGWritingMode
379         unsigned _glyphOrientationHorizontal : 3; // EGlyphOrientation
380         unsigned _glyphOrientationVertical : 3; // EGlyphOrientation
381     } svg_inherited_flags;
382 
383     // don't inherit
384     struct NonInheritedFlags {
385         // 32 bit non-inherited, don't add to the struct, or the operator will break.
386         bool operator==(const NonInheritedFlags &other) const { return _niflags == other._niflags; }
387         bool operator!=(const NonInheritedFlags &other) const { return _niflags != other._niflags; }
388 
389         union {
390             struct {
391                 unsigned _alignmentBaseline : 4; // EAlignmentBaseline
392                 unsigned _dominantBaseline : 4; // EDominantBaseline
393                 unsigned _baselineShift : 2; // EBaselineShift
394                 unsigned _vectorEffect: 1; // EVectorEffect
395                 // 21 bits unused
396             } f;
397             uint32_t _niflags;
398         };
399     } svg_noninherited_flags;
400 
401     // inherited attributes
402     DataRef<StyleFillData> fill;
403     DataRef<StyleStrokeData> stroke;
404     DataRef<StyleTextData> text;
405     DataRef<StyleInheritedResourceData> inheritedResources;
406 
407     // non-inherited attributes
408     DataRef<StyleStopData> stops;
409     DataRef<StyleMiscData> misc;
410     DataRef<StyleShadowSVGData> shadowSVG;
411     DataRef<StyleResourceData> resources;
412 
413 private:
414     enum CreateDefaultType { CreateDefault };
415 
416     SVGRenderStyle();
417     SVGRenderStyle(const SVGRenderStyle&);
418     SVGRenderStyle(CreateDefaultType); // Used to create the default style.
419 
setBitDefaults()420     void setBitDefaults()
421     {
422         svg_inherited_flags._clipRule = initialClipRule();
423         svg_inherited_flags._colorRendering = initialColorRendering();
424         svg_inherited_flags._fillRule = initialFillRule();
425         svg_inherited_flags._imageRendering = initialImageRendering();
426         svg_inherited_flags._shapeRendering = initialShapeRendering();
427         svg_inherited_flags._textAnchor = initialTextAnchor();
428         svg_inherited_flags._capStyle = initialCapStyle();
429         svg_inherited_flags._joinStyle = initialJoinStyle();
430         svg_inherited_flags._colorInterpolation = initialColorInterpolation();
431         svg_inherited_flags._colorInterpolationFilters = initialColorInterpolationFilters();
432         svg_inherited_flags._writingMode = initialWritingMode();
433         svg_inherited_flags._glyphOrientationHorizontal = initialGlyphOrientationHorizontal();
434         svg_inherited_flags._glyphOrientationVertical = initialGlyphOrientationVertical();
435 
436         svg_noninherited_flags._niflags = 0;
437         svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline();
438         svg_noninherited_flags.f._dominantBaseline = initialDominantBaseline();
439         svg_noninherited_flags.f._baselineShift = initialBaselineShift();
440         svg_noninherited_flags.f._vectorEffect = initialVectorEffect();
441     }
442 };
443 
444 } // namespace WebCore
445 
446 #endif // ENABLE(SVG)
447 #endif // SVGRenderStyle_h
448