1 /*
2 * Copyright (C) 2004, 2005 Nikolas Zimmermann <zimmermann@kde.org>
3 * Copyright (C) 2004, 2005, 2006, 2007 Rob Buis <buis@kde.org>
4 * Copyright (C) Research In Motion Limited 2010-2011. All rights reserved.
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Library General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Library General Public License for more details.
15 *
16 * You should have received a copy of the GNU Library General Public License
17 * along with this library; see the file COPYING.LIB. If not, write to
18 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 * Boston, MA 02110-1301, USA.
20 */
21
22 #include "config.h"
23
24 #if ENABLE(SVG)
25 #include "SVGPaint.h"
26
27 #include "SVGException.h"
28 #include "SVGURIReference.h"
29 #include <wtf/text/StringConcatenate.h>
30
31 namespace WebCore {
32
colorTypeForPaintType(const SVGPaint::SVGPaintType & paintType)33 static inline SVGColor::SVGColorType colorTypeForPaintType(const SVGPaint::SVGPaintType& paintType)
34 {
35 switch (paintType) {
36 case SVGPaint::SVG_PAINTTYPE_NONE:
37 case SVGPaint::SVG_PAINTTYPE_UNKNOWN:
38 case SVGPaint::SVG_PAINTTYPE_URI:
39 case SVGPaint::SVG_PAINTTYPE_URI_NONE:
40 return SVGColor::SVG_COLORTYPE_UNKNOWN;
41 case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR:
42 case SVGPaint::SVG_PAINTTYPE_RGBCOLOR:
43 return SVGColor::SVG_COLORTYPE_RGBCOLOR;
44 case SVGPaint::SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
45 case SVGPaint::SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
46 return SVGColor::SVG_COLORTYPE_RGBCOLOR_ICCCOLOR;
47 case SVGPaint::SVG_PAINTTYPE_URI_CURRENTCOLOR:
48 case SVGPaint::SVG_PAINTTYPE_CURRENTCOLOR:
49 return SVGColor::SVG_COLORTYPE_CURRENTCOLOR;
50 }
51
52 ASSERT_NOT_REACHED();
53 return SVGColor::SVG_COLORTYPE_UNKNOWN;
54 }
55
SVGPaint(const SVGPaintType & paintType,String uri)56 SVGPaint::SVGPaint(const SVGPaintType& paintType, String uri)
57 : SVGColor(colorTypeForPaintType(paintType))
58 , m_paintType(paintType)
59 , m_uri(uri)
60 {
61 }
62
setUri(const String & uri)63 void SVGPaint::setUri(const String& uri)
64 {
65 // Spec: Sets the paintType to SVG_PAINTTYPE_URI_NONE and sets uri to the specified value.
66 m_uri = uri;
67 m_paintType = SVG_PAINTTYPE_URI_NONE;
68 setColor(Color());
69 setColorType(colorTypeForPaintType(m_paintType));
70 // FIXME: A follow up patch will call valueChanged() here.
71 }
72
defaultFill()73 SVGPaint* SVGPaint::defaultFill()
74 {
75 static SVGPaint* staticDefaultFill = createColor(Color::black).releaseRef();
76 return staticDefaultFill;
77 }
78
defaultStroke()79 SVGPaint* SVGPaint::defaultStroke()
80 {
81 static SVGPaint* staticDefaultStroke = createNone().releaseRef();
82 return staticDefaultStroke;
83 }
84
setPaint(unsigned short paintType,const String & uri,const String & rgbColor,const String & iccColor,ExceptionCode & ec)85 void SVGPaint::setPaint(unsigned short paintType, const String& uri, const String& rgbColor, const String& iccColor, ExceptionCode& ec)
86 {
87 if ((paintType > SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR && paintType < SVG_PAINTTYPE_NONE) || paintType > SVG_PAINTTYPE_URI) {
88 ec = SVGException::SVG_WRONG_TYPE_ERR;
89 return;
90 }
91
92 bool requiresURI = false;
93
94 SVGPaintType type = static_cast<SVGPaintType>(paintType);
95 switch (type) {
96 case SVG_PAINTTYPE_UNKNOWN:
97 // Spec: It is invalid to attempt to define a new value of this type or to attempt to switch an existing value to this type.
98 ec = SVGException::SVG_INVALID_VALUE_ERR;
99 return;
100 case SVG_PAINTTYPE_RGBCOLOR:
101 case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
102 case SVG_PAINTTYPE_NONE:
103 case SVG_PAINTTYPE_CURRENTCOLOR:
104 break;
105 case SVG_PAINTTYPE_URI_NONE:
106 case SVG_PAINTTYPE_URI_CURRENTCOLOR:
107 case SVG_PAINTTYPE_URI_RGBCOLOR:
108 case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
109 case SVG_PAINTTYPE_URI:
110 requiresURI = true;
111 break;
112 };
113
114 // Spec: If paintType requires a URI, then uri must be non-null; otherwise, uri must be null.
115 if (requiresURI && uri.isEmpty()) {
116 ec = SVGException::SVG_INVALID_VALUE_ERR;
117 return;
118 }
119
120 SVGColor::SVGColorType colorType = colorTypeForPaintType(type);
121 if (colorType == SVGColor::SVG_COLORTYPE_UNKNOWN) {
122 // The standard setColor() code path used in the else branch
123 // raises an exception when attempting to switch to an unknown color type.
124 // Here we explicitely want to reset to Color() and an unknown type, so force it.
125 setColorType(colorType);
126 setColor(Color());
127 } else {
128 setColor(colorType, rgbColor, iccColor, ec);
129 if (ec)
130 return;
131 }
132
133 m_paintType = type;
134 m_uri = requiresURI ? uri : String();
135 // FIXME: A follow up patch will call valueChanged() here.
136 }
137
cssText() const138 String SVGPaint::cssText() const
139 {
140 switch (m_paintType) {
141 case SVG_PAINTTYPE_UNKNOWN:
142 case SVG_PAINTTYPE_RGBCOLOR:
143 case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
144 case SVG_PAINTTYPE_CURRENTCOLOR:
145 return SVGColor::cssText();
146 case SVG_PAINTTYPE_NONE:
147 return "none";
148 case SVG_PAINTTYPE_URI_NONE:
149 return makeString(m_uri, " none");
150 case SVG_PAINTTYPE_URI_CURRENTCOLOR:
151 case SVG_PAINTTYPE_URI_RGBCOLOR:
152 case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR: {
153 String color = SVGColor::cssText();
154 if (color.isEmpty())
155 return m_uri;
156 return makeString(m_uri, ' ', color);
157 }
158 case SVG_PAINTTYPE_URI:
159 return m_uri;
160 };
161
162 ASSERT_NOT_REACHED();
163 return String();
164 }
165
matchesTargetURI(const String & referenceId)166 bool SVGPaint::matchesTargetURI(const String& referenceId)
167 {
168 switch (m_paintType) {
169 case SVG_PAINTTYPE_UNKNOWN:
170 case SVG_PAINTTYPE_RGBCOLOR:
171 case SVG_PAINTTYPE_RGBCOLOR_ICCCOLOR:
172 case SVG_PAINTTYPE_CURRENTCOLOR:
173 case SVG_PAINTTYPE_NONE:
174 return false;
175 case SVG_PAINTTYPE_URI_NONE:
176 case SVG_PAINTTYPE_URI_CURRENTCOLOR:
177 case SVG_PAINTTYPE_URI_RGBCOLOR:
178 case SVG_PAINTTYPE_URI_RGBCOLOR_ICCCOLOR:
179 case SVG_PAINTTYPE_URI:
180 return referenceId == SVGURIReference::getTarget(m_uri);
181 }
182
183 ASSERT_NOT_REACHED();
184 return false;
185 }
186
187 }
188
189 #endif // ENABLE(SVG)
190