1/*
2    Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
3                  2004, 2005 Rob Buis <buis@kde.org>
4
5    Based on khtml code by:
6    Copyright (C) 1999 Antti Koivisto (koivisto@kde.org)
7    Copyright (C) 1999-2003 Lars Knoll (knoll@kde.org)
8    Copyright (C) 2002-2003 Dirk Mueller (mueller@kde.org)
9    Copyright (C) 2002 Apple Computer, Inc.
10
11    This library is free software; you can redistribute it and/or
12    modify it under the terms of the GNU Library General Public
13    License as published by the Free Software Foundation; either
14    version 2 of the License, or (at your option) any later version.
15
16    This library is distributed in the hope that it will be useful,
17    but WITHOUT ANY WARRANTY; without even the implied warranty of
18    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19    Library General Public License for more details.
20
21    You should have received a copy of the GNU Library General Public License
22    along with this library; see the file COPYING.LIB.  If not, write to
23    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
24    Boston, MA 02110-1301, USA.
25*/
26
27#include "config.h"
28#if ENABLE(SVG)
29#include "SVGRenderStyle.h"
30
31#include "CSSPrimitiveValue.h"
32#include "CSSValueList.h"
33#include "IntRect.h"
34#include "NodeRenderStyle.h"
35#include "RenderObject.h"
36#include "RenderStyle.h"
37#include "SVGStyledElement.h"
38
39using namespace std;
40
41namespace WebCore {
42
43SVGRenderStyle::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    clip = defaultStyle->clip;
52    mask = defaultStyle->mask;
53    misc = defaultStyle->misc;
54    markers = defaultStyle->markers;
55    shadowSVG = defaultStyle->shadowSVG;
56
57    setBitDefaults();
58}
59
60SVGRenderStyle::SVGRenderStyle(CreateDefaultType)
61{
62    setBitDefaults();
63
64    fill.init();
65    stroke.init();
66    text.init();
67    stops.init();
68    clip.init();
69    mask.init();
70    misc.init();
71    markers.init();
72    shadowSVG.init();
73}
74
75SVGRenderStyle::SVGRenderStyle(const SVGRenderStyle& other)
76    : RefCounted<SVGRenderStyle>()
77{
78    fill = other.fill;
79    stroke = other.stroke;
80    text = other.text;
81    stops = other.stops;
82    clip = other.clip;
83    mask = other.mask;
84    misc = other.misc;
85    markers = other.markers;
86    shadowSVG = other.shadowSVG;
87
88    svg_inherited_flags = other.svg_inherited_flags;
89    svg_noninherited_flags = other.svg_noninherited_flags;
90}
91
92SVGRenderStyle::~SVGRenderStyle()
93{
94}
95
96bool SVGRenderStyle::operator==(const SVGRenderStyle& o) const
97{
98    return (fill == o.fill && stroke == o.stroke && text == o.text &&
99        stops == o.stops && clip == o.clip && mask == o.mask &&
100        misc == o.misc && markers == o.markers && shadowSVG == o.shadowSVG &&
101        svg_inherited_flags == o.svg_inherited_flags &&
102        svg_noninherited_flags == o.svg_noninherited_flags);
103}
104
105bool SVGRenderStyle::inheritedNotEqual(const SVGRenderStyle* other) const
106{
107    return (fill != other->fill
108            || stroke != other->stroke
109            || markers != other->markers
110            || text != other->text
111            || svg_inherited_flags != other->svg_inherited_flags);
112}
113
114void SVGRenderStyle::inheritFrom(const SVGRenderStyle* svgInheritParent)
115{
116    if (!svgInheritParent)
117        return;
118
119    fill = svgInheritParent->fill;
120    stroke = svgInheritParent->stroke;
121    markers = svgInheritParent->markers;
122    text = svgInheritParent->text;
123
124    svg_inherited_flags = svgInheritParent->svg_inherited_flags;
125}
126
127float SVGRenderStyle::cssPrimitiveToLength(const RenderObject* item, CSSValue* value, float defaultValue)
128{
129    CSSPrimitiveValue* primitive = static_cast<CSSPrimitiveValue*>(value);
130
131    unsigned short cssType = (primitive ? primitive->primitiveType() : (unsigned short) CSSPrimitiveValue::CSS_UNKNOWN);
132    if (!(cssType > CSSPrimitiveValue::CSS_UNKNOWN && cssType <= CSSPrimitiveValue::CSS_PC))
133        return defaultValue;
134
135    if (cssType == CSSPrimitiveValue::CSS_PERCENTAGE) {
136        SVGStyledElement* element = static_cast<SVGStyledElement*>(item->node());
137        SVGElement* viewportElement = (element ? element->viewportElement() : 0);
138        if (viewportElement) {
139            float result = primitive->getFloatValue() / 100.0f;
140            return SVGLength::PercentageOfViewport(result, element, LengthModeOther);
141        }
142    }
143
144    return primitive->computeLengthFloat(const_cast<RenderStyle*>(item->style()), item->document()->documentElement()->renderStyle());
145}
146
147
148static void getSVGShadowExtent(ShadowData* shadow, int& top, int& right, int& bottom, int& left)
149{
150    top = 0;
151    right = 0;
152    bottom = 0;
153    left = 0;
154
155    int blurAndSpread = shadow->blur + shadow->spread;
156
157    top = min(top, shadow->y - blurAndSpread);
158    right = max(right, shadow->x + blurAndSpread);
159    bottom = max(bottom, shadow->y + blurAndSpread);
160    left = min(left, shadow->x - blurAndSpread);
161}
162
163void SVGRenderStyle::inflateForShadow(IntRect& repaintRect) const
164{
165    ShadowData* svgShadow = shadow();
166    if (!svgShadow)
167        return;
168
169    FloatRect repaintFloatRect = FloatRect(repaintRect);
170    inflateForShadow(repaintFloatRect);
171    repaintRect = enclosingIntRect(repaintFloatRect);
172}
173
174void SVGRenderStyle::inflateForShadow(FloatRect& repaintRect) const
175{
176    ShadowData* svgShadow = shadow();
177    if (!svgShadow)
178        return;
179
180    int shadowTop;
181    int shadowRight;
182    int shadowBottom;
183    int shadowLeft;
184    getSVGShadowExtent(svgShadow, shadowTop, shadowRight, shadowBottom, shadowLeft);
185
186    int overflowLeft = repaintRect.x() + shadowLeft;
187    int overflowRight = repaintRect.right() + shadowRight;
188    int overflowTop = repaintRect.y() + shadowTop;
189    int overflowBottom = repaintRect.bottom() + shadowBottom;
190
191    repaintRect.setX(overflowLeft);
192    repaintRect.setY(overflowTop);
193    repaintRect.setWidth(overflowRight - overflowLeft);
194    repaintRect.setHeight(overflowBottom - overflowTop);
195}
196
197}
198
199#endif // ENABLE(SVG)
200
201// vim:ts=4:noet
202