1/*
2 Copyright (C) 2005 Apple Computer, Inc.
3 Copyright (C) 2004, 2005, 2007 Nikolas Zimmermann <zimmermann@kde.org>
4 Copyright (C) 2004, 2005 Rob Buis <buis@kde.org>
5 Copyright (C) 2007 Alexey Proskuryakov <ap@webkit.org>
6 Copyright (C) 2009 Maksim Orlovich <maksim@kde.org>
7
8 Based on khtml css code by:
9 Copyright (C) 1999-2003 Lars Knoll <knoll@kde.org>
10 Copyright (C) 2003 Apple Computer, Inc.
11 Copyright (C) 2004 Allan Sandfeld Jensen <kde@carewolf.com>
12 Copyright (C) 2004 Germain Garand <germain@ebooksfrance.org>
13
14 This file is part of the KDE project
15
16 This library is free software; you can redistribute it and/or
17 modify it under the terms of the GNU Library General Public
18 License as published by the Free Software Foundation; either
19 version 2 of the License, or (at your option) any later version.
20
21 This library is distributed in the hope that it will be useful,
22 but WITHOUT ANY WARRANTY; without even the implied warranty of
23 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
24 Library General Public License for more details.
25
26 You should have received a copy of the GNU Library General Public License
27 along with this library; see the file COPYING.LIB. If not, write to
28 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
29 Boston, MA 02110-1301, USA.
30*/
31
32#include "cssstyleselector.h"
33#include "css_valueimpl.h"
34#include "css_svgvalueimpl.h"
35#include "cssvalues.h"
36
37#include "SVGNames.h"
38#include "SVGRenderStyle.h"
39#include "SVGRenderStyleDefs.h"
40#include "SVGStyledElement.h"
41
42#include <wtf/MathExtras.h>
43
44#define HANDLE_INHERIT(prop, Prop) \
45 if (isInherit) \
46 {\
47 svgstyle->set##Prop(parentStyle->svgStyle()->prop());\
48 return;\
49 }
50
51#define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
52 HANDLE_INHERIT(prop, Prop) \
53 else if (isInitial) \
54 svgstyle->set##Prop(SVGRenderStyle::initial##Prop());
55
56#define HANDLE_INHERIT_COND(propID, prop, Prop) \
57 if (id == propID) \
58 {\
59 svgstyle->set##Prop(parentStyle->svgStyle()->prop());\
60 return;\
61 }
62
63#define HANDLE_INITIAL_COND(propID, Prop) \
64 if (id == propID) \
65 {\
66 svgstyle->set##Prop(SVGRenderStyle::initial##Prop());\
67 return;\
68 }
69
70#define HANDLE_INITIAL_COND_WITH_VALUE(propID, Prop, Value) \
71 if (id == propID) { \
72 svgstyle->set##Prop(SVGRenderStyle::initial##Value()); \
73 return; \
74 }
75
76namespace khtml
77{
78
79using namespace DOM;
80using namespace WebCore;
81
82static SVGPaintImpl *toPaint(CSSValueImpl *val)
83{
84 if (val->cssValueType() != DOM::CSSValue::CSS_SVG_VALUE) {
85 return nullptr;
86 }
87 SVGCSSValueImpl *svgVal = static_cast<SVGCSSValueImpl *>(val);
88 if (svgVal->isSVGPaint()) {
89 return static_cast<SVGPaintImpl *>(svgVal);
90 } else {
91 return nullptr;
92 }
93}
94
95static SVGColorImpl *toColor(CSSValueImpl *val)
96{
97 if (val->cssValueType() != DOM::CSSValue::CSS_SVG_VALUE) {
98 return nullptr;
99 }
100 SVGCSSValueImpl *svgVal = static_cast<SVGCSSValueImpl *>(val);
101 if (svgVal->isSVGColor()) {
102 return static_cast<SVGColorImpl *>(svgVal);
103 } else {
104 return nullptr;
105 }
106}
107
108static float roundToNearestGlyphOrientationAngle(float angle)
109{
110 angle = fabsf(fmodf(angle, 360.0f));
111
112 if (angle <= 45.0f || angle > 315.0f) {
113 return 0.0f;
114 } else if (angle > 45.0f && angle <= 135.0f) {
115 return 90.0f;
116 } else if (angle > 135.0f && angle <= 225.0f) {
117 return 180.0f;
118 }
119
120 return 270.0f;
121}
122
123static int angleToGlyphOrientation(float angle)
124{
125 angle = roundToNearestGlyphOrientationAngle(angle);
126
127 if (angle == 0.0f) {
128 return GO_0DEG;
129 } else if (angle == 90.0f) {
130 return GO_90DEG;
131 } else if (angle == 180.0f) {
132 return GO_180DEG;
133 } else if (angle == 270.0f) {
134 return GO_270DEG;
135 }
136
137 return -1;
138}
139
140static EColorInterpolation colorInterpolationForValue(DOM::CSSPrimitiveValueImpl *primitiveValue)
141{
142 if (!primitiveValue) {
143 return CI_AUTO;
144 }
145
146 switch (primitiveValue->getIdent()) {
147 case CSS_VAL_SRGB:
148 return CI_SRGB;
149 case CSS_VAL_LINEARRGB:
150 return CI_LINEARRGB;
151 case CSS_VAL_AUTO:
152 default:
153 return CI_AUTO;
154 }
155}
156
157void CSSStyleSelector::applySVGRule(int id, DOM::CSSValueImpl *value)
158{
159 CSSPrimitiveValueImpl *primitiveValue = nullptr;
160 if (value->isPrimitiveValue()) {
161 primitiveValue = static_cast<CSSPrimitiveValueImpl *>(value);
162 }
163
164 SVGRenderStyle *svgstyle = style->accessSVGStyle();
165 unsigned short valueType = value->cssValueType();
166
167 bool isInherit = parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT;
168 bool isInitial = valueType == CSSPrimitiveValue::CSS_INITIAL || (!parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT);
169
170 // What follows is a list that maps the CSS properties into their
171 // corresponding front-end RenderStyle values. Shorthands(e.g. border,
172 // background) occur in this list as well and are only hit when mapping
173 // "inherit" or "initial" into front-end values.
174 switch (id) {
175 // ident only properties
176 case CSS_PROP_ALIGNMENT_BASELINE: {
177 HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline)
178 if (!primitiveValue) {
179 break;
180 }
181
182 switch (primitiveValue->getIdent()) {
183 case CSS_VAL_AUTO:
184 svgstyle->setAlignmentBaseline(AB_AUTO);
185 break;
186 case CSS_VAL_BASELINE:
187 svgstyle->setAlignmentBaseline(AB_BASELINE);
188 break;
189 case CSS_VAL_BEFORE_EDGE:
190 svgstyle->setAlignmentBaseline(AB_BEFORE_EDGE);
191 break;
192 case CSS_VAL_TEXT_BEFORE_EDGE:
193 svgstyle->setAlignmentBaseline(AB_TEXT_BEFORE_EDGE);
194 break;
195 case CSS_VAL_MIDDLE:
196 svgstyle->setAlignmentBaseline(AB_MIDDLE);
197 break;
198 case CSS_VAL_CENTRAL:
199 svgstyle->setAlignmentBaseline(AB_CENTRAL);
200 break;
201 case CSS_VAL_AFTER_EDGE:
202 svgstyle->setAlignmentBaseline(AB_AFTER_EDGE);
203 break;
204 case CSS_VAL_TEXT_AFTER_EDGE:
205 svgstyle->setAlignmentBaseline(AB_TEXT_AFTER_EDGE);
206 break;
207 case CSS_VAL_IDEOGRAPHIC:
208 svgstyle->setAlignmentBaseline(AB_IDEOGRAPHIC);
209 break;
210 case CSS_VAL_ALPHABETIC:
211 svgstyle->setAlignmentBaseline(AB_ALPHABETIC);
212 break;
213 case CSS_VAL_HANGING:
214 svgstyle->setAlignmentBaseline(AB_HANGING);
215 break;
216 case CSS_VAL_MATHEMATICAL:
217 svgstyle->setAlignmentBaseline(AB_MATHEMATICAL);
218 break;
219 default:
220 break;
221 }
222 break;
223 }
224 case CSS_PROP_BASELINE_SHIFT: {
225 HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
226 if (!primitiveValue) {
227 break;
228 }
229
230 if (primitiveValue->getIdent()) {
231 switch (primitiveValue->getIdent()) {
232 case CSS_VAL_BASELINE:
233 svgstyle->setBaselineShift(BS_BASELINE);
234 break;
235 case CSS_VAL_SUB:
236 svgstyle->setBaselineShift(BS_SUB);
237 break;
238 case CSS_VAL_SUPER:
239 svgstyle->setBaselineShift(BS_SUPER);
240 break;
241 default:
242 break;
243 }
244 } else {
245 svgstyle->setBaselineShift(BS_LENGTH);
246 svgstyle->setBaselineShiftValue(primitiveValue);
247 }
248
249 break;
250 }
251 case CSS_PROP_KERNING: {
252 if (isInherit) {
253 HANDLE_INHERIT_COND(CSS_PROP_KERNING, kerning, Kerning)
254 return;
255 } else if (isInitial) {
256 HANDLE_INITIAL_COND_WITH_VALUE(CSS_PROP_KERNING, Kerning, Kerning)
257 return;
258 }
259 svgstyle->setKerning(primitiveValue);
260 break;
261 }
262 case CSS_PROP_POINTER_EVENTS: {
263 HANDLE_INHERIT_AND_INITIAL(pointerEvents, PointerEvents)
264 if (!primitiveValue) {
265 break;
266 }
267
268 switch (primitiveValue->getIdent()) {
269 case CSS_VAL_NONE:
270 svgstyle->setPointerEvents(PE_NONE);
271 break;
272 case CSS_VAL_STROKE:
273 svgstyle->setPointerEvents(PE_STROKE);
274 break;
275 case CSS_VAL_FILL:
276 svgstyle->setPointerEvents(PE_FILL);
277 break;
278 case CSS_VAL_PAINTED:
279 svgstyle->setPointerEvents(PE_PAINTED);
280 break;
281 case CSS_VAL_VISIBLE:
282 svgstyle->setPointerEvents(PE_VISIBLE);
283 break;
284 case CSS_VAL_VISIBLESTROKE:
285 svgstyle->setPointerEvents(PE_VISIBLE_STROKE);
286 break;
287 case CSS_VAL_VISIBLEFILL:
288 svgstyle->setPointerEvents(PE_VISIBLE_FILL);
289 break;
290 case CSS_VAL_VISIBLEPAINTED:
291 svgstyle->setPointerEvents(PE_VISIBLE_PAINTED);
292 break;
293 case CSS_VAL_ALL:
294 svgstyle->setPointerEvents(PE_ALL);
295 break;
296 default:
297 break;
298 }
299 break;
300 }
301 case CSS_PROP_DOMINANT_BASELINE: {
302 HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline)
303
304 if (!primitiveValue) {
305 break;
306 }
307
308 switch (primitiveValue->getIdent()) {
309 case CSS_VAL_AUTO:
310 svgstyle->setDominantBaseline(DB_AUTO);
311 break;
312 case CSS_VAL_USE_SCRIPT:
313 svgstyle->setDominantBaseline(DB_USE_SCRIPT);
314 break;
315 case CSS_VAL_NO_CHANGE:
316 svgstyle->setDominantBaseline(DB_NO_CHANGE);
317 break;
318 case CSS_VAL_RESET_SIZE:
319 svgstyle->setDominantBaseline(DB_RESET_SIZE);
320 break;
321 case CSS_VAL_IDEOGRAPHIC:
322 svgstyle->setDominantBaseline(DB_IDEOGRAPHIC);
323 break;
324 case CSS_VAL_ALPHABETIC:
325 svgstyle->setDominantBaseline(DB_ALPHABETIC);
326 break;
327 case CSS_VAL_HANGING:
328 svgstyle->setDominantBaseline(DB_HANGING);
329 break;
330 case CSS_VAL_MATHEMATICAL:
331 svgstyle->setDominantBaseline(DB_MATHEMATICAL);
332 break;
333 case CSS_VAL_CENTRAL:
334 svgstyle->setDominantBaseline(DB_CENTRAL);
335 break;
336 case CSS_VAL_MIDDLE:
337 svgstyle->setDominantBaseline(DB_MIDDLE);
338 break;
339 case CSS_VAL_TEXT_AFTER_EDGE:
340 svgstyle->setDominantBaseline(DB_TEXT_AFTER_EDGE);
341 break;
342 case CSS_VAL_TEXT_BEFORE_EDGE:
343 svgstyle->setDominantBaseline(DB_TEXT_BEFORE_EDGE);
344 break;
345 default:
346 break;
347 }
348
349 break;
350 }
351 case CSS_PROP_COLOR_INTERPOLATION: {
352 HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation);
353
354 svgstyle->setColorInterpolation(colorInterpolationForValue(primitiveValue));
355 break;
356 }
357 case CSS_PROP_COLOR_INTERPOLATION_FILTERS: {
358 HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters)
359
360 svgstyle->setColorInterpolationFilters(colorInterpolationForValue(primitiveValue));
361 break;
362 }
363 case CSS_PROP_COLOR_RENDERING: {
364 HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering)
365 if (!primitiveValue) {
366 break;
367 }
368
369 switch (primitiveValue->getIdent()) {
370 case CSS_VAL_AUTO:
371 svgstyle->setColorRendering(CR_AUTO);
372 break;
373 case CSS_VAL_OPTIMIZESPEED:
374 svgstyle->setColorRendering(CR_OPTIMIZESPEED);
375 break;
376 case CSS_VAL_OPTIMIZEQUALITY:
377 svgstyle->setColorRendering(CR_OPTIMIZEQUALITY);
378 break;
379 default:
380 break;
381 }
382 break;
383 }
384 case CSS_PROP_CLIP_RULE: {
385 HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule)
386 if (primitiveValue) {
387 svgstyle->setClipRule((primitiveValue->getIdent() == CSS_VAL_NONZERO) ? RULE_NONZERO : RULE_EVENODD);
388 }
389 break;
390 }
391 case CSS_PROP_FILL_RULE: {
392 HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule)
393 if (primitiveValue) {
394 svgstyle->setFillRule((primitiveValue->getIdent() == CSS_VAL_NONZERO) ? RULE_NONZERO : RULE_EVENODD);
395 }
396 break;
397 }
398
399 case CSS_PROP_STROKE_LINEJOIN: {
400 HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle)
401 if (!primitiveValue) {
402 break;
403 }
404
405 switch (primitiveValue->getIdent()) {
406 case CSS_VAL_MITER:
407 svgstyle->setJoinStyle(khtml::MiterJoin);
408 break;
409 case CSS_VAL_ROUND:
410 svgstyle->setJoinStyle(khtml::RoundJoin);
411 break;
412 case CSS_VAL_BEVEL:
413 svgstyle->setJoinStyle(khtml::BevelJoin);
414 break;
415 default:
416 break;
417 }
418 break;
419 }
420 case CSS_PROP_IMAGE_RENDERING: {
421 HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering)
422 if (!primitiveValue) {
423 break;
424 }
425
426 switch (primitiveValue->getIdent()) {
427 case CSS_VAL_AUTO:
428 svgstyle->setImageRendering(IR_AUTO);
429 break;
430 case CSS_VAL_OPTIMIZESPEED:
431 svgstyle->setImageRendering(IR_OPTIMIZESPEED);
432 break;
433 case CSS_VAL_OPTIMIZEQUALITY:
434 svgstyle->setImageRendering(IR_OPTIMIZEQUALITY);
435 break;
436 default:
437 break;
438 }
439 break;
440 }
441 case CSS_PROP_SHAPE_RENDERING: {
442 HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering)
443 if (!primitiveValue) {
444 break;
445 }
446
447 switch (primitiveValue->getIdent()) {
448 case CSS_VAL_AUTO:
449 svgstyle->setShapeRendering(SR_AUTO);
450 break;
451 case CSS_VAL_OPTIMIZESPEED:
452 svgstyle->setShapeRendering(SR_OPTIMIZESPEED);
453 break;
454 case CSS_VAL_CRISPEDGES:
455 svgstyle->setShapeRendering(SR_CRISPEDGES);
456 break;
457 case CSS_VAL_GEOMETRICPRECISION:
458 svgstyle->setShapeRendering(SR_GEOMETRICPRECISION);
459 break;
460 default:
461 break;
462 }
463 break;
464 }
465 case CSS_PROP_TEXT_RENDERING: {
466 HANDLE_INHERIT_AND_INITIAL(textRendering, TextRendering)
467 if (!primitiveValue) {
468 break;
469 }
470
471 switch (primitiveValue->getIdent()) {
472 case CSS_VAL_AUTO:
473 svgstyle->setTextRendering(TR_AUTO);
474 break;
475 case CSS_VAL_OPTIMIZESPEED:
476 svgstyle->setTextRendering(TR_OPTIMIZESPEED);
477 break;
478 case CSS_VAL_OPTIMIZELEGIBILITY:
479 svgstyle->setTextRendering(TR_OPTIMIZELEGIBILITY);
480 break;
481 case CSS_VAL_GEOMETRICPRECISION:
482 svgstyle->setTextRendering(TR_GEOMETRICPRECISION);
483 break;
484 default:
485 break;
486 }
487
488 break;
489 }
490 // end of ident only properties
491 case CSS_PROP_FILL: {
492 HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint)
493 if (SVGPaintImpl *paint = toPaint(value)) {
494 svgstyle->setFillPaint(paint);
495 }
496 break;
497 }
498 case CSS_PROP_STROKE: {
499 HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint)
500 if (SVGPaintImpl *paint = toPaint(value)) {
501 svgstyle->setStrokePaint(paint);
502 }
503 break;
504 }
505 case CSS_PROP_STROKE_WIDTH: {
506 HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
507 if (!primitiveValue) {
508 return;
509 }
510
511 svgstyle->setStrokeWidth(primitiveValue);
512 break;
513 }
514
515 case CSS_PROP_STROKE_DASHARRAY: {
516 HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
517 if (!primitiveValue && value && value->isValueList()) {
518 CSSValueListImpl *dashes = static_cast<CSSValueListImpl *>(value);
519 svgstyle->setStrokeDashArray(dashes);
520 }
521 break;
522 }
523 case CSS_PROP_STROKE_DASHOFFSET: {
524 HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
525 if (!primitiveValue) {
526 return;
527 }
528
529 svgstyle->setStrokeDashOffset(primitiveValue);
530 break;
531 }
532 case CSS_PROP_FILL_OPACITY: {
533 HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity)
534 if (!primitiveValue) {
535 return;
536 }
537
538 float f = 0.0f;
539 int type = primitiveValue->primitiveType();
540 if (type == CSSPrimitiveValue::CSS_PERCENTAGE) {
541 f = primitiveValue->floatValue() / 100.0f;
542 } else if (type == CSSPrimitiveValue::CSS_NUMBER) {
543 f = primitiveValue->floatValue();
544 } else {
545 return;
546 }
547
548 svgstyle->setFillOpacity(f);
549 break;
550 }
551 case CSS_PROP_STROKE_OPACITY: {
552 HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity)
553 if (!primitiveValue) {
554 return;
555 }
556
557 float f = 0.0f;
558 int type = primitiveValue->primitiveType();
559 if (type == CSSPrimitiveValue::CSS_PERCENTAGE) {
560 f = primitiveValue->floatValue() / 100.0f;
561 } else if (type == CSSPrimitiveValue::CSS_NUMBER) {
562 f = primitiveValue->floatValue();
563 } else {
564 return;
565 }
566
567 svgstyle->setStrokeOpacity(f);
568 break;
569 }
570
571 case CSS_PROP_STOP_OPACITY: {
572 HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity)
573 if (!primitiveValue) {
574 return;
575 }
576
577 float f = 0.0f;
578 int type = primitiveValue->primitiveType();
579 if (type == CSSPrimitiveValue::CSS_PERCENTAGE) {
580 f = primitiveValue->floatValue() / 100.0f;
581 } else if (type == CSSPrimitiveValue::CSS_NUMBER) {
582 f = primitiveValue->floatValue();
583 } else {
584 return;
585 }
586
587 svgstyle->setStopOpacity(f);
588 break;
589 }
590
591 case CSS_PROP_MARKER_START: {
592 HANDLE_INHERIT_AND_INITIAL(startMarker, StartMarker)
593 if (!primitiveValue) {
594 return;
595 }
596
597 String s;
598 int type = primitiveValue->primitiveType();
599 if (type == CSSPrimitiveValue::CSS_URI) {
600 s = primitiveValue->getStringValue();
601 } else {
602 return;
603 }
604
605 svgstyle->setStartMarker(s);
606 break;
607 }
608 case CSS_PROP_MARKER_MID: {
609 HANDLE_INHERIT_AND_INITIAL(midMarker, MidMarker)
610 if (!primitiveValue) {
611 return;
612 }
613
614 String s;
615 int type = primitiveValue->primitiveType();
616 if (type == CSSPrimitiveValue::CSS_URI) {
617 s = primitiveValue->getStringValue();
618 } else {
619 return;
620 }
621
622 svgstyle->setMidMarker(s);
623 break;
624 }
625 case CSS_PROP_MARKER_END: {
626 HANDLE_INHERIT_AND_INITIAL(endMarker, EndMarker)
627 if (!primitiveValue) {
628 return;
629 }
630
631 String s;
632 int type = primitiveValue->primitiveType();
633 if (type == CSSPrimitiveValue::CSS_URI) {
634 s = primitiveValue->getStringValue();
635 } else {
636 return;
637 }
638
639 svgstyle->setEndMarker(s);
640 break;
641 }
642 case CSS_PROP_STROKE_LINECAP: {
643 HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle)
644 if (!primitiveValue) {
645 break;
646 }
647
648 switch (primitiveValue->getIdent()) {
649 case CSS_VAL_BUTT:
650 svgstyle->setCapStyle(ButtCap);
651 break;
652 case CSS_VAL_ROUND:
653 svgstyle->setCapStyle(RoundCap);
654 break;
655 case CSS_VAL_SQUARE:
656 svgstyle->setCapStyle(SquareCap);
657 break;
658 default:
659 break;
660 }
661 break;
662 }
663 case CSS_PROP_STROKE_MITERLIMIT: {
664 HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit)
665 if (!primitiveValue) {
666 return;
667 }
668
669 float f = 0.0f;
670 int type = primitiveValue->primitiveType();
671 if (type == CSSPrimitiveValue::CSS_NUMBER) {
672 f = primitiveValue->floatValue();
673 } else {
674 return;
675 }
676
677 svgstyle->setStrokeMiterLimit(f);
678 break;
679 }
680 case CSS_PROP_FILTER: {
681 HANDLE_INHERIT_AND_INITIAL(filter, Filter)
682 if (!primitiveValue) {
683 return;
684 }
685
686 String s;
687 int type = primitiveValue->primitiveType();
688 if (type == CSSPrimitiveValue::CSS_URI) {
689 s = primitiveValue->getStringValue();
690 } else {
691 return;
692 }
693 svgstyle->setFilter(s);
694 break;
695 }
696 case CSS_PROP_MASK: {
697 HANDLE_INHERIT_AND_INITIAL(maskElement, MaskElement)
698 if (!primitiveValue) {
699 return;
700 }
701
702 String s;
703 int type = primitiveValue->primitiveType();
704 if (type == CSSPrimitiveValue::CSS_URI) {
705 s = primitiveValue->getStringValue();
706 } else {
707 return;
708 }
709
710 svgstyle->setMaskElement(s);
711 break;
712 }
713 case CSS_PROP_CLIP_PATH: {
714 HANDLE_INHERIT_AND_INITIAL(clipPath, ClipPath)
715 if (!primitiveValue) {
716 return;
717 }
718
719 String s;
720 int type = primitiveValue->primitiveType();
721 if (type == CSSPrimitiveValue::CSS_URI) {
722 s = primitiveValue->getStringValue();
723 } else {
724 return;
725 }
726
727 svgstyle->setClipPath(s);
728 break;
729 }
730
731 case CSS_PROP_TEXT_ANCHOR: {
732 HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor)
733 if (primitiveValue) {
734 switch (primitiveValue->getIdent()) {
735 case CSS_VAL_START:
736 svgstyle->setTextAnchor(TA_START);
737 break;
738 case CSS_VAL_MIDDLE:
739 svgstyle->setTextAnchor(TA_MIDDLE);
740 break;
741 case CSS_VAL_END:
742 svgstyle->setTextAnchor(TA_END);
743 break;
744 }
745 }
746 break;
747 }
748
749 case CSS_PROP_WRITING_MODE: {
750 HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode)
751 if (!primitiveValue) {
752 return;
753 }
754
755 switch (primitiveValue->getIdent()) {
756 case CSS_VAL_LR_TB:
757 svgstyle->setWritingMode(WM_LRTB);
758 break;
759 case CSS_VAL_LR:
760 svgstyle->setWritingMode(WM_LR);
761 break;
762 case CSS_VAL_RL_TB:
763 svgstyle->setWritingMode(WM_RLTB);
764 break;
765 case CSS_VAL_RL:
766 svgstyle->setWritingMode(WM_RL);
767 break;
768 case CSS_VAL_TB_RL:
769 svgstyle->setWritingMode(WM_TBRL);
770 break;
771 case CSS_VAL_TB:
772 svgstyle->setWritingMode(WM_TB);
773 break;
774 default:
775 break;
776 }
777 break;
778 }
779
780 case CSS_PROP_STOP_COLOR: {
781 HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
782
783 SVGColorImpl *c = toColor(value);
784 if (!c) {
785 break;
786 }
787
788 QColor col;
789 if (c->colorType() == SVGColorImpl::SVG_COLORTYPE_CURRENTCOLOR) {
790 col = style->color();
791 } else {
792 col = c->color();
793 }
794
795 svgstyle->setStopColor(col);
796 break;
797 }
798
799 case CSS_PROP_LIGHTING_COLOR: {
800 HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
801
802 SVGColorImpl *c = toColor(value);
803 if (!c) {
804 break;
805 }
806
807 QColor col;
808 if (c->colorType() == SVGColorImpl::SVG_COLORTYPE_CURRENTCOLOR) {
809 col = style->color();
810 } else {
811 col = c->color();
812 }
813
814 svgstyle->setLightingColor(col);
815 break;
816 }
817 case CSS_PROP_FLOOD_OPACITY: {
818 HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity)
819 if (!primitiveValue) {
820 return;
821 }
822
823 float f = 0.0f;
824 int type = primitiveValue->primitiveType();
825 if (type == CSSPrimitiveValue::CSS_PERCENTAGE) {
826 f = primitiveValue->floatValue() / 100.0f;
827 } else if (type == CSSPrimitiveValue::CSS_NUMBER) {
828 f = primitiveValue->floatValue();
829 } else {
830 return;
831 }
832
833 svgstyle->setFloodOpacity(f);
834 break;
835 }
836 case CSS_PROP_FLOOD_COLOR: {
837 QColor col;
838 if (isInitial) {
839 col = SVGRenderStyle::initialFloodColor();
840 } else {
841 SVGColorImpl *c = toColor(value);
842 if (!c) {
843 break;
844 }
845
846 if (c->colorType() == SVGColorImpl::SVG_COLORTYPE_CURRENTCOLOR) {
847 col = style->color();
848 } else {
849 col = c->color();
850 }
851 }
852
853 svgstyle->setFloodColor(col);
854 break;
855 }
856 case CSS_PROP_GLYPH_ORIENTATION_HORIZONTAL: {
857 HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal)
858 if (!primitiveValue) {
859 return;
860 }
861
862 if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
863 int orientation = angleToGlyphOrientation(primitiveValue->floatValue());
864 ASSERT(orientation != -1);
865
866 svgstyle->setGlyphOrientationHorizontal((EGlyphOrientation) orientation);
867 }
868
869 break;
870 }
871 case CSS_PROP_GLYPH_ORIENTATION_VERTICAL: {
872 HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical)
873 if (!primitiveValue) {
874 return;
875 }
876
877 if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
878 int orientation = angleToGlyphOrientation(primitiveValue->floatValue());
879 ASSERT(orientation != -1);
880
881 svgstyle->setGlyphOrientationVertical((EGlyphOrientation) orientation);
882 } else if (primitiveValue->getIdent() == CSS_VAL_AUTO) {
883 svgstyle->setGlyphOrientationVertical(GO_AUTO);
884 }
885
886 break;
887 }
888 case CSS_PROP_ENABLE_BACKGROUND:
889 // Silently ignoring this property for now
890 // https://bugs.webkit.org/show_bug.cgi?id=6022
891 break;
892 default:
893 // If you crash here, it's because you added a css property and are not handling it
894 // in either this switch statement or the one in CSSStyleSelector::applyProperty
895 qCWarning(KHTML_LOG) << "unimplemented property" << id << getPropertyName(id).string();
896 return;
897 }
898}
899
900}
901
902