1 /* 2 Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann (at) kde.org> 3 2004, 2005 Rob Buis <buis (at) 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 #include "bindings/v8/ExceptionStatePlaceholder.h" 27 #include "core/css/CSSValueList.h" 28 #include "core/rendering/style/DataRef.h" 29 #include "core/rendering/style/RenderStyleConstants.h" 30 #include "core/rendering/style/SVGRenderStyleDefs.h" 31 #include "core/rendering/style/StyleDifference.h" 32 #include "core/svg/SVGPaint.h" 33 #include "platform/graphics/GraphicsTypes.h" 34 #include "platform/graphics/Path.h" 35 36 namespace WebCore { 37 38 class SVGRenderStyle : public RefCounted<SVGRenderStyle> { 39 public: 40 static PassRefPtr<SVGRenderStyle> create() { return adoptRef(new SVGRenderStyle); } 41 PassRefPtr<SVGRenderStyle> copy() const { return adoptRef(new SVGRenderStyle(*this));} 42 ~SVGRenderStyle(); 43 44 bool inheritedNotEqual(const SVGRenderStyle*) const; 45 void inheritFrom(const SVGRenderStyle*); 46 void copyNonInheritedFrom(const SVGRenderStyle*); 47 48 StyleDifference diff(const SVGRenderStyle*) const; 49 50 bool operator==(const SVGRenderStyle&) const; 51 bool operator!=(const SVGRenderStyle& o) const { return !(*this == o); } 52 53 // Initial values for all the properties 54 static EAlignmentBaseline initialAlignmentBaseline() { return AB_AUTO; } 55 static EDominantBaseline initialDominantBaseline() { return DB_AUTO; } 56 static EBaselineShift initialBaselineShift() { return BS_BASELINE; } 57 static EVectorEffect initialVectorEffect() { return VE_NONE; } 58 static EBufferedRendering initialBufferedRendering() { return BR_AUTO; } 59 static LineCap initialCapStyle() { return ButtCap; } 60 static WindRule initialClipRule() { return RULE_NONZERO; } 61 static EColorInterpolation initialColorInterpolation() { return CI_SRGB; } 62 static EColorInterpolation initialColorInterpolationFilters() { return CI_LINEARRGB; } 63 static EColorRendering initialColorRendering() { return CR_AUTO; } 64 static WindRule initialFillRule() { return RULE_NONZERO; } 65 static LineJoin initialJoinStyle() { return MiterJoin; } 66 static EShapeRendering initialShapeRendering() { return SR_AUTO; } 67 static ETextAnchor initialTextAnchor() { return TA_START; } 68 static SVGWritingMode initialWritingMode() { return WM_LRTB; } 69 static EGlyphOrientation initialGlyphOrientationHorizontal() { return GO_0DEG; } 70 static EGlyphOrientation initialGlyphOrientationVertical() { return GO_AUTO; } 71 static float initialFillOpacity() { return 1; } 72 static SVGPaint::SVGPaintType initialFillPaintType() { return SVGPaint::SVG_PAINTTYPE_RGBCOLOR; } 73 static Color initialFillPaintColor() { return Color::black; } 74 static String initialFillPaintUri() { return String(); } 75 static float initialStrokeOpacity() { return 1; } 76 static SVGPaint::SVGPaintType initialStrokePaintType() { return SVGPaint::SVG_PAINTTYPE_NONE; } 77 static Color initialStrokePaintColor() { return Color(); } 78 static String initialStrokePaintUri() { return String(); } 79 static PassRefPtr<SVGLengthList> initialStrokeDashArray() { return SVGLengthList::create(); } 80 static float initialStrokeMiterLimit() { return 4; } 81 static float initialStopOpacity() { return 1; } 82 static Color initialStopColor() { return Color(0, 0, 0); } 83 static float initialFloodOpacity() { return 1; } 84 static Color initialFloodColor() { return Color(0, 0, 0); } 85 static Color initialLightingColor() { return Color(255, 255, 255); } 86 static const AtomicString& initialClipperResource() { return nullAtom; } 87 static const AtomicString& initialFilterResource() { return nullAtom; } 88 static const AtomicString& initialMaskerResource() { return nullAtom; } 89 static const AtomicString& initialMarkerStartResource() { return nullAtom; } 90 static const AtomicString& initialMarkerMidResource() { return nullAtom; } 91 static const AtomicString& initialMarkerEndResource() { return nullAtom; } 92 static EMaskType initialMaskType() { return MT_LUMINANCE; } 93 static EPaintOrder initialPaintOrder() { return PO_NORMAL; } 94 95 static PassRefPtr<SVGLength> initialBaselineShiftValue() 96 { 97 RefPtr<SVGLength> length = SVGLength::create(); 98 length->newValueSpecifiedUnits(LengthTypeNumber, 0); 99 return length.release(); 100 } 101 102 static PassRefPtr<SVGLength> initialStrokeDashOffset() 103 { 104 RefPtr<SVGLength> length = SVGLength::create(); 105 length->newValueSpecifiedUnits(LengthTypeNumber, 0); 106 return length.release(); 107 } 108 109 static PassRefPtr<SVGLength> initialStrokeWidth() 110 { 111 RefPtr<SVGLength> length = SVGLength::create(); 112 length->newValueSpecifiedUnits(LengthTypeNumber, 1); 113 return length.release(); 114 } 115 116 // SVG CSS Property setters 117 void setAlignmentBaseline(EAlignmentBaseline val) { svg_noninherited_flags.f._alignmentBaseline = val; } 118 void setDominantBaseline(EDominantBaseline val) { svg_noninherited_flags.f._dominantBaseline = val; } 119 void setBaselineShift(EBaselineShift val) { svg_noninherited_flags.f._baselineShift = val; } 120 void setVectorEffect(EVectorEffect val) { svg_noninherited_flags.f._vectorEffect = val; } 121 void setBufferedRendering(EBufferedRendering val) { svg_noninherited_flags.f.bufferedRendering = val; } 122 void setCapStyle(LineCap val) { svg_inherited_flags._capStyle = val; } 123 void setClipRule(WindRule val) { svg_inherited_flags._clipRule = val; } 124 void setColorInterpolation(EColorInterpolation val) { svg_inherited_flags._colorInterpolation = val; } 125 void setColorInterpolationFilters(EColorInterpolation val) { svg_inherited_flags._colorInterpolationFilters = val; } 126 void setColorRendering(EColorRendering val) { svg_inherited_flags._colorRendering = val; } 127 void setFillRule(WindRule val) { svg_inherited_flags._fillRule = val; } 128 void setJoinStyle(LineJoin val) { svg_inherited_flags._joinStyle = val; } 129 void setShapeRendering(EShapeRendering val) { svg_inherited_flags._shapeRendering = val; } 130 void setTextAnchor(ETextAnchor val) { svg_inherited_flags._textAnchor = val; } 131 void setWritingMode(SVGWritingMode val) { svg_inherited_flags._writingMode = val; } 132 void setGlyphOrientationHorizontal(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationHorizontal = val; } 133 void setGlyphOrientationVertical(EGlyphOrientation val) { svg_inherited_flags._glyphOrientationVertical = val; } 134 void setMaskType(EMaskType val) { svg_noninherited_flags.f.maskType = val; } 135 void setPaintOrder(EPaintOrder val) { svg_inherited_flags._paintOrder = (int)val; } 136 137 void setFillOpacity(float obj) 138 { 139 if (!(fill->opacity == obj)) 140 fill.access()->opacity = obj; 141 } 142 143 void setFillPaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false) 144 { 145 if (applyToRegularStyle) { 146 if (!(fill->paintType == type)) 147 fill.access()->paintType = type; 148 if (!(fill->paintColor == color)) 149 fill.access()->paintColor = color; 150 if (!(fill->paintUri == uri)) 151 fill.access()->paintUri = uri; 152 } 153 if (applyToVisitedLinkStyle) { 154 if (!(fill->visitedLinkPaintType == type)) 155 fill.access()->visitedLinkPaintType = type; 156 if (!(fill->visitedLinkPaintColor == color)) 157 fill.access()->visitedLinkPaintColor = color; 158 if (!(fill->visitedLinkPaintUri == uri)) 159 fill.access()->visitedLinkPaintUri = uri; 160 } 161 } 162 163 void setStrokeOpacity(float obj) 164 { 165 if (!(stroke->opacity == obj)) 166 stroke.access()->opacity = obj; 167 } 168 169 void setStrokePaint(SVGPaint::SVGPaintType type, const Color& color, const String& uri, bool applyToRegularStyle = true, bool applyToVisitedLinkStyle = false) 170 { 171 if (applyToRegularStyle) { 172 if (!(stroke->paintType == type)) 173 stroke.access()->paintType = type; 174 if (!(stroke->paintColor == color)) 175 stroke.access()->paintColor = color; 176 if (!(stroke->paintUri == uri)) 177 stroke.access()->paintUri = uri; 178 } 179 if (applyToVisitedLinkStyle) { 180 if (!(stroke->visitedLinkPaintType == type)) 181 stroke.access()->visitedLinkPaintType = type; 182 if (!(stroke->visitedLinkPaintColor == color)) 183 stroke.access()->visitedLinkPaintColor = color; 184 if (!(stroke->visitedLinkPaintUri == uri)) 185 stroke.access()->visitedLinkPaintUri = uri; 186 } 187 } 188 189 void setStrokeDashArray(PassRefPtr<SVGLengthList> obj) 190 { 191 if (!(stroke->dashArray == obj)) 192 stroke.access()->dashArray = obj; 193 } 194 195 void setStrokeMiterLimit(float obj) 196 { 197 if (!(stroke->miterLimit == obj)) 198 stroke.access()->miterLimit = obj; 199 } 200 201 void setStrokeWidth(PassRefPtr<SVGLength> obj) 202 { 203 if (!(stroke->width == obj)) 204 stroke.access()->width = obj; 205 } 206 207 void setStrokeDashOffset(PassRefPtr<SVGLength> obj) 208 { 209 if (!(stroke->dashOffset == obj)) 210 stroke.access()->dashOffset = obj; 211 } 212 213 void setStopOpacity(float obj) 214 { 215 if (!(stops->opacity == obj)) 216 stops.access()->opacity = obj; 217 } 218 219 void setStopColor(const Color& obj) 220 { 221 if (!(stops->color == obj)) 222 stops.access()->color = obj; 223 } 224 225 void setFloodOpacity(float obj) 226 { 227 if (!(misc->floodOpacity == obj)) 228 misc.access()->floodOpacity = obj; 229 } 230 231 void setFloodColor(const Color& obj) 232 { 233 if (!(misc->floodColor == obj)) 234 misc.access()->floodColor = obj; 235 } 236 237 void setLightingColor(const Color& obj) 238 { 239 if (!(misc->lightingColor == obj)) 240 misc.access()->lightingColor = obj; 241 } 242 243 void setBaselineShiftValue(PassRefPtr<SVGLength> obj) 244 { 245 if (!(misc->baselineShiftValue == obj)) 246 misc.access()->baselineShiftValue = obj; 247 } 248 249 // Setters for non-inherited resources 250 void setClipperResource(const AtomicString& obj) 251 { 252 if (!(resources->clipper == obj)) 253 resources.access()->clipper = obj; 254 } 255 256 void setFilterResource(const AtomicString& obj) 257 { 258 if (!(resources->filter == obj)) 259 resources.access()->filter = obj; 260 } 261 262 void setMaskerResource(const AtomicString& obj) 263 { 264 if (!(resources->masker == obj)) 265 resources.access()->masker = obj; 266 } 267 268 // Setters for inherited resources 269 void setMarkerStartResource(const AtomicString& obj) 270 { 271 if (!(inheritedResources->markerStart == obj)) 272 inheritedResources.access()->markerStart = obj; 273 } 274 275 void setMarkerMidResource(const AtomicString& obj) 276 { 277 if (!(inheritedResources->markerMid == obj)) 278 inheritedResources.access()->markerMid = obj; 279 } 280 281 void setMarkerEndResource(const AtomicString& obj) 282 { 283 if (!(inheritedResources->markerEnd == obj)) 284 inheritedResources.access()->markerEnd = obj; 285 } 286 287 // Read accessors for all the properties 288 EAlignmentBaseline alignmentBaseline() const { return (EAlignmentBaseline) svg_noninherited_flags.f._alignmentBaseline; } 289 EDominantBaseline dominantBaseline() const { return (EDominantBaseline) svg_noninherited_flags.f._dominantBaseline; } 290 EBaselineShift baselineShift() const { return (EBaselineShift) svg_noninherited_flags.f._baselineShift; } 291 EVectorEffect vectorEffect() const { return (EVectorEffect) svg_noninherited_flags.f._vectorEffect; } 292 EBufferedRendering bufferedRendering() const { return (EBufferedRendering) svg_noninherited_flags.f.bufferedRendering; } 293 LineCap capStyle() const { return (LineCap) svg_inherited_flags._capStyle; } 294 WindRule clipRule() const { return (WindRule) svg_inherited_flags._clipRule; } 295 EColorInterpolation colorInterpolation() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolation; } 296 EColorInterpolation colorInterpolationFilters() const { return (EColorInterpolation) svg_inherited_flags._colorInterpolationFilters; } 297 EColorRendering colorRendering() const { return (EColorRendering) svg_inherited_flags._colorRendering; } 298 WindRule fillRule() const { return (WindRule) svg_inherited_flags._fillRule; } 299 LineJoin joinStyle() const { return (LineJoin) svg_inherited_flags._joinStyle; } 300 EShapeRendering shapeRendering() const { return (EShapeRendering) svg_inherited_flags._shapeRendering; } 301 ETextAnchor textAnchor() const { return (ETextAnchor) svg_inherited_flags._textAnchor; } 302 SVGWritingMode writingMode() const { return (SVGWritingMode) svg_inherited_flags._writingMode; } 303 EGlyphOrientation glyphOrientationHorizontal() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationHorizontal; } 304 EGlyphOrientation glyphOrientationVertical() const { return (EGlyphOrientation) svg_inherited_flags._glyphOrientationVertical; } 305 float fillOpacity() const { return fill->opacity; } 306 const SVGPaint::SVGPaintType& fillPaintType() const { return fill->paintType; } 307 const Color& fillPaintColor() const { return fill->paintColor; } 308 const String& fillPaintUri() const { return fill->paintUri; } 309 float strokeOpacity() const { return stroke->opacity; } 310 const SVGPaint::SVGPaintType& strokePaintType() const { return stroke->paintType; } 311 const Color& strokePaintColor() const { return stroke->paintColor; } 312 const String& strokePaintUri() const { return stroke->paintUri; } 313 SVGLengthList* strokeDashArray() const { return stroke->dashArray.get(); } 314 float strokeMiterLimit() const { return stroke->miterLimit; } 315 SVGLength* strokeWidth() const { return stroke->width.get(); } 316 SVGLength* strokeDashOffset() const { return stroke->dashOffset.get(); } 317 float stopOpacity() const { return stops->opacity; } 318 const Color& stopColor() const { return stops->color; } 319 float floodOpacity() const { return misc->floodOpacity; } 320 const Color& floodColor() const { return misc->floodColor; } 321 const Color& lightingColor() const { return misc->lightingColor; } 322 SVGLength* baselineShiftValue() const { return misc->baselineShiftValue.get(); } 323 const AtomicString& clipperResource() const { return resources->clipper; } 324 const AtomicString& filterResource() const { return resources->filter; } 325 const AtomicString& maskerResource() const { return resources->masker; } 326 const AtomicString& markerStartResource() const { return inheritedResources->markerStart; } 327 const AtomicString& markerMidResource() const { return inheritedResources->markerMid; } 328 const AtomicString& markerEndResource() const { return inheritedResources->markerEnd; } 329 EMaskType maskType() const { return (EMaskType) svg_noninherited_flags.f.maskType; } 330 EPaintOrder paintOrder() const { return (EPaintOrder) svg_inherited_flags._paintOrder; } 331 EPaintOrderType paintOrderType(unsigned index) const; 332 333 const SVGPaint::SVGPaintType& visitedLinkFillPaintType() const { return fill->visitedLinkPaintType; } 334 const Color& visitedLinkFillPaintColor() const { return fill->visitedLinkPaintColor; } 335 const String& visitedLinkFillPaintUri() const { return fill->visitedLinkPaintUri; } 336 const SVGPaint::SVGPaintType& visitedLinkStrokePaintType() const { return stroke->visitedLinkPaintType; } 337 const Color& visitedLinkStrokePaintColor() const { return stroke->visitedLinkPaintColor; } 338 const String& visitedLinkStrokePaintUri() const { return stroke->visitedLinkPaintUri; } 339 340 // convenience 341 bool hasClipper() const { return !clipperResource().isEmpty(); } 342 bool hasMasker() const { return !maskerResource().isEmpty(); } 343 bool hasFilter() const { return !filterResource().isEmpty(); } 344 bool hasMarkers() const { return !markerStartResource().isEmpty() || !markerMidResource().isEmpty() || !markerEndResource().isEmpty(); } 345 bool hasStroke() const { return strokePaintType() != SVGPaint::SVG_PAINTTYPE_NONE; } 346 bool hasVisibleStroke() const { return hasStroke() && !strokeWidth()->isZero(); } 347 bool hasFill() const { return fillPaintType() != SVGPaint::SVG_PAINTTYPE_NONE; } 348 bool isVerticalWritingMode() const { return writingMode() == WM_TBRL || writingMode() == WM_TB; } 349 350 protected: 351 // inherit 352 struct InheritedFlags { 353 bool operator==(const InheritedFlags& other) const 354 { 355 return (_colorRendering == other._colorRendering) 356 && (_shapeRendering == other._shapeRendering) 357 && (_clipRule == other._clipRule) 358 && (_fillRule == other._fillRule) 359 && (_capStyle == other._capStyle) 360 && (_joinStyle == other._joinStyle) 361 && (_textAnchor == other._textAnchor) 362 && (_colorInterpolation == other._colorInterpolation) 363 && (_colorInterpolationFilters == other._colorInterpolationFilters) 364 && (_writingMode == other._writingMode) 365 && (_glyphOrientationHorizontal == other._glyphOrientationHorizontal) 366 && (_glyphOrientationVertical == other._glyphOrientationVertical) 367 && (_paintOrder == other._paintOrder); 368 } 369 370 bool operator!=(const InheritedFlags& other) const 371 { 372 return !(*this == other); 373 } 374 375 unsigned _colorRendering : 2; // EColorRendering 376 unsigned _shapeRendering : 2; // EShapeRendering 377 unsigned _clipRule : 1; // WindRule 378 unsigned _fillRule : 1; // WindRule 379 unsigned _capStyle : 2; // LineCap 380 unsigned _joinStyle : 2; // LineJoin 381 unsigned _textAnchor : 2; // ETextAnchor 382 unsigned _colorInterpolation : 2; // EColorInterpolation 383 unsigned _colorInterpolationFilters : 2; // EColorInterpolation 384 unsigned _writingMode : 3; // SVGWritingMode 385 unsigned _glyphOrientationHorizontal : 3; // EGlyphOrientation 386 unsigned _glyphOrientationVertical : 3; // EGlyphOrientation 387 unsigned _paintOrder : 6; // EPaintOrder 388 } svg_inherited_flags; 389 390 // don't inherit 391 struct NonInheritedFlags { 392 // 32 bit non-inherited, don't add to the struct, or the operator will break. 393 bool operator==(const NonInheritedFlags &other) const { return _niflags == other._niflags; } 394 bool operator!=(const NonInheritedFlags &other) const { return _niflags != other._niflags; } 395 396 union { 397 struct { 398 unsigned _alignmentBaseline : 4; // EAlignmentBaseline 399 unsigned _dominantBaseline : 4; // EDominantBaseline 400 unsigned _baselineShift : 2; // EBaselineShift 401 unsigned _vectorEffect: 1; // EVectorEffect 402 unsigned bufferedRendering: 2; // EBufferedRendering 403 unsigned maskType: 1; // EMaskType 404 // 18 bits unused 405 } f; 406 uint32_t _niflags; 407 }; 408 } svg_noninherited_flags; 409 410 // inherited attributes 411 DataRef<StyleFillData> fill; 412 DataRef<StyleStrokeData> stroke; 413 DataRef<StyleInheritedResourceData> inheritedResources; 414 415 // non-inherited attributes 416 DataRef<StyleStopData> stops; 417 DataRef<StyleMiscData> misc; 418 DataRef<StyleResourceData> resources; 419 420 private: 421 enum CreateDefaultType { CreateDefault }; 422 423 SVGRenderStyle(); 424 SVGRenderStyle(const SVGRenderStyle&); 425 SVGRenderStyle(CreateDefaultType); // Used to create the default style. 426 427 bool diffNeedsLayoutAndRepaint(const SVGRenderStyle* other) const; 428 bool diffNeedsRepaint(const SVGRenderStyle* other) const; 429 430 void setBitDefaults() 431 { 432 svg_inherited_flags._clipRule = initialClipRule(); 433 svg_inherited_flags._colorRendering = initialColorRendering(); 434 svg_inherited_flags._fillRule = initialFillRule(); 435 svg_inherited_flags._shapeRendering = initialShapeRendering(); 436 svg_inherited_flags._textAnchor = initialTextAnchor(); 437 svg_inherited_flags._capStyle = initialCapStyle(); 438 svg_inherited_flags._joinStyle = initialJoinStyle(); 439 svg_inherited_flags._colorInterpolation = initialColorInterpolation(); 440 svg_inherited_flags._colorInterpolationFilters = initialColorInterpolationFilters(); 441 svg_inherited_flags._writingMode = initialWritingMode(); 442 svg_inherited_flags._glyphOrientationHorizontal = initialGlyphOrientationHorizontal(); 443 svg_inherited_flags._glyphOrientationVertical = initialGlyphOrientationVertical(); 444 svg_inherited_flags._paintOrder = initialPaintOrder(); 445 446 svg_noninherited_flags._niflags = 0; 447 svg_noninherited_flags.f._alignmentBaseline = initialAlignmentBaseline(); 448 svg_noninherited_flags.f._dominantBaseline = initialDominantBaseline(); 449 svg_noninherited_flags.f._baselineShift = initialBaselineShift(); 450 svg_noninherited_flags.f._vectorEffect = initialVectorEffect(); 451 svg_noninherited_flags.f.bufferedRendering = initialBufferedRendering(); 452 svg_noninherited_flags.f.maskType = initialMaskType(); 453 } 454 }; 455 456 } // namespace WebCore 457 458 #endif // SVGRenderStyle_h 459