OSDN Git Service

am 3c54ece0: am 5dc34a85: activeDocumentLoader() causes crash in WebCoreFrameBridge.cpp
[android-x86/external-webkit.git] / WebCore / css / SVGCSSStyleSelector.cpp
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 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.
17
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.
22
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.
27 */
28
29 #include "config.h"
30
31 #if ENABLE(SVG)
32 #include "CSSStyleSelector.h"
33
34 #include "CSSPrimitiveValueMappings.h"
35 #include "CSSPropertyNames.h"
36 #include "CSSValueList.h"
37 #include "Document.h"
38 #include "ShadowValue.h"
39 #include "SVGColor.h"
40 #include "SVGNames.h"
41 #include "SVGPaint.h"
42 #include "SVGRenderStyle.h"
43 #include "SVGRenderStyleDefs.h"
44 #include "SVGStyledElement.h"
45 #include "SVGURIReference.h"
46 #include <stdlib.h>
47 #include <wtf/MathExtras.h>
48
49 #define HANDLE_INHERIT(prop, Prop) \
50 if (isInherit) \
51 {\
52     svgstyle->set##Prop(m_parentStyle->svgStyle()->prop());\
53     return;\
54 }
55
56 #define HANDLE_INHERIT_AND_INITIAL(prop, Prop) \
57 HANDLE_INHERIT(prop, Prop) \
58 else if (isInitial) \
59     svgstyle->set##Prop(SVGRenderStyle::initial##Prop());
60
61 namespace WebCore {
62
63 static float roundToNearestGlyphOrientationAngle(float angle)
64 {
65     angle = fabsf(fmodf(angle, 360.0f));
66
67     if (angle <= 45.0f || angle > 315.0f)
68         return 0.0f;
69     else if (angle > 45.0f && angle <= 135.0f)
70         return 90.0f;
71     else if (angle > 135.0f && angle <= 225.0f)
72         return 180.0f;
73
74     return 270.0f;
75 }
76
77 static int angleToGlyphOrientation(float angle)
78 {
79     angle = roundToNearestGlyphOrientationAngle(angle);
80
81     if (angle == 0.0f)
82         return GO_0DEG;
83     else if (angle == 90.0f)
84         return GO_90DEG;
85     else if (angle == 180.0f)
86         return GO_180DEG;
87     else if (angle == 270.0f)
88         return GO_270DEG;
89
90     return -1;
91 }
92
93 static Color colorFromSVGColorCSSValue(CSSValue* value, const Color& fgColor)
94 {
95     ASSERT(value->isSVGColor());
96     SVGColor* c = static_cast<SVGColor*>(value);
97     Color color;
98     if (c->colorType() == SVGColor::SVG_COLORTYPE_CURRENTCOLOR)
99         color = fgColor;
100     else
101         color = c->color();
102     return color;
103 }
104
105 void CSSStyleSelector::applySVGProperty(int id, CSSValue* value)
106 {
107     ASSERT(value);
108     CSSPrimitiveValue* primitiveValue = 0;
109     if (value->isPrimitiveValue())
110         primitiveValue = static_cast<CSSPrimitiveValue*>(value);
111
112     SVGRenderStyle* svgstyle = m_style->accessSVGStyle();
113     unsigned short valueType = value->cssValueType();
114     
115     bool isInherit = m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT;
116     bool isInitial = valueType == CSSPrimitiveValue::CSS_INITIAL || (!m_parentNode && valueType == CSSPrimitiveValue::CSS_INHERIT);
117
118     // What follows is a list that maps the CSS properties into their
119     // corresponding front-end RenderStyle values. Shorthands(e.g. border,
120     // background) occur in this list as well and are only hit when mapping
121     // "inherit" or "initial" into front-end values.
122     switch (id)
123     {
124         // ident only properties
125         case CSSPropertyAlignmentBaseline:
126         {
127             HANDLE_INHERIT_AND_INITIAL(alignmentBaseline, AlignmentBaseline)
128             if (!primitiveValue)
129                 break;
130             
131             svgstyle->setAlignmentBaseline(*primitiveValue);
132             break;
133         }
134         case CSSPropertyBaselineShift:
135         {
136             HANDLE_INHERIT_AND_INITIAL(baselineShift, BaselineShift);
137             if (!primitiveValue)
138                 break;
139
140             if (primitiveValue->getIdent()) {
141                 switch (primitiveValue->getIdent()) {
142                 case CSSValueBaseline:
143                     svgstyle->setBaselineShift(BS_BASELINE);
144                     break;
145                 case CSSValueSub:
146                     svgstyle->setBaselineShift(BS_SUB);
147                     break;
148                 case CSSValueSuper:
149                     svgstyle->setBaselineShift(BS_SUPER);
150                     break;
151                 default:
152                     break;
153                 }
154             } else {
155                 svgstyle->setBaselineShift(BS_LENGTH);
156                 svgstyle->setBaselineShiftValue(SVGLength::fromCSSPrimitiveValue(primitiveValue));
157             }
158
159             break;
160         }
161         case CSSPropertyKerning:
162         {
163             HANDLE_INHERIT_AND_INITIAL(kerning, Kerning);
164             svgstyle->setKerning(SVGLength::fromCSSPrimitiveValue(primitiveValue));
165             break;
166         }
167         case CSSPropertyDominantBaseline:
168         {
169             HANDLE_INHERIT_AND_INITIAL(dominantBaseline, DominantBaseline)
170             if (primitiveValue)
171                 svgstyle->setDominantBaseline(*primitiveValue);
172             break;
173         }
174         case CSSPropertyColorInterpolation:
175         {
176             HANDLE_INHERIT_AND_INITIAL(colorInterpolation, ColorInterpolation)
177             if (primitiveValue)
178                 svgstyle->setColorInterpolation(*primitiveValue);
179             break;
180         }
181         case CSSPropertyColorInterpolationFilters:
182         {
183             HANDLE_INHERIT_AND_INITIAL(colorInterpolationFilters, ColorInterpolationFilters)
184             if (primitiveValue)
185                 svgstyle->setColorInterpolationFilters(*primitiveValue);
186             break;
187         }
188         case CSSPropertyColorRendering:
189         {
190             HANDLE_INHERIT_AND_INITIAL(colorRendering, ColorRendering)
191             if (primitiveValue)
192                 svgstyle->setColorRendering(*primitiveValue);
193             break;
194         }
195         case CSSPropertyClipRule:
196         {
197             HANDLE_INHERIT_AND_INITIAL(clipRule, ClipRule)
198             if (primitiveValue)
199                 svgstyle->setClipRule(*primitiveValue);
200             break;
201         }
202         case CSSPropertyFillRule:
203         {
204             HANDLE_INHERIT_AND_INITIAL(fillRule, FillRule)
205             if (primitiveValue)
206                 svgstyle->setFillRule(*primitiveValue);
207             break;
208         }
209         case CSSPropertyStrokeLinejoin:
210         {
211             HANDLE_INHERIT_AND_INITIAL(joinStyle, JoinStyle)
212             if (primitiveValue)
213                 svgstyle->setJoinStyle(*primitiveValue);
214             break;
215         }
216         case CSSPropertyImageRendering:
217         {
218             HANDLE_INHERIT_AND_INITIAL(imageRendering, ImageRendering)
219             if (primitiveValue)
220                 svgstyle->setImageRendering(*primitiveValue);
221             break;
222         }
223         case CSSPropertyShapeRendering:
224         {
225             HANDLE_INHERIT_AND_INITIAL(shapeRendering, ShapeRendering)
226             if (primitiveValue)
227                 svgstyle->setShapeRendering(*primitiveValue);
228             break;
229         }
230         // end of ident only properties
231         case CSSPropertyFill:
232         {
233             HANDLE_INHERIT_AND_INITIAL(fillPaint, FillPaint)
234             if (value->isSVGPaint())
235                 svgstyle->setFillPaint(static_cast<SVGPaint*>(value));
236             break;
237         }
238         case CSSPropertyStroke:
239         {
240             HANDLE_INHERIT_AND_INITIAL(strokePaint, StrokePaint)
241             if (value->isSVGPaint())
242                 svgstyle->setStrokePaint(static_cast<SVGPaint*>(value));
243             
244             break;
245         }
246         case CSSPropertyStrokeWidth:
247         {
248             HANDLE_INHERIT_AND_INITIAL(strokeWidth, StrokeWidth)
249             if (primitiveValue)
250                 svgstyle->setStrokeWidth(SVGLength::fromCSSPrimitiveValue(primitiveValue));
251             break;
252         }
253         case CSSPropertyStrokeDasharray:
254         {
255             HANDLE_INHERIT_AND_INITIAL(strokeDashArray, StrokeDashArray)
256             if (!value->isValueList())
257                 break;
258
259             CSSValueList* dashes = static_cast<CSSValueList*>(value);
260
261             Vector<SVGLength> array;
262             size_t length = dashes->length();
263             for (size_t i = 0; i < length; ++i) {
264                 CSSPrimitiveValue* dash = static_cast<CSSPrimitiveValue*>(dashes->itemWithoutBoundsCheck(i));
265                 if (!dash)
266                     continue;
267
268                 array.append(SVGLength::fromCSSPrimitiveValue(dash));
269             }
270
271             svgstyle->setStrokeDashArray(array);
272             break;
273         }
274         case CSSPropertyStrokeDashoffset:
275         {
276             HANDLE_INHERIT_AND_INITIAL(strokeDashOffset, StrokeDashOffset)
277             if (primitiveValue)
278                 svgstyle->setStrokeDashOffset(SVGLength::fromCSSPrimitiveValue(primitiveValue));
279             break;
280         }
281         case CSSPropertyFillOpacity:
282         {
283             HANDLE_INHERIT_AND_INITIAL(fillOpacity, FillOpacity)
284             if (!primitiveValue)
285                 return;
286         
287             float f = 0.0f;    
288             int type = primitiveValue->primitiveType();
289             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
290                 f = primitiveValue->getFloatValue() / 100.0f;
291             else if (type == CSSPrimitiveValue::CSS_NUMBER)
292                 f = primitiveValue->getFloatValue();
293             else
294                 return;
295
296             svgstyle->setFillOpacity(f);
297             break;
298         }
299         case CSSPropertyStrokeOpacity:
300         {
301             HANDLE_INHERIT_AND_INITIAL(strokeOpacity, StrokeOpacity)
302             if (!primitiveValue)
303                 return;
304         
305             float f = 0.0f;    
306             int type = primitiveValue->primitiveType();
307             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
308                 f = primitiveValue->getFloatValue() / 100.0f;
309             else if (type == CSSPrimitiveValue::CSS_NUMBER)
310                 f = primitiveValue->getFloatValue();
311             else
312                 return;
313
314             svgstyle->setStrokeOpacity(f);
315             break;
316         }
317         case CSSPropertyStopOpacity:
318         {
319             HANDLE_INHERIT_AND_INITIAL(stopOpacity, StopOpacity)
320             if (!primitiveValue)
321                 return;
322         
323             float f = 0.0f;    
324             int type = primitiveValue->primitiveType();
325             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
326                 f = primitiveValue->getFloatValue() / 100.0f;
327             else if (type == CSSPrimitiveValue::CSS_NUMBER)
328                 f = primitiveValue->getFloatValue();
329             else
330                 return;
331
332             svgstyle->setStopOpacity(f);
333             break;
334         }
335         case CSSPropertyMarkerStart:
336         {
337             HANDLE_INHERIT_AND_INITIAL(markerStartResource, MarkerStartResource)
338             if (!primitiveValue)
339                 return;
340
341             String s;
342             int type = primitiveValue->primitiveType();
343             if (type == CSSPrimitiveValue::CSS_URI)
344                 s = primitiveValue->getStringValue();
345             else
346                 return;
347
348             svgstyle->setMarkerStartResource(SVGURIReference::getTarget(s));
349             break;
350         }
351         case CSSPropertyMarkerMid:
352         {
353             HANDLE_INHERIT_AND_INITIAL(markerMidResource, MarkerMidResource)
354             if (!primitiveValue)
355                 return;
356
357             String s;
358             int type = primitiveValue->primitiveType();
359             if (type == CSSPrimitiveValue::CSS_URI)
360                 s = primitiveValue->getStringValue();
361             else
362                 return;
363
364             svgstyle->setMarkerMidResource(SVGURIReference::getTarget(s));
365             break;
366         }
367         case CSSPropertyMarkerEnd:
368         {
369             HANDLE_INHERIT_AND_INITIAL(markerEndResource, MarkerEndResource)
370             if (!primitiveValue)
371                 return;
372
373             String s;
374             int type = primitiveValue->primitiveType();
375             if (type == CSSPrimitiveValue::CSS_URI)
376                 s = primitiveValue->getStringValue();
377             else
378                 return;
379
380             svgstyle->setMarkerEndResource(SVGURIReference::getTarget(s));
381             break;
382         }
383         case CSSPropertyStrokeLinecap:
384         {
385             HANDLE_INHERIT_AND_INITIAL(capStyle, CapStyle)
386             if (primitiveValue)
387                 svgstyle->setCapStyle(*primitiveValue);
388             break;
389         }
390         case CSSPropertyStrokeMiterlimit:
391         {
392             HANDLE_INHERIT_AND_INITIAL(strokeMiterLimit, StrokeMiterLimit)
393             if (!primitiveValue)
394                 return;
395
396             float f = 0.0f;
397             int type = primitiveValue->primitiveType();
398             if (type == CSSPrimitiveValue::CSS_NUMBER)
399                 f = primitiveValue->getFloatValue();
400             else
401                 return;
402
403             svgstyle->setStrokeMiterLimit(f);
404             break;
405         }
406         case CSSPropertyFilter:
407         {
408             HANDLE_INHERIT_AND_INITIAL(filterResource, FilterResource)
409             if (!primitiveValue)
410                 return;
411
412             String s;
413             int type = primitiveValue->primitiveType();
414             if (type == CSSPrimitiveValue::CSS_URI)
415                 s = primitiveValue->getStringValue();
416             else
417                 return;
418
419             svgstyle->setFilterResource(SVGURIReference::getTarget(s));
420             break;
421         }
422         case CSSPropertyMask:
423         {
424             HANDLE_INHERIT_AND_INITIAL(maskerResource, MaskerResource)
425             if (!primitiveValue)
426                 return;
427
428             String s;
429             int type = primitiveValue->primitiveType();
430             if (type == CSSPrimitiveValue::CSS_URI)
431                 s = primitiveValue->getStringValue();
432             else
433                 return;
434             
435             svgstyle->setMaskerResource(SVGURIReference::getTarget(s));
436             break;
437         }
438         case CSSPropertyClipPath:
439         {
440             HANDLE_INHERIT_AND_INITIAL(clipperResource, ClipperResource)
441             if (!primitiveValue)
442                 return;
443
444             String s;
445             int type = primitiveValue->primitiveType();
446             if (type == CSSPrimitiveValue::CSS_URI)
447                 s = primitiveValue->getStringValue();
448             else
449                 return;
450
451             svgstyle->setClipperResource(SVGURIReference::getTarget(s));
452             break;
453         }
454         case CSSPropertyTextAnchor:
455         {
456             HANDLE_INHERIT_AND_INITIAL(textAnchor, TextAnchor)
457             if (primitiveValue)
458                 svgstyle->setTextAnchor(*primitiveValue);
459             break;
460         }
461         case CSSPropertyWritingMode:
462         {
463             HANDLE_INHERIT_AND_INITIAL(writingMode, WritingMode)
464             if (primitiveValue)
465                 svgstyle->setWritingMode(*primitiveValue);
466             break;
467         }
468         case CSSPropertyStopColor:
469         {
470             HANDLE_INHERIT_AND_INITIAL(stopColor, StopColor);
471             svgstyle->setStopColor(colorFromSVGColorCSSValue(value, m_style->color()));
472             break;
473         }
474        case CSSPropertyLightingColor:
475         {
476             HANDLE_INHERIT_AND_INITIAL(lightingColor, LightingColor);
477             svgstyle->setLightingColor(colorFromSVGColorCSSValue(value, m_style->color()));
478             break;
479         }
480         case CSSPropertyFloodOpacity:
481         {
482             HANDLE_INHERIT_AND_INITIAL(floodOpacity, FloodOpacity)
483             if (!primitiveValue)
484                 return;
485
486             float f = 0.0f;
487             int type = primitiveValue->primitiveType();
488             if (type == CSSPrimitiveValue::CSS_PERCENTAGE)
489                 f = primitiveValue->getFloatValue() / 100.0f;
490             else if (type == CSSPrimitiveValue::CSS_NUMBER)
491                 f = primitiveValue->getFloatValue();
492             else
493                 return;
494
495             svgstyle->setFloodOpacity(f);
496             break;
497         }
498         case CSSPropertyFloodColor:
499         {
500             if (isInitial) {
501                 svgstyle->setFloodColor(SVGRenderStyle::initialFloodColor());
502                 return;
503             }
504             svgstyle->setFloodColor(colorFromSVGColorCSSValue(value, m_style->color()));
505             break;
506         }
507         case CSSPropertyGlyphOrientationHorizontal:
508         {
509             HANDLE_INHERIT_AND_INITIAL(glyphOrientationHorizontal, GlyphOrientationHorizontal)
510             if (!primitiveValue)
511                 return;
512
513             if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
514                 int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
515                 ASSERT(orientation != -1);
516
517                 svgstyle->setGlyphOrientationHorizontal((EGlyphOrientation) orientation);
518             }
519
520             break;
521         }
522         case CSSPropertyGlyphOrientationVertical:
523         {
524             HANDLE_INHERIT_AND_INITIAL(glyphOrientationVertical, GlyphOrientationVertical)
525             if (!primitiveValue)
526                 return;
527
528             if (primitiveValue->primitiveType() == CSSPrimitiveValue::CSS_DEG) {
529                 int orientation = angleToGlyphOrientation(primitiveValue->getFloatValue());
530                 ASSERT(orientation != -1);
531
532                 svgstyle->setGlyphOrientationVertical((EGlyphOrientation) orientation);
533             } else if (primitiveValue->getIdent() == CSSValueAuto)
534                 svgstyle->setGlyphOrientationVertical(GO_AUTO);
535
536             break;
537         }
538         case CSSPropertyEnableBackground:
539             // Silently ignoring this property for now
540             // http://bugs.webkit.org/show_bug.cgi?id=6022
541             break;
542         case CSSPropertyWebkitSvgShadow: {
543             if (isInherit)
544                 return svgstyle->setShadow(m_parentStyle->svgStyle()->shadow() ? new ShadowData(*m_parentStyle->svgStyle()->shadow()) : 0);
545             if (isInitial || primitiveValue) // initial | none
546                 return svgstyle->setShadow(0);
547
548             if (!value->isValueList())
549                 return;
550
551             CSSValueList *list = static_cast<CSSValueList*>(value);
552             ASSERT(list->length() == 1);
553             ShadowValue* item = static_cast<ShadowValue*>(list->itemWithoutBoundsCheck(0));
554             int x = item->x->computeLengthInt(style(), m_rootElementStyle);
555             int y = item->y->computeLengthInt(style(), m_rootElementStyle);
556             int blur = item->blur ? item->blur->computeLengthInt(style(), m_rootElementStyle) : 0;
557             Color color;
558             if (item->color)
559                 color = getColorFromPrimitiveValue(item->color.get());
560
561             // -webkit-svg-shadow does should not have a spread or style
562             ASSERT(!item->spread);
563             ASSERT(!item->style);
564                 
565             ShadowData* shadowData = new ShadowData(x, y, blur, 0, Normal, color.isValid() ? color : Color::transparent);
566             svgstyle->setShadow(shadowData);
567             return;
568         }
569         case CSSPropertyVectorEffect: {
570             HANDLE_INHERIT_AND_INITIAL(vectorEffect, VectorEffect)
571             if (!primitiveValue)
572                 break;
573
574             svgstyle->setVectorEffect(*primitiveValue);
575             break;
576         }
577         default:
578             // If you crash here, it's because you added a css property and are not handling it
579             // in either this switch statement or the one in CSSStyleSelector::applyProperty
580             ASSERT_WITH_MESSAGE(0, "unimplemented propertyID: %d", id);
581             return;
582     }
583 }
584
585 }
586
587 #endif