2 Copyright (C) 2005 Apple Computer, Inc.
3 Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
4 2004, 2005 Rob Buis <buis@kde.org>
6 Based on khtml css code by:
7 Copyright(C) 1999-2003 Lars Knoll(knoll@kde.org)
8 (C) 2003 Apple Computer, Inc.
9 (C) 2004 Allan Sandfeld Jensen(kde@carewolf.com)
10 (C) 2004 Germain Garand(germain@ebooksfrance.org)
12 This file is part of the KDE project
14 This library is free software; you can redistribute it and/or
15 modify it under the terms of the GNU Library General Public
16 License as published by the Free Software Foundation; either
17 version 2 of the License, or (at your option) any later version.
19 This library is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
22 Library General Public License for more details.
24 You should have received a copy of the GNU Library General Public License
25 along with this library; see the file COPYING.LIB. If not, write to
26 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
27 Boston, MA 02110-1301, USA.
32 #include "CSSStyleSelector.h"
34 #include "CSSPropertyNames.h"
35 #include "CSSValueKeywords.h"
36 #include "CSSValueList.h"
40 #include "SVGRenderStyle.h"
41 #include "SVGRenderStyleDefs.h"
42 #include "SVGStyledElement.h"
45 #include <wtf/MathExtras.h>
47 #define HANDLE_INHERIT(prop, Prop) \
50 svgstyle->set##Prop(parentStyle->svgStyle()->prop());\
54 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
55 HANDLE_INHERIT(prop, Prop) \
57 svgstyle->set##Prop(SVGRenderStyle::initial##Prop());
59 #define HANDLE_INHERIT_COND(propID, prop, Prop) \
62 svgstyle->set##Prop(parentStyle->svgStyle()->prop());\
66 #define HANDLE_INITIAL_COND(propID, Prop) \
69 svgstyle->set##Prop(SVGRenderStyle::initial##Prop());\
73 #define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
75 svgstyle->set##Prop(SVGRenderStyle::initial##Value()); \
81 void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
83 CSSPrimitiveValue* primitiveValue = 0;
84 if (value->isPrimitiveValue())
85 primitiveValue = static_cast<CSSPrimitiveValue*>(value);
87 SVGRenderStyle* svgstyle = style->accessSVGStyle();
88 unsigned short valueType = value->cssValueType();
90 bool isInherit = parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT;
91 bool isInitial = valueType == CSSPrimitiveValue::CSS_INITIAL || (!parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT);
93 // What follows is a list that maps the CSS properties into their
94 // corresponding front-end RenderStyle values. Shorthands(e.g. border,
95 // background) occur in this list as well and are only hit when mapping
96 // "inherit" or "initial" into front-end values.
99 // ident only properties
100 case CSS_PROP_ALIGNMENT_BASELINE:
102 HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline)
106 switch (primitiveValue->getIdent()) {
108 svgstyle->setAlignmentBaseline(AB_AUTO);
110 case CSS_VAL_BASELINE:
111 svgstyle->setAlignmentBaseline(AB_BASELINE);
113 case CSS_VAL_BEFORE_EDGE:
114 svgstyle->setAlignmentBaseline(AB_BEFORE_EDGE);
116 case CSS_VAL_TEXT_BEFORE_EDGE:
117 svgstyle->setAlignmentBaseline(AB_TEXT_BEFORE_EDGE);
120 svgstyle->setAlignmentBaseline(AB_MIDDLE);
122 case CSS_VAL_CENTRAL:
123 svgstyle->setAlignmentBaseline(AB_CENTRAL);
125 case CSS_VAL_AFTER_EDGE:
126 svgstyle->setAlignmentBaseline(AB_AFTER_EDGE);
128 case CSS_VAL_TEXT_AFTER_EDGE:
129 svgstyle->setAlignmentBaseline(AB_TEXT_AFTER_EDGE);
131 case CSS_VAL_IDEOGRAPHIC:
132 svgstyle->setAlignmentBaseline(AB_IDEOGRAPHIC);
134 case CSS_VAL_ALPHABETIC:
135 svgstyle->setAlignmentBaseline(AB_ALPHABETIC);
137 case CSS_VAL_HANGING:
138 svgstyle->setAlignmentBaseline(AB_HANGING);
140 case CSS_VAL_MATHEMATICAL:
141 svgstyle->setAlignmentBaseline(AB_MATHEMATICAL);
149 case CSS_PROP_BASELINE_SHIFT:
151 HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
155 if (primitiveValue->getIdent()) {
156 switch (primitiveValue->getIdent()) {
157 case CSS_VAL_BASELINE:
158 svgstyle->setBaselineShift(BS_BASELINE);
161 svgstyle->setBaselineShift(BS_SUB);
164 svgstyle->setBaselineShift(BS_SUPER);
170 svgstyle->setBaselineShift(BS_LENGTH);
171 svgstyle->setBaselineShiftValue(primitiveValue);
176 case CSS_PROP_KERNING:
179 HANDLE_INHERIT_COND(CSS_PROP_KERNING, kerning, Kerning)
182 else if (isInitial) {
183 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_KERNING, Kerning, Kerning)
187 svgstyle->setKerning(primitiveValue);
190 case CSS_PROP_POINTER_EVENTS:
192 HANDLE_INHERIT_AND_INITIAL(pointerEvents, PointerEvents)
196 switch (primitiveValue->getIdent()) {
198 svgstyle->setPointerEvents(PE_ALL);
201 svgstyle->setPointerEvents(PE_NONE);
203 case CSS_VAL_VISIBLEPAINTED:
204 svgstyle->setPointerEvents(PE_VISIBLE_PAINTED);
206 case CSS_VAL_VISIBLEFILL:
207 svgstyle->setPointerEvents(PE_VISIBLE_FILL);
209 case CSS_VAL_VISIBLESTROKE:
210 svgstyle->setPointerEvents(PE_VISIBLE_STROKE);
212 case CSS_VAL_VISIBLE:
213 svgstyle->setPointerEvents(PE_VISIBLE);
215 case CSS_VAL_PAINTED:
216 svgstyle->setPointerEvents(PE_PAINTED);
219 svgstyle->setPointerEvents(PE_FILL);
222 svgstyle->setPointerEvents(PE_STROKE);
229 case CSS_PROP_DOMINANT_BASELINE:
231 HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline)
235 switch (primitiveValue->getIdent()) {
237 svgstyle->setDominantBaseline(DB_AUTO);
239 case CSS_VAL_USE_SCRIPT:
240 svgstyle->setDominantBaseline(DB_USE_SCRIPT);
242 case CSS_VAL_NO_CHANGE:
243 svgstyle->setDominantBaseline(DB_NO_CHANGE);
245 case CSS_VAL_RESET_SIZE:
246 svgstyle->setDominantBaseline(DB_RESET_SIZE);
248 case CSS_VAL_IDEOGRAPHIC:
249 svgstyle->setDominantBaseline(DB_IDEOGRAPHIC);
251 case CSS_VAL_ALPHABETIC:
252 svgstyle->setDominantBaseline(DB_ALPHABETIC);
254 case CSS_VAL_HANGING:
255 svgstyle->setDominantBaseline(DB_HANGING);
257 case CSS_VAL_MATHEMATICAL:
258 svgstyle->setDominantBaseline(DB_MATHEMATICAL);
260 case CSS_VAL_CENTRAL:
261 svgstyle->setDominantBaseline(DB_CENTRAL);
264 svgstyle->setDominantBaseline(DB_MIDDLE);
266 case CSS_VAL_TEXT_AFTER_EDGE:
267 svgstyle->setDominantBaseline(DB_TEXT_AFTER_EDGE);
269 case CSS_VAL_TEXT_BEFORE_EDGE:
270 svgstyle->setDominantBaseline(DB_TEXT_BEFORE_EDGE);
278 case CSS_PROP_COLOR_INTERPOLATION:
280 HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation)
284 switch (primitiveValue->getIdent()) {
286 svgstyle->setColorInterpolation(CI_SRGB);
288 case CSS_VAL_LINEARRGB:
289 svgstyle->setColorInterpolation(CI_LINEARRGB);
292 svgstyle->setColorInterpolation(CI_AUTO);
299 case CSS_PROP_COLOR_INTERPOLATION_FILTERS:
301 HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters)
305 switch (primitiveValue->getIdent()) {
307 svgstyle->setColorInterpolationFilters(CI_SRGB);
309 case CSS_VAL_LINEARRGB:
310 svgstyle->setColorInterpolationFilters(CI_LINEARRGB);
313 svgstyle->setColorInterpolationFilters(CI_AUTO);
320 case CSS_PROP_CLIP_RULE:
322 HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule)
326 switch (primitiveValue->getIdent()) {
327 case CSS_VAL_NONZERO:
328 svgstyle->setClipRule(RULE_NONZERO);
330 case CSS_VAL_EVENODD:
331 svgstyle->setClipRule(RULE_EVENODD);
339 case CSS_PROP_FILL_RULE:
341 HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule)
345 switch (primitiveValue->getIdent()) {
346 case CSS_VAL_NONZERO:
347 svgstyle->setFillRule(RULE_NONZERO);
349 case CSS_VAL_EVENODD:
350 svgstyle->setFillRule(RULE_EVENODD);
357 case CSS_PROP_STROKE_LINEJOIN:
359 HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle)
364 switch (primitiveValue->getIdent()) {
366 svgstyle->setJoinStyle(MiterJoin);
369 svgstyle->setJoinStyle(RoundJoin);
372 svgstyle->setJoinStyle(BevelJoin);
379 case CSS_PROP_IMAGE_RENDERING:
381 HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering)
385 switch (primitiveValue->getIdent()) {
387 svgstyle->setImageRendering(IR_AUTO);
388 case CSS_VAL_OPTIMIZESPEED:
389 svgstyle->setImageRendering(IR_OPTIMIZESPEED);
390 case CSS_VAL_OPTIMIZEQUALITY:
391 svgstyle->setImageRendering(IR_OPTIMIZEQUALITY);
395 case CSS_PROP_SHAPE_RENDERING:
397 HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering)
401 switch (primitiveValue->getIdent()) {
403 svgstyle->setShapeRendering(SR_AUTO);
404 case CSS_VAL_OPTIMIZESPEED:
405 svgstyle->setShapeRendering(SR_OPTIMIZESPEED);
406 case CSS_VAL_CRISPEDGES:
407 svgstyle->setShapeRendering(SR_CRISPEDGES);
408 case CSS_VAL_GEOMETRICPRECISION:
409 svgstyle->setShapeRendering(SR_GEOMETRICPRECISION);
413 case CSS_PROP_TEXT_RENDERING:
415 HANDLE_INHERIT_AND_INITIAL(textRendering, TextRendering)
419 switch (primitiveValue->getIdent()) {
421 svgstyle->setTextRendering(TR_AUTO);
422 case CSS_VAL_OPTIMIZESPEED:
423 svgstyle->setTextRendering(TR_OPTIMIZESPEED);
424 case CSS_VAL_OPTIMIZELEGIBILITY:
425 svgstyle->setTextRendering(TR_OPTIMIZELEGIBILITY);
426 case CSS_VAL_GEOMETRICPRECISION:
427 svgstyle->setTextRendering(TR_GEOMETRICPRECISION);
431 // end of ident only properties
434 HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint)
435 if (!primitiveValue && value) {
436 SVGPaint *paint = static_cast<SVGPaint*>(value);
438 svgstyle->setFillPaint(paint);
443 case CSS_PROP_STROKE:
445 HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint)
446 if (!primitiveValue && value) {
447 SVGPaint *paint = static_cast<SVGPaint*>(value);
449 svgstyle->setStrokePaint(paint);
454 case CSS_PROP_STROKE_WIDTH:
456 HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
460 svgstyle->setStrokeWidth(primitiveValue);
463 case CSS_PROP_STROKE_DASHARRAY:
465 HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
466 if (!primitiveValue && value) {
467 CSSValueList* dashes = static_cast<CSSValueList*>(value);
469 svgstyle->setStrokeDashArray(dashes);
474 case CSS_PROP_STROKE_DASHOFFSET:
476 HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
480 svgstyle->setStrokeDashOffset(primitiveValue);
483 case CSS_PROP_FILL_OPACITY:
485 HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity)
490 int type = primitiveValue->primitiveType();
491 if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
492 f = primitiveValue->getFloatValue() / 100.0f;
493 else if (type == CSSPrimitiveValue::CSS_NUMBER)
494 f = primitiveValue->getFloatValue();
498 svgstyle->setFillOpacity(f);
501 case CSS_PROP_STROKE_OPACITY:
503 HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity)
508 int type = primitiveValue->primitiveType();
509 if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
510 f = primitiveValue->getFloatValue() / 100.0f;
511 else if (type == CSSPrimitiveValue::CSS_NUMBER)
512 f = primitiveValue->getFloatValue();
516 svgstyle->setStrokeOpacity(f);
519 case CSS_PROP_STOP_OPACITY:
521 HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity)
526 int type = primitiveValue->primitiveType();
527 if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
528 f = primitiveValue->getFloatValue() / 100.0f;
529 else if (type == CSSPrimitiveValue::CSS_NUMBER)
530 f = primitiveValue->getFloatValue();
534 svgstyle->setStopOpacity(f);
537 case CSS_PROP_MARKER_START:
539 HANDLE_INHERIT_AND_INITIAL(startMarker, StartMarker)
544 int type = primitiveValue->primitiveType();
545 if (type == CSSPrimitiveValue::CSS_URI)
546 s = primitiveValue->getStringValue();
550 svgstyle->setStartMarker(s);
553 case CSS_PROP_MARKER_MID:
555 HANDLE_INHERIT_AND_INITIAL(midMarker, MidMarker)
560 int type = primitiveValue->primitiveType();
561 if (type == CSSPrimitiveValue::CSS_URI)
562 s = primitiveValue->getStringValue();
566 svgstyle->setMidMarker(s);
569 case CSS_PROP_MARKER_END:
571 HANDLE_INHERIT_AND_INITIAL(endMarker, EndMarker)
576 int type = primitiveValue->primitiveType();
577 if (type == CSSPrimitiveValue::CSS_URI)
578 s = primitiveValue->getStringValue();
582 svgstyle->setEndMarker(s);
585 case CSS_PROP_STROKE_LINECAP:
587 HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle)
591 switch (primitiveValue->getIdent()) {
593 svgstyle->setCapStyle(ButtCap);
596 svgstyle->setCapStyle(RoundCap);
599 svgstyle->setCapStyle(SquareCap);
606 case CSS_PROP_STROKE_MITERLIMIT:
608 HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit)
613 int type = primitiveValue->primitiveType();
614 if (type == CSSPrimitiveValue::CSS_NUMBER)
615 f = primitiveValue->getFloatValue();
619 svgstyle->setStrokeMiterLimit(f);
622 case CSS_PROP_FILTER:
624 HANDLE_INHERIT_AND_INITIAL(filter, Filter)
629 int type = primitiveValue->primitiveType();
630 if (type == CSSPrimitiveValue::CSS_URI)
631 s = primitiveValue->getStringValue();
634 svgstyle->setFilter(s);
639 HANDLE_INHERIT_AND_INITIAL(maskElement, MaskElement)
644 int type = primitiveValue->primitiveType();
645 if (type == CSSPrimitiveValue::CSS_URI)
646 s = primitiveValue->getStringValue();
650 svgstyle->setMaskElement(s);
653 case CSS_PROP_CLIP_PATH:
655 HANDLE_INHERIT_AND_INITIAL(clipPath, ClipPath)
660 int type = primitiveValue->primitiveType();
661 if (type == CSSPrimitiveValue::CSS_URI)
662 s = primitiveValue->getStringValue();
666 svgstyle->setClipPath(s);
669 case CSS_PROP_TEXT_ANCHOR:
671 HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor)
675 switch (primitiveValue->getIdent()) {
677 svgstyle->setTextAnchor(TA_START);
680 svgstyle->setTextAnchor(TA_MIDDLE);
683 svgstyle->setTextAnchor(TA_END);
690 case CSS_PROP_WRITING_MODE:
692 HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode)
694 svgstyle->setWritingMode((EWritingMode)(primitiveValue->getIdent() - CSS_VAL_LR_TB));
697 case CSS_PROP_STOP_COLOR:
699 HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
701 SVGColor* c = static_cast<SVGColor*>(value);
703 return CSSStyleSelector::applyProperty(id, value);
706 if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
707 col = style->color();
711 svgstyle->setStopColor(col);
714 case CSS_PROP_LIGHTING_COLOR:
716 HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
718 SVGColor* c = static_cast<SVGColor*>(value);
720 return CSSStyleSelector::applyProperty(id, value);
723 if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
724 col = style->color();
728 svgstyle->setLightingColor(col);
731 case CSS_PROP_FLOOD_OPACITY:
733 HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity)
738 int type = primitiveValue->primitiveType();
739 if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
740 f = primitiveValue->getFloatValue() / 100.0f;
741 else if (type == CSSPrimitiveValue::CSS_NUMBER)
742 f = primitiveValue->getFloatValue();
746 svgstyle->setFloodOpacity(f);
749 case CSS_PROP_FLOOD_COLOR:
753 col = SVGRenderStyle::initialFloodColor();
755 SVGColor *c = static_cast<SVGColor*>(value);
757 return CSSStyleSelector::applyProperty(id, value);
759 if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
760 col = style->color();
765 svgstyle->setFloodColor(col);
768 case CSS_PROP_GLYPH_ORIENTATION_VERTICAL:
769 case CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL:
770 // support for above properties has not been implemented in the engine yet
773 // If you crash here, it's because you added a css property and are not handling it
774 // in either this switch statement or the one in CSSStyleSelector::applyProperty
775 ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id);
783 #endif // ENABLE(SVG)