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 #if ENABLE(SVG) 31 #include "SVGRenderStyle.h" 32 33 #include "CSSPrimitiveValue.h" 34 #include "CSSValueList.h" 35 #include "IntRect.h" 36 #include "NodeRenderStyle.h" 37 #include "SVGStyledElement.h" 38 39 using namespace std; 40 41 namespace WebCore { 42 43 SVGRenderStyle::SVGRenderStyle() 44 { 45 static SVGRenderStyle* defaultStyle = new SVGRenderStyle(CreateDefault); 46 47 fill = defaultStyle->fill; 48 stroke = defaultStyle->stroke; 49 text = defaultStyle->text; 50 stops = defaultStyle->stops; 51 misc = defaultStyle->misc; 52 shadowSVG = defaultStyle->shadowSVG; 53 inheritedResources = defaultStyle->inheritedResources; 54 resources = defaultStyle->resources; 55 56 setBitDefaults(); 57 } 58 59 SVGRenderStyle::SVGRenderStyle(CreateDefaultType) 60 { 61 setBitDefaults(); 62 63 fill.init(); 64 stroke.init(); 65 text.init(); 66 stops.init(); 67 misc.init(); 68 shadowSVG.init(); 69 inheritedResources.init(); 70 resources.init(); 71 } 72 73 SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other) 74 : RefCounted<SVGRenderStyle>() 75 { 76 fill = other.fill; 77 stroke = other.stroke; 78 text = other.text; 79 stops = other.stops; 80 misc = other.misc; 81 shadowSVG = other.shadowSVG; 82 inheritedResources = other.inheritedResources; 83 resources = other.resources; 84 85 svg_inherited_flags = other.svg_inherited_flags; 86 svg_noninherited_flags = other.svg_noninherited_flags; 87 } 88 89 SVGRenderStyle::~SVGRenderStyle() 90 { 91 } 92 93 bool SVGRenderStyle::operator==(const SVGRenderStyle& other) const 94 { 95 return fill == other.fill 96 && stroke == other.stroke 97 && text == other.text 98 && stops == other.stops 99 && misc == other.misc 100 && shadowSVG == other.shadowSVG 101 && inheritedResources == other.inheritedResources 102 && resources == other.resources 103 && svg_inherited_flags == other.svg_inherited_flags 104 && svg_noninherited_flags == other.svg_noninherited_flags; 105 } 106 107 bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const 108 { 109 return fill != other->fill 110 || stroke != other->stroke 111 || text != other->text 112 || inheritedResources != other->inheritedResources 113 || svg_inherited_flags != other->svg_inherited_flags; 114 } 115 116 void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent) 117 { 118 if (!svgInheritParent) 119 return; 120 121 fill = svgInheritParent->fill; 122 stroke = svgInheritParent->stroke; 123 text = svgInheritParent->text; 124 inheritedResources = svgInheritParent->inheritedResources; 125 126 svg_inherited_flags = svgInheritParent->svg_inherited_flags; 127 } 128 129 StyleDifference SVGRenderStyle::diff(const SVGRenderStyle* other) const 130 { 131 // NOTE: All comparisions that may return StyleDifferenceLayout have to go before those who return StyleDifferenceRepaint 132 133 // If kerning changes, we need a relayout, to force SVGCharacterData to be recalculated in the SVGRootInlineBox. 134 if (text != other->text) 135 return StyleDifferenceLayout; 136 137 // If resources change, we need a relayout, as the presence of resources influences the repaint rect. 138 if (resources != other->resources) 139 return StyleDifferenceLayout; 140 141 // If markers change, we need a relayout, as marker boundaries are cached in RenderSVGPath. 142 if (inheritedResources != other->inheritedResources) 143 return StyleDifferenceLayout; 144 145 // All text related properties influence layout. 146 if (svg_inherited_flags._textAnchor != other->svg_inherited_flags._textAnchor 147 || svg_inherited_flags._writingMode != other->svg_inherited_flags._writingMode 148 || svg_inherited_flags._glyphOrientationHorizontal != other->svg_inherited_flags._glyphOrientationHorizontal 149 || svg_inherited_flags._glyphOrientationVertical != other->svg_inherited_flags._glyphOrientationVertical 150 || svg_noninherited_flags.f._alignmentBaseline != other->svg_noninherited_flags.f._alignmentBaseline 151 || svg_noninherited_flags.f._dominantBaseline != other->svg_noninherited_flags.f._dominantBaseline 152 || svg_noninherited_flags.f._baselineShift != other->svg_noninherited_flags.f._baselineShift) 153 return StyleDifferenceLayout; 154 155 // Text related properties influence layout. 156 bool miscNotEqual = misc != other->misc; 157 if (miscNotEqual && misc->baselineShiftValue != other->misc->baselineShiftValue) 158 return StyleDifferenceLayout; 159 160 // These properties affect the cached stroke bounding box rects. 161 if (svg_inherited_flags._capStyle != other->svg_inherited_flags._capStyle 162 || svg_inherited_flags._joinStyle != other->svg_inherited_flags._joinStyle) 163 return StyleDifferenceLayout; 164 165 // Shadow changes require relayouts, as they affect the repaint rects. 166 if (shadowSVG != other->shadowSVG) 167 return StyleDifferenceLayout; 168 169 // Some stroke properties, requires relayouts, as the cached stroke boundaries need to be recalculated. 170 if (stroke != other->stroke) { 171 if (stroke->width != other->stroke->width 172 || stroke->paint != other->stroke->paint 173 || stroke->miterLimit != other->stroke->miterLimit 174 || stroke->dashArray != other->stroke->dashArray 175 || stroke->dashOffset != other->stroke->dashOffset) 176 return StyleDifferenceLayout; 177 178 // Only the stroke-opacity case remains, where we only need a repaint. 179 ASSERT(stroke->opacity != other->stroke->opacity); 180 return StyleDifferenceRepaint; 181 } 182 183 // NOTE: All comparisions below may only return StyleDifferenceRepaint 184 185 // Painting related properties only need repaints. 186 if (miscNotEqual) { 187 if (misc->floodColor != other->misc->floodColor 188 || misc->floodOpacity != other->misc->floodOpacity 189 || misc->lightingColor != other->misc->lightingColor) 190 return StyleDifferenceRepaint; 191 } 192 193 // If fill changes, we just need to repaint. Fill boundaries are not influenced by this, only by the Path, that RenderSVGPath contains. 194 if (fill != other->fill) 195 return StyleDifferenceRepaint; 196 197 // If gradient stops change, we just need to repaint. Style updates are already handled through RenderSVGGradientSTop. 198 if (stops != other->stops) 199 return StyleDifferenceRepaint; 200 201 // Changes of these flags only cause repaints. 202 if (svg_inherited_flags._colorRendering != other->svg_inherited_flags._colorRendering 203 || svg_inherited_flags._imageRendering != other->svg_inherited_flags._imageRendering 204 || svg_inherited_flags._shapeRendering != other->svg_inherited_flags._shapeRendering 205 || svg_inherited_flags._clipRule != other->svg_inherited_flags._clipRule 206 || svg_inherited_flags._fillRule != other->svg_inherited_flags._fillRule 207 || svg_inherited_flags._colorInterpolation != other->svg_inherited_flags._colorInterpolation 208 || svg_inherited_flags._colorInterpolationFilters != other->svg_inherited_flags._colorInterpolationFilters) 209 return StyleDifferenceRepaint; 210 211 // FIXME: vector-effect is not taken into account in the layout-phase. Once this is fixed, we should relayout here. 212 if (svg_noninherited_flags.f._vectorEffect != other->svg_noninherited_flags.f._vectorEffect) 213 return StyleDifferenceRepaint; 214 215 return StyleDifferenceEqual; 216 } 217 218 } 219 220 #endif // ENABLE(SVG) 221