• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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>
6 
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)
12 
13     This file is part of the KDE project
14 
15     This library is free software; you can redistribute it and/or
16     modify it under the terms of the GNU Library General Public
17     License as published by the Free Software Foundation; either
18     version 2 of the License, or (at your option) any later version.
19 
20     This library is distributed in the hope that it will be useful,
21     but WITHOUT ANY WARRANTY; without even the implied warranty of
22     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
23     Library General Public License for more details.
24 
25     You should have received a copy of the GNU Library General Public License
26     along with this library; see the file COPYING.LIB.  If not, write to
27     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
28     Boston, MA 02110-1301, USA.
29 */
30 
31 #include "config.h"
32 
33 #if ENABLE(SVG)
34 #include "CSSStyleSelector.h"
35 
36 #include "CSSPrimitiveValueMappings.h"
37 #include "CSSPropertyNames.h"
38 #include "CSSValueList.h"
39 #include "Document.h"
40 #include "SVGColor.h"
41 #include "SVGNames.h"
42 #include "SVGPaint.h"
43 #include "SVGRenderStyle.h"
44 #include "SVGRenderStyleDefs.h"
45 #include "SVGStyledElement.h"
46 #include "SVGURIReference.h"
47 #include <stdlib.h>
48 #include <wtf/MathExtras.h>
49 
50 #define HANDLE_INHERIT(prop, Prop) \
51 if (isInherit) \
52 {\
53     svgstyle->set##Prop(m_parentStyle->svgStyle()->prop());\
54     return;\
55 }
56 
57 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
58 HANDLE_INHERIT(prop, Prop) \
59 else if (isInitial) \
60     svgstyle->set##Prop(SVGRenderStyle::initial##Prop());
61 
62 
63 namespace WebCore {
64 
roundToNearestGlyphOrientationAngle(float angle)65 static float roundToNearestGlyphOrientationAngle(float angle)
66 {
67     angle = fabsf(fmodf(angle, 360.0f));
68 
69     if (angle <= 45.0f || angle > 315.0f)
70         return 0.0f;
71     else if (angle > 45.0f && angle <= 135.0f)
72         return 90.0f;
73     else if (angle > 135.0f && angle <= 225.0f)
74         return 180.0f;
75 
76     return 270.0f;
77 }
78 
angleToGlyphOrientation(float angle)79 static int angleToGlyphOrientation(float angle)
80 {
81     angle = roundToNearestGlyphOrientationAngle(angle);
82 
83     if (angle == 0.0f)
84         return GO_0DEG;
85     else if (angle == 90.0f)
86         return GO_90DEG;
87     else if (angle == 180.0f)
88         return GO_180DEG;
89     else if (angle == 270.0f)
90         return GO_270DEG;
91 
92     return -1;
93 }
94 
colorFromSVGColorCSSValue(CSSValue * value,RenderStyle * style)95 static Color colorFromSVGColorCSSValue(CSSValue* value, RenderStyle* style)
96 {
97     ASSERT(value->isSVGColor());
98     SVGColor* c = static_cast<SVGColor*>(value);
99     Color color;
100     if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
101         color = style->color();
102     else
103         color = c->color();
104     return color;
105 }
106 
applySVGProperty(int id,CSSValue * value)107 void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
108 {
109     ASSERT(value);
110     CSSPrimitiveValue* primitiveValue = 0;
111     if (value->isPrimitiveValue())
112         primitiveValue = static_cast<CSSPrimitiveValue*>(value);
113 
114     SVGRenderStyle* svgstyle = m_style->accessSVGStyle();
115     unsigned short valueType = value->cssValueType();
116 
117     bool isInherit = m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT;
118     bool isInitial = valueType == CSSPrimitiveValue::CSS_INITIAL || (!m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT);
119 
120     // What follows is a list that maps the CSS properties into their
121     // corresponding front-end RenderStyle values. Shorthands(e.g. border,
122     // background) occur in this list as well and are only hit when mapping
123     // "inherit" or "initial" into front-end values.
124     switch (id)
125     {
126         // ident only properties
127         case CSSPropertyAlignmentBaseline:
128         {
129             HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline)
130             if (!primitiveValue)
131                 break;
132 
133             svgstyle->setAlignmentBaseline(*primitiveValue);
134             break;
135         }
136         case CSSPropertyBaselineShift:
137         {
138             HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
139             if (!primitiveValue)
140                 break;
141 
142             if (primitiveValue->getIdent()) {
143                 switch (primitiveValue->getIdent()) {
144                 case CSSValueBaseline:
145                     svgstyle->setBaselineShift(BS_BASELINE);
146                     break;
147                 case CSSValueSub:
148                     svgstyle->setBaselineShift(BS_SUB);
149                     break;
150                 case CSSValueSuper:
151                     svgstyle->setBaselineShift(BS_SUPER);
152                     break;
153                 default:
154                     break;
155                 }
156             } else {
157                 svgstyle->setBaselineShift(BS_LENGTH);
158                 svgstyle->setBaselineShiftValue(primitiveValue);
159             }
160 
161             break;
162         }
163         case CSSPropertyKerning:
164         {
165             HANDLE_INHERIT_AND_INITIAL(kerning, Kerning);
166             svgstyle->setKerning(primitiveValue);
167             break;
168         }
169         case CSSPropertyDominantBaseline:
170         {
171             HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline)
172             if (primitiveValue)
173                 svgstyle->setDominantBaseline(*primitiveValue);
174             break;
175         }
176         case CSSPropertyColorInterpolation:
177         {
178             HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation)
179             if (primitiveValue)
180                 svgstyle->setColorInterpolation(*primitiveValue);
181             break;
182         }
183         case CSSPropertyColorInterpolationFilters:
184         {
185             HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters)
186             if (primitiveValue)
187                 svgstyle->setColorInterpolationFilters(*primitiveValue);
188             break;
189         }
190         case CSSPropertyColorRendering:
191         {
192             HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering)
193             if (primitiveValue)
194                 svgstyle->setColorRendering(*primitiveValue);
195             break;
196         }
197         case CSSPropertyClipRule:
198         {
199             HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule)
200             if (primitiveValue)
201                 svgstyle->setClipRule(*primitiveValue);
202             break;
203         }
204         case CSSPropertyFillRule:
205         {
206             HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule)
207             if (primitiveValue)
208                 svgstyle->setFillRule(*primitiveValue);
209             break;
210         }
211         case CSSPropertyStrokeLinejoin:
212         {
213             HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle)
214             if (primitiveValue)
215                 svgstyle->setJoinStyle(*primitiveValue);
216             break;
217         }
218         case CSSPropertyImageRendering:
219         {
220             HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering)
221             if (primitiveValue)
222                 svgstyle->setImageRendering(*primitiveValue);
223             break;
224         }
225         case CSSPropertyShapeRendering:
226         {
227             HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering)
228             if (primitiveValue)
229                 svgstyle->setShapeRendering(*primitiveValue);
230             break;
231         }
232         case CSSPropertyTextRendering:
233         {
234             HANDLE_INHERIT_AND_INITIAL(textRendering, TextRendering)
235             if (primitiveValue)
236                 svgstyle->setTextRendering(*primitiveValue);
237             break;
238         }
239         // end of ident only properties
240         case CSSPropertyFill:
241         {
242             HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint)
243             if (value->isSVGPaint())
244                 svgstyle->setFillPaint(static_cast<SVGPaint*>(value));
245             break;
246         }
247         case CSSPropertyStroke:
248         {
249             HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint)
250             if (value->isSVGPaint())
251                 svgstyle->setStrokePaint(static_cast<SVGPaint*>(value));
252 
253             break;
254         }
255         case CSSPropertyStrokeWidth:
256         {
257             HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
258             if (primitiveValue)
259                 svgstyle->setStrokeWidth(primitiveValue);
260             break;
261         }
262         case CSSPropertyStrokeDasharray:
263         {
264             HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
265             if (value->isValueList())
266                 svgstyle->setStrokeDashArray(static_cast<CSSValueList*>(value));
267             break;
268         }
269         case CSSPropertyStrokeDashoffset:
270         {
271             HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
272             if (primitiveValue)
273                 svgstyle->setStrokeDashOffset(primitiveValue);
274             break;
275         }
276         case CSSPropertyFillOpacity:
277         {
278             HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity)
279             if (!primitiveValue)
280                 return;
281 
282             float f = 0.0f;
283             int type = primitiveValue->primitiveType();
284             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
285                 f = primitiveValue->getFloatValue() / 100.0f;
286             else if (type == CSSPrimitiveValue::CSS_NUMBER)
287                 f = primitiveValue->getFloatValue();
288             else
289                 return;
290 
291             svgstyle->setFillOpacity(f);
292             break;
293         }
294         case CSSPropertyStrokeOpacity:
295         {
296             HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity)
297             if (!primitiveValue)
298                 return;
299 
300             float f = 0.0f;
301             int type = primitiveValue->primitiveType();
302             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
303                 f = primitiveValue->getFloatValue() / 100.0f;
304             else if (type == CSSPrimitiveValue::CSS_NUMBER)
305                 f = primitiveValue->getFloatValue();
306             else
307                 return;
308 
309             svgstyle->setStrokeOpacity(f);
310             break;
311         }
312         case CSSPropertyStopOpacity:
313         {
314             HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity)
315             if (!primitiveValue)
316                 return;
317 
318             float f = 0.0f;
319             int type = primitiveValue->primitiveType();
320             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
321                 f = primitiveValue->getFloatValue() / 100.0f;
322             else if (type == CSSPrimitiveValue::CSS_NUMBER)
323                 f = primitiveValue->getFloatValue();
324             else
325                 return;
326 
327             svgstyle->setStopOpacity(f);
328             break;
329         }
330         case CSSPropertyMarkerStart:
331         {
332             HANDLE_INHERIT_AND_INITIAL(startMarker, StartMarker)
333             if (!primitiveValue)
334                 return;
335 
336             String s;
337             int type = primitiveValue->primitiveType();
338             if (type == CSSPrimitiveValue::CSS_URI)
339                 s = primitiveValue->getStringValue();
340             else
341                 return;
342 
343             svgstyle->setStartMarker(SVGURIReference::getTarget(s));
344             break;
345         }
346         case CSSPropertyMarkerMid:
347         {
348             HANDLE_INHERIT_AND_INITIAL(midMarker, MidMarker)
349             if (!primitiveValue)
350                 return;
351 
352             String s;
353             int type = primitiveValue->primitiveType();
354             if (type == CSSPrimitiveValue::CSS_URI)
355                 s = primitiveValue->getStringValue();
356             else
357                 return;
358 
359             svgstyle->setMidMarker(SVGURIReference::getTarget(s));
360             break;
361         }
362         case CSSPropertyMarkerEnd:
363         {
364             HANDLE_INHERIT_AND_INITIAL(endMarker, EndMarker)
365             if (!primitiveValue)
366                 return;
367 
368             String s;
369             int type = primitiveValue->primitiveType();
370             if (type == CSSPrimitiveValue::CSS_URI)
371                 s = primitiveValue->getStringValue();
372             else
373                 return;
374 
375             svgstyle->setEndMarker(SVGURIReference::getTarget(s));
376             break;
377         }
378         case CSSPropertyStrokeLinecap:
379         {
380             HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle)
381             if (primitiveValue)
382                 svgstyle->setCapStyle(*primitiveValue);
383             break;
384         }
385         case CSSPropertyStrokeMiterlimit:
386         {
387             HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit)
388             if (!primitiveValue)
389                 return;
390 
391             float f = 0.0f;
392             int type = primitiveValue->primitiveType();
393             if (type == CSSPrimitiveValue::CSS_NUMBER)
394                 f = primitiveValue->getFloatValue();
395             else
396                 return;
397 
398             svgstyle->setStrokeMiterLimit(f);
399             break;
400         }
401         case CSSPropertyFilter:
402         {
403             HANDLE_INHERIT_AND_INITIAL(filter, Filter)
404             if (!primitiveValue)
405                 return;
406 
407             String s;
408             int type = primitiveValue->primitiveType();
409             if (type == CSSPrimitiveValue::CSS_URI)
410                 s = primitiveValue->getStringValue();
411             else
412                 return;
413             svgstyle->setFilter(SVGURIReference::getTarget(s));
414             break;
415         }
416         case CSSPropertyMask:
417         {
418             HANDLE_INHERIT_AND_INITIAL(maskElement, MaskElement)
419             if (!primitiveValue)
420                 return;
421 
422             String s;
423             int type = primitiveValue->primitiveType();
424             if (type == CSSPrimitiveValue::CSS_URI)
425                 s = primitiveValue->getStringValue();
426             else
427                 return;
428 
429             svgstyle->setMaskElement(SVGURIReference::getTarget(s));
430             break;
431         }
432         case CSSPropertyClipPath:
433         {
434             HANDLE_INHERIT_AND_INITIAL(clipPath, ClipPath)
435             if (!primitiveValue)
436                 return;
437 
438             String s;
439             int type = primitiveValue->primitiveType();
440             if (type == CSSPrimitiveValue::CSS_URI)
441                 s = primitiveValue->getStringValue();
442             else
443                 return;
444 
445             svgstyle->setClipPath(SVGURIReference::getTarget(s));
446             break;
447         }
448         case CSSPropertyTextAnchor:
449         {
450             HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor)
451             if (primitiveValue)
452                 svgstyle->setTextAnchor(*primitiveValue);
453             break;
454         }
455         case CSSPropertyWritingMode:
456         {
457             HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode)
458             if (primitiveValue)
459                 svgstyle->setWritingMode(*primitiveValue);
460             break;
461         }
462         case CSSPropertyStopColor:
463         {
464             HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
465             svgstyle->setStopColor(colorFromSVGColorCSSValue(value, m_style.get()));
466             break;
467         }
468        case CSSPropertyLightingColor:
469         {
470             HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
471             svgstyle->setLightingColor(colorFromSVGColorCSSValue(value, m_style.get()));
472             break;
473         }
474         case CSSPropertyFloodOpacity:
475         {
476             HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity)
477             if (!primitiveValue)
478                 return;
479 
480             float f = 0.0f;
481             int type = primitiveValue->primitiveType();
482             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
483                 f = primitiveValue->getFloatValue() / 100.0f;
484             else if (type == CSSPrimitiveValue::CSS_NUMBER)
485                 f = primitiveValue->getFloatValue();
486             else
487                 return;
488 
489             svgstyle->setFloodOpacity(f);
490             break;
491         }
492         case CSSPropertyFloodColor:
493         {
494             if (isInitial) {
495                 svgstyle->setFloodColor(SVGRenderStyle::initialFloodColor());
496                 return;
497             }
498             svgstyle->setFloodColor(colorFromSVGColorCSSValue(value, m_style.get()));
499             break;
500         }
501         case CSSPropertyGlyphOrientationHorizontal:
502         {
503             HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal)
504             if (!primitiveValue)
505                 return;
506 
507             if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
508                 int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
509                 ASSERT(orientation != -1);
510 
511                 svgstyle->setGlyphOrientationHorizontal((EGlyphOrientation) orientation);
512             }
513 
514             break;
515         }
516         case CSSPropertyGlyphOrientationVertical:
517         {
518             HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical)
519             if (!primitiveValue)
520                 return;
521 
522             if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
523                 int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
524                 ASSERT(orientation != -1);
525 
526                 svgstyle->setGlyphOrientationVertical((EGlyphOrientation) orientation);
527             } else if (primitiveValue->getIdent() == CSSValueAuto)
528                 svgstyle->setGlyphOrientationVertical(GO_AUTO);
529 
530             break;
531         }
532         case CSSPropertyEnableBackground:
533             // Silently ignoring this property for now
534             // http://bugs.webkit.org/show_bug.cgi?id=6022
535             break;
536         default:
537             // If you crash here, it's because you added a css property and are not handling it
538             // in either this switch statement or the one in CSSStyleSelector::applyProperty
539             ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id);
540             return;
541     }
542 }
543 
544 }
545 
546 // vim:ts=4:noet
547 #endif // ENABLE(SVG)
548