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 | |
76 | namespace khtml |
77 | { |
78 | |
79 | using namespace DOM; |
80 | using namespace WebCore; |
81 | |
82 | static 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 | |
95 | static 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 | |
108 | static 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 | |
123 | static 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 | |
140 | static 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 | |
157 | void 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 | |