2 Copyright (C) 2005 Apple Computer, Inc.
3 Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
4 2004, 2005, 2008 Rob Buis <buis@kde.org>
5 Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
7 Based on khtml css code by:
8 Copyright(C) 1999-2003 Lars Knoll(knoll@kde.org)
9 (C) 2003 Apple Computer, Inc.
10 (C) 2004 Allan Sandfeld Jensen(kde@carewolf.com)
11 (C) 2004 Germain Garand(germain@ebooksfrance.org)
13 This library is free software; you can redistribute it and/or
14 modify it under the terms of the GNU Library General Public
15 License as published by the Free Software Foundation; either
16 version 2 of the License, or (at your option) any later version.
18 This library is distributed in the hope that it will be useful,
19 but WITHOUT ANY WARRANTY; without even the implied warranty of
20 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21 Library General Public License for more details.
23 You should have received a copy of the GNU Library General Public License
24 along with this library; see the file COPYING.LIB. If not, write to
25 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
26 Boston, MA 02110-1301, USA.
32 #include "CSSStyleSelector.h"
34 #include "CSSPrimitiveValueMappings.h"
35 #include "CSSPropertyNames.h"
36 #include "CSSValueList.h"
38 #include "ShadowValue.h"
42 #include "SVGRenderStyle.h"
43 #include "SVGRenderStyleDefs.h"
44 #include "SVGStyledElement.h"
45 #include "SVGURIReference.h"
47 #include <wtf/MathExtras.h>
49 #define HANDLE_INHERIT(prop, Prop) \
52 svgstyle->set##Prop(m_parentStyle->svgStyle()->prop());\
56 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
57 HANDLE_INHERIT(prop, Prop) \
59 svgstyle->set##Prop(SVGRenderStyle::initial##Prop());
64 static float roundToNearestGlyphOrientationAngle(float angle
)
66 angle
= fabsf(fmodf(angle
, 360.0f
));
68 if (angle
<= 45.0f
|| angle
> 315.0f
)
70 else if (angle
> 45.0f
&& angle
<= 135.0f
)
72 else if (angle
> 135.0f
&& angle
<= 225.0f
)
78 static int angleToGlyphOrientation(float angle
)
80 angle
= roundToNearestGlyphOrientationAngle(angle
);
84 else if (angle
== 90.0f
)
86 else if (angle
== 180.0f
)
88 else if (angle
== 270.0f
)
94 static Color
colorFromSVGColorCSSValue(CSSValue
* value
, RenderStyle
* style
)
96 ASSERT(value
->isSVGColor());
97 SVGColor
* c
= static_cast<SVGColor
*>(value
);
99 if (c
->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR
)
100 color
= style
->color();
106 void CSSStyleSelector::applySVGProperty(int id
, CSSValue
* value
)
109 CSSPrimitiveValue
* primitiveValue
= 0;
110 if (value
->isPrimitiveValue())
111 primitiveValue
= static_cast<CSSPrimitiveValue
*>(value
);
113 SVGRenderStyle
* svgstyle
= m_style
->accessSVGStyle();
114 unsigned short valueType
= value
->cssValueType();
116 bool isInherit
= m_parentNode
&& valueType
== CSSPrimitiveValue::CSS_INHERIT
;
117 bool isInitial
= valueType
== CSSPrimitiveValue::CSS_INITIAL
|| (!m_parentNode
&& valueType
== CSSPrimitiveValue::CSS_INHERIT
);
119 // What follows is a list that maps the CSS properties into their
120 // corresponding front-end RenderStyle values. Shorthands(e.g. border,
121 // background) occur in this list as well and are only hit when mapping
122 // "inherit" or "initial" into front-end values.
125 // ident only properties
126 case CSSPropertyAlignmentBaseline
:
128 HANDLE_INHERIT_AND_INITIAL(alignmentBaseline
, AlignmentBaseline
)
132 svgstyle
->setAlignmentBaseline(*primitiveValue
);
135 case CSSPropertyBaselineShift
:
137 HANDLE_INHERIT_AND_INITIAL(baselineShift
, BaselineShift
);
141 if (primitiveValue
->getIdent()) {
142 switch (primitiveValue
->getIdent()) {
143 case CSSValueBaseline
:
144 svgstyle
->setBaselineShift(BS_BASELINE
);
147 svgstyle
->setBaselineShift(BS_SUB
);
150 svgstyle
->setBaselineShift(BS_SUPER
);
156 svgstyle
->setBaselineShift(BS_LENGTH
);
157 svgstyle
->setBaselineShiftValue(primitiveValue
);
162 case CSSPropertyKerning
:
164 HANDLE_INHERIT_AND_INITIAL(kerning
, Kerning
);
165 svgstyle
->setKerning(primitiveValue
);
168 case CSSPropertyDominantBaseline
:
170 HANDLE_INHERIT_AND_INITIAL(dominantBaseline
, DominantBaseline
)
172 svgstyle
->setDominantBaseline(*primitiveValue
);
175 case CSSPropertyColorInterpolation
:
177 HANDLE_INHERIT_AND_INITIAL(colorInterpolation
, ColorInterpolation
)
179 svgstyle
->setColorInterpolation(*primitiveValue
);
182 case CSSPropertyColorInterpolationFilters
:
184 HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters
, ColorInterpolationFilters
)
186 svgstyle
->setColorInterpolationFilters(*primitiveValue
);
189 case CSSPropertyColorRendering
:
191 HANDLE_INHERIT_AND_INITIAL(colorRendering
, ColorRendering
)
193 svgstyle
->setColorRendering(*primitiveValue
);
196 case CSSPropertyClipRule
:
198 HANDLE_INHERIT_AND_INITIAL(clipRule
, ClipRule
)
200 svgstyle
->setClipRule(*primitiveValue
);
203 case CSSPropertyFillRule
:
205 HANDLE_INHERIT_AND_INITIAL(fillRule
, FillRule
)
207 svgstyle
->setFillRule(*primitiveValue
);
210 case CSSPropertyStrokeLinejoin
:
212 HANDLE_INHERIT_AND_INITIAL(joinStyle
, JoinStyle
)
214 svgstyle
->setJoinStyle(*primitiveValue
);
217 case CSSPropertyImageRendering
:
219 HANDLE_INHERIT_AND_INITIAL(imageRendering
, ImageRendering
)
221 svgstyle
->setImageRendering(*primitiveValue
);
224 case CSSPropertyShapeRendering
:
226 HANDLE_INHERIT_AND_INITIAL(shapeRendering
, ShapeRendering
)
228 svgstyle
->setShapeRendering(*primitiveValue
);
231 // end of ident only properties
232 case CSSPropertyFill
:
234 HANDLE_INHERIT_AND_INITIAL(fillPaint
, FillPaint
)
235 if (value
->isSVGPaint())
236 svgstyle
->setFillPaint(static_cast<SVGPaint
*>(value
));
239 case CSSPropertyStroke
:
241 HANDLE_INHERIT_AND_INITIAL(strokePaint
, StrokePaint
)
242 if (value
->isSVGPaint())
243 svgstyle
->setStrokePaint(static_cast<SVGPaint
*>(value
));
247 case CSSPropertyStrokeWidth
:
249 HANDLE_INHERIT_AND_INITIAL(strokeWidth
, StrokeWidth
)
251 svgstyle
->setStrokeWidth(primitiveValue
);
254 case CSSPropertyStrokeDasharray
:
256 HANDLE_INHERIT_AND_INITIAL(strokeDashArray
, StrokeDashArray
)
257 if (value
->isValueList())
258 svgstyle
->setStrokeDashArray(static_cast<CSSValueList
*>(value
));
261 case CSSPropertyStrokeDashoffset
:
263 HANDLE_INHERIT_AND_INITIAL(strokeDashOffset
, StrokeDashOffset
)
265 svgstyle
->setStrokeDashOffset(primitiveValue
);
268 case CSSPropertyFillOpacity
:
270 HANDLE_INHERIT_AND_INITIAL(fillOpacity
, FillOpacity
)
275 int type
= primitiveValue
->primitiveType();
276 if (type
== CSSPrimitiveValue::CSS_PERCENTAGE
)
277 f
= primitiveValue
->getFloatValue() / 100.0f
;
278 else if (type
== CSSPrimitiveValue::CSS_NUMBER
)
279 f
= primitiveValue
->getFloatValue();
283 svgstyle
->setFillOpacity(f
);
286 case CSSPropertyStrokeOpacity
:
288 HANDLE_INHERIT_AND_INITIAL(strokeOpacity
, StrokeOpacity
)
293 int type
= primitiveValue
->primitiveType();
294 if (type
== CSSPrimitiveValue::CSS_PERCENTAGE
)
295 f
= primitiveValue
->getFloatValue() / 100.0f
;
296 else if (type
== CSSPrimitiveValue::CSS_NUMBER
)
297 f
= primitiveValue
->getFloatValue();
301 svgstyle
->setStrokeOpacity(f
);
304 case CSSPropertyStopOpacity
:
306 HANDLE_INHERIT_AND_INITIAL(stopOpacity
, StopOpacity
)
311 int type
= primitiveValue
->primitiveType();
312 if (type
== CSSPrimitiveValue::CSS_PERCENTAGE
)
313 f
= primitiveValue
->getFloatValue() / 100.0f
;
314 else if (type
== CSSPrimitiveValue::CSS_NUMBER
)
315 f
= primitiveValue
->getFloatValue();
319 svgstyle
->setStopOpacity(f
);
322 case CSSPropertyMarkerStart
:
324 HANDLE_INHERIT_AND_INITIAL(startMarker
, StartMarker
)
329 int type
= primitiveValue
->primitiveType();
330 if (type
== CSSPrimitiveValue::CSS_URI
)
331 s
= primitiveValue
->getStringValue();
335 svgstyle
->setStartMarker(SVGURIReference::getTarget(s
));
338 case CSSPropertyMarkerMid
:
340 HANDLE_INHERIT_AND_INITIAL(midMarker
, MidMarker
)
345 int type
= primitiveValue
->primitiveType();
346 if (type
== CSSPrimitiveValue::CSS_URI
)
347 s
= primitiveValue
->getStringValue();
351 svgstyle
->setMidMarker(SVGURIReference::getTarget(s
));
354 case CSSPropertyMarkerEnd
:
356 HANDLE_INHERIT_AND_INITIAL(endMarker
, EndMarker
)
361 int type
= primitiveValue
->primitiveType();
362 if (type
== CSSPrimitiveValue::CSS_URI
)
363 s
= primitiveValue
->getStringValue();
367 svgstyle
->setEndMarker(SVGURIReference::getTarget(s
));
370 case CSSPropertyStrokeLinecap
:
372 HANDLE_INHERIT_AND_INITIAL(capStyle
, CapStyle
)
374 svgstyle
->setCapStyle(*primitiveValue
);
377 case CSSPropertyStrokeMiterlimit
:
379 HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit
, StrokeMiterLimit
)
384 int type
= primitiveValue
->primitiveType();
385 if (type
== CSSPrimitiveValue::CSS_NUMBER
)
386 f
= primitiveValue
->getFloatValue();
390 svgstyle
->setStrokeMiterLimit(f
);
393 case CSSPropertyFilter
:
395 HANDLE_INHERIT_AND_INITIAL(filter
, Filter
)
400 int type
= primitiveValue
->primitiveType();
401 if (type
== CSSPrimitiveValue::CSS_URI
)
402 s
= primitiveValue
->getStringValue();
405 svgstyle
->setFilter(SVGURIReference::getTarget(s
));
408 case CSSPropertyMask
:
410 HANDLE_INHERIT_AND_INITIAL(maskElement
, MaskElement
)
415 int type
= primitiveValue
->primitiveType();
416 if (type
== CSSPrimitiveValue::CSS_URI
)
417 s
= primitiveValue
->getStringValue();
421 svgstyle
->setMaskElement(SVGURIReference::getTarget(s
));
424 case CSSPropertyClipPath
:
426 HANDLE_INHERIT_AND_INITIAL(clipPath
, ClipPath
)
431 int type
= primitiveValue
->primitiveType();
432 if (type
== CSSPrimitiveValue::CSS_URI
)
433 s
= primitiveValue
->getStringValue();
437 svgstyle
->setClipPath(SVGURIReference::getTarget(s
));
440 case CSSPropertyTextAnchor
:
442 HANDLE_INHERIT_AND_INITIAL(textAnchor
, TextAnchor
)
444 svgstyle
->setTextAnchor(*primitiveValue
);
447 case CSSPropertyWritingMode
:
449 HANDLE_INHERIT_AND_INITIAL(writingMode
, WritingMode
)
451 svgstyle
->setWritingMode(*primitiveValue
);
454 case CSSPropertyStopColor
:
456 HANDLE_INHERIT_AND_INITIAL(stopColor
, StopColor
);
457 svgstyle
->setStopColor(colorFromSVGColorCSSValue(value
, m_style
.get()));
460 case CSSPropertyLightingColor
:
462 HANDLE_INHERIT_AND_INITIAL(lightingColor
, LightingColor
);
463 svgstyle
->setLightingColor(colorFromSVGColorCSSValue(value
, m_style
.get()));
466 case CSSPropertyFloodOpacity
:
468 HANDLE_INHERIT_AND_INITIAL(floodOpacity
, FloodOpacity
)
473 int type
= primitiveValue
->primitiveType();
474 if (type
== CSSPrimitiveValue::CSS_PERCENTAGE
)
475 f
= primitiveValue
->getFloatValue() / 100.0f
;
476 else if (type
== CSSPrimitiveValue::CSS_NUMBER
)
477 f
= primitiveValue
->getFloatValue();
481 svgstyle
->setFloodOpacity(f
);
484 case CSSPropertyFloodColor
:
487 svgstyle
->setFloodColor(SVGRenderStyle::initialFloodColor());
490 svgstyle
->setFloodColor(colorFromSVGColorCSSValue(value
, m_style
.get()));
493 case CSSPropertyGlyphOrientationHorizontal
:
495 HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal
, GlyphOrientationHorizontal
)
499 if (primitiveValue
->primitiveType() == CSSPrimitiveValue::CSS_DEG
) {
500 int orientation
= angleToGlyphOrientation(primitiveValue
->getFloatValue());
501 ASSERT(orientation
!= -1);
503 svgstyle
->setGlyphOrientationHorizontal((EGlyphOrientation
) orientation
);
508 case CSSPropertyGlyphOrientationVertical
:
510 HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical
, GlyphOrientationVertical
)
514 if (primitiveValue
->primitiveType() == CSSPrimitiveValue::CSS_DEG
) {
515 int orientation
= angleToGlyphOrientation(primitiveValue
->getFloatValue());
516 ASSERT(orientation
!= -1);
518 svgstyle
->setGlyphOrientationVertical((EGlyphOrientation
) orientation
);
519 } else if (primitiveValue
->getIdent() == CSSValueAuto
)
520 svgstyle
->setGlyphOrientationVertical(GO_AUTO
);
524 case CSSPropertyEnableBackground
:
525 // Silently ignoring this property for now
526 // http://bugs.webkit.org/show_bug.cgi?id=6022
528 case CSSPropertyWebkitShadow
: {
530 return svgstyle
->setShadow(m_parentStyle
->svgStyle()->shadow() ? new ShadowData(*m_parentStyle
->svgStyle()->shadow()) : 0);
531 if (isInitial
|| primitiveValue
) // initial | none
532 return svgstyle
->setShadow(0);
534 if (!value
->isValueList())
537 float zoomFactor
= m_style
->effectiveZoom();
539 CSSValueList
*list
= static_cast<CSSValueList
*>(value
);
540 ASSERT(list
->length() == 1);
541 ShadowValue
* item
= static_cast<ShadowValue
*>(list
->itemWithoutBoundsCheck(0));
542 int x
= item
->x
->computeLengthInt(style(), m_rootElementStyle
, zoomFactor
);
543 int y
= item
->y
->computeLengthInt(style(), m_rootElementStyle
, zoomFactor
);
544 int blur
= item
->blur
? item
->blur
->computeLengthInt(style(), m_rootElementStyle
, zoomFactor
) : 0;
547 color
= getColorFromPrimitiveValue(item
->color
.get());
549 // -webkit-shadow does should not have a spread or style
550 ASSERT(!item
->spread
);
551 ASSERT(!item
->style
);
553 ShadowData
* shadowData
= new ShadowData(x
, y
, blur
, 0, Normal
, color
.isValid() ? color
: Color::transparent
);
554 svgstyle
->setShadow(shadowData
);
558 // If you crash here, it's because you added a css property and are not handling it
559 // in either this switch statement or the one in CSSStyleSelector::applyProperty
560 ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id
);
568 #endif // ENABLE(SVG)