1 /* 2 Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann (at) kde.org> 3 2004, 2005, 2010 Rob Buis <buis (at) kde.org> 4 Copyright (C) Research In Motion Limited 2010. All rights reserved. 5 6 Based on khtml code by: 7 Copyright (C) 1999 Antti Koivisto (koivisto (at) kde.org) 8 Copyright (C) 1999-2003 Lars Knoll (knoll (at) kde.org) 9 Copyright (C) 2002-2003 Dirk Mueller (mueller (at) kde.org) 10 Copyright (C) 2002 Apple Computer, Inc. 11 12 This library is free software; you can redistribute it and/or 13 modify it under the terms of the GNU Library General Public 14 License as published by the Free Software Foundation; either 15 version 2 of the License, or (at your option) any later version. 16 17 This library is distributed in the hope that it will be useful, 18 but WITHOUT ANY WARRANTY; without even the implied warranty of 19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 Library General Public License for more details. 21 22 You should have received a copy of the GNU Library General Public License 23 along with this library; see the file COPYING.LIB. If not, write to 24 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 25 Boston, MA 02110-1301, USA. 26 */ 27 28 #include "config.h" 29 30 #include "core/rendering/style/SVGRenderStyle.h" 31 32 namespace blink { 33 34 SVGRenderStyle::SVGRenderStyle() 35 { 36 static SVGRenderStyle* defaultStyle = new SVGRenderStyle(CreateDefault); 37 38 fill = defaultStyle->fill; 39 stroke = defaultStyle->stroke; 40 stops = defaultStyle->stops; 41 misc = defaultStyle->misc; 42 inheritedResources = defaultStyle->inheritedResources; 43 resources = defaultStyle->resources; 44 45 setBitDefaults(); 46 } 47 48 SVGRenderStyle::SVGRenderStyle(CreateDefaultType) 49 { 50 setBitDefaults(); 51 52 fill.init(); 53 stroke.init(); 54 stops.init(); 55 misc.init(); 56 inheritedResources.init(); 57 resources.init(); 58 } 59 60 SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other) 61 : RefCounted<SVGRenderStyle>() 62 { 63 fill = other.fill; 64 stroke = other.stroke; 65 stops = other.stops; 66 misc = other.misc; 67 inheritedResources = other.inheritedResources; 68 resources = other.resources; 69 70 svg_inherited_flags = other.svg_inherited_flags; 71 svg_noninherited_flags = other.svg_noninherited_flags; 72 } 73 74 SVGRenderStyle::~SVGRenderStyle() 75 { 76 } 77 78 bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const 79 { 80 return fill == other.fill 81 && stroke == other.stroke 82 && stops == other.stops 83 && misc == other.misc 84 && inheritedResources == other.inheritedResources 85 && resources == other.resources 86 && svg_inherited_flags == other.svg_inherited_flags 87 && svg_noninherited_flags == other.svg_noninherited_flags; 88 } 89 90 bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const 91 { 92 return fill != other->fill 93 || stroke != other->stroke 94 || inheritedResources != other->inheritedResources 95 || svg_inherited_flags != other->svg_inherited_flags; 96 } 97 98 void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent) 99 { 100 if (!svgInheritParent) 101 return; 102 103 fill = svgInheritParent->fill; 104 stroke = svgInheritParent->stroke; 105 inheritedResources = svgInheritParent->inheritedResources; 106 107 svg_inherited_flags = svgInheritParent->svg_inherited_flags; 108 } 109 110 void SVGRenderStyle::copyNonInheritedFrom(const SVGRenderStyle* other) 111 { 112 svg_noninherited_flags = other->svg_noninherited_flags; 113 stops = other->stops; 114 misc = other->misc; 115 resources = other->resources; 116 } 117 118 StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const 119 { 120 StyleDifference styleDifference; 121 122 if (diffNeedsLayoutAndPaintInvalidation(other)) { 123 styleDifference.setNeedsFullLayout(); 124 styleDifference.setNeedsPaintInvalidationObject(); 125 } else if (diffNeedsPaintInvalidation(other)) { 126 styleDifference.setNeedsPaintInvalidationObject(); 127 } 128 129 return styleDifference; 130 } 131 132 bool SVGRenderStyle::diffNeedsLayoutAndPaintInvalidation(const SVGRenderStyle* other) const 133 { 134 // If resources change, we need a relayout, as the presence of resources influences the paint invalidation rect. 135 if (resources != other->resources) 136 return true; 137 138 // If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath. 139 if (inheritedResources != other->inheritedResources) 140 return true; 141 142 // All text related properties influence layout. 143 if (svg_inherited_flags._textAnchor != other->svg_inherited_flags._textAnchor 144 || svg_inherited_flags._writingMode != other->svg_inherited_flags._writingMode 145 || svg_inherited_flags._glyphOrientationHorizontal != other->svg_inherited_flags._glyphOrientationHorizontal 146 || svg_inherited_flags._glyphOrientationVertical != other->svg_inherited_flags._glyphOrientationVertical 147 || svg_noninherited_flags.f._alignmentBaseline != other->svg_noninherited_flags.f._alignmentBaseline 148 || svg_noninherited_flags.f._dominantBaseline != other->svg_noninherited_flags.f._dominantBaseline 149 || svg_noninherited_flags.f._baselineShift != other->svg_noninherited_flags.f._baselineShift) 150 return true; 151 152 // Text related properties influence layout. 153 if (misc->baselineShiftValue != other->misc->baselineShiftValue) 154 return true; 155 156 // These properties affect the cached stroke bounding box rects. 157 if (svg_inherited_flags._capStyle != other->svg_inherited_flags._capStyle 158 || svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle) 159 return true; 160 161 // vector-effect changes require a re-layout. 162 if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect) 163 return true; 164 165 // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated. 166 if (stroke.get() != other->stroke.get()) { 167 if (stroke->width != other->stroke->width 168 || stroke->paintType != other->stroke->paintType 169 || stroke->paintColor != other->stroke->paintColor 170 || stroke->paintUri != other->stroke->paintUri 171 || stroke->miterLimit != other->stroke->miterLimit 172 || stroke->dashArray != other->stroke->dashArray 173 || stroke->dashOffset != other->stroke->dashOffset 174 || stroke->visitedLinkPaintColor != other->stroke->visitedLinkPaintColor 175 || stroke->visitedLinkPaintUri != other->stroke->visitedLinkPaintUri 176 || stroke->visitedLinkPaintType != other->stroke->visitedLinkPaintType) 177 return true; 178 } 179 180 return false; 181 } 182 183 bool SVGRenderStyle::diffNeedsPaintInvalidation(const SVGRenderStyle* other) const 184 { 185 if (stroke->opacity != other->stroke->opacity) 186 return true; 187 188 // Painting related properties only need paint invalidation. 189 if (misc.get() != other->misc.get()) { 190 if (misc->floodColor != other->misc->floodColor 191 || misc->floodOpacity != other->misc->floodOpacity 192 || misc->lightingColor != other->misc->lightingColor) 193 return true; 194 } 195 196 // If fill changes, we just need to issue paint invalidations. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains. 197 if (fill.get() != other->fill.get()) { 198 if (fill->paintType != other->fill->paintType 199 || fill->paintColor != other->fill->paintColor 200 || fill->paintUri != other->fill->paintUri 201 || fill->opacity != other->fill->opacity) 202 return true; 203 } 204 205 // If gradient stops change, we just need to issue paint invalidations. Style updates are already handled through RenderSVGGradientSTop. 206 if (stops != other->stops) 207 return true; 208 209 // Changes of these flags only cause paint invalidations. 210 if (svg_inherited_flags._colorRendering != other->svg_inherited_flags._colorRendering 211 || svg_inherited_flags._shapeRendering != other->svg_inherited_flags._shapeRendering 212 || svg_inherited_flags._clipRule != other->svg_inherited_flags._clipRule 213 || svg_inherited_flags._fillRule != other->svg_inherited_flags._fillRule 214 || svg_inherited_flags._colorInterpolation != other->svg_inherited_flags._colorInterpolation 215 || svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._colorInterpolationFilters 216 || svg_inherited_flags._paintOrder != other->svg_inherited_flags._paintOrder) 217 return true; 218 219 if (svg_noninherited_flags.f.bufferedRendering != other->svg_noninherited_flags.f.bufferedRendering) 220 return true; 221 222 if (svg_noninherited_flags.f.maskType != other->svg_noninherited_flags.f.maskType) 223 return true; 224 225 return false; 226 } 227 228 EPaintOrderType SVGRenderStyle::paintOrderType(unsigned index) const 229 { 230 ASSERT(index < ((1 << kPaintOrderBitwidth)-1)); 231 unsigned pt = (paintOrder() >> (kPaintOrderBitwidth*index)) & ((1u << kPaintOrderBitwidth) - 1); 232 return (EPaintOrderType)pt; 233 } 234 235 } 236