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