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 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 "SVGColor.h"
26
27#include "CSSParser.h"
28#include "RGBColor.h"
29#include "SVGException.h"
30
31namespace WebCore {
32
33SVGColor::SVGColor(const SVGColorType& colorType)
34    : m_colorType(colorType)
35{
36}
37
38PassRefPtr<RGBColor> SVGColor::rgbColor() const
39{
40    return RGBColor::create(m_color.rgb());
41}
42
43void SVGColor::setRGBColor(const String& rgbColor, ExceptionCode& ec)
44{
45    Color color = SVGColor::colorFromRGBColorString(rgbColor);
46    if (!color.isValid()) {
47        ec = SVGException::SVG_INVALID_VALUE_ERR;
48        return;
49    }
50
51    m_color = color;
52    m_colorType = SVG_COLORTYPE_RGBCOLOR;
53    // FIXME: A follow up patch will call valueChanged() here.
54}
55
56Color SVGColor::colorFromRGBColorString(const String& colorString)
57{
58    // FIXME: Rework css parser so it is more SVG aware.
59    RGBA32 color;
60    if (CSSParser::parseColor(color, colorString.stripWhiteSpace()))
61        return color;
62    return Color();
63}
64
65void SVGColor::setRGBColorICCColor(const String& rgbColor, const String& iccColor, ExceptionCode& ec)
66{
67    if (rgbColor.isEmpty() || iccColor.isEmpty()) {
68        ec = SVGException::SVG_INVALID_VALUE_ERR;
69        return;
70    }
71
72    // FIXME: No support for ICC colors. We're just ignoring it.
73    setRGBColor(rgbColor, ec);
74    if (ec)
75        return;
76
77    m_colorType = SVG_COLORTYPE_RGBCOLOR_ICCCOLOR;
78    // FIXME: A follow up patch will call valueChanged() here.
79}
80
81void SVGColor::setColor(unsigned short colorType, const String& rgbColor, const String& iccColor, ExceptionCode& ec)
82{
83    if (colorType > SVG_COLORTYPE_CURRENTCOLOR) {
84        ec = SVGException::SVG_WRONG_TYPE_ERR;
85        return;
86    }
87
88    bool requiresRGBColor = false;
89    bool requiresICCColor = false;
90
91    SVGColorType type = static_cast<SVGColorType>(colorType);
92    switch (type) {
93    case SVG_COLORTYPE_UNKNOWN:
94        // 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.
95        ec = SVGException::SVG_INVALID_VALUE_ERR;
96        return;
97    case SVG_COLORTYPE_RGBCOLOR_ICCCOLOR:
98        requiresICCColor = true;
99    case SVG_COLORTYPE_RGBCOLOR:
100        requiresRGBColor = true;
101        break;
102    case SVG_COLORTYPE_CURRENTCOLOR:
103        break;
104    }
105
106    // Spec: If colorType requires an RGBColor, then rgbColor must be a string that matches <color>; otherwise, rgbColor must be null.
107    if (requiresRGBColor && rgbColor.isEmpty()) {
108        ec = SVGException::SVG_INVALID_VALUE_ERR;
109        return;
110    }
111
112    // Spec: If colorType requires an SVGICCColor, then iccColor must be a string that matches <icccolor>; otherwise, iccColor must be null.
113    if (requiresICCColor && iccColor.isEmpty()) {
114        ec = SVGException::SVG_INVALID_VALUE_ERR;
115        return;
116    }
117
118    // FIXME: A follow up patch will call valueChanged() here.
119    m_colorType = type;
120    if (!requiresRGBColor) {
121        ASSERT(!requiresICCColor);
122        m_color = Color();
123        return;
124    }
125
126    if (requiresICCColor)
127        setRGBColorICCColor(rgbColor, iccColor, ec);
128    else
129        setRGBColor(rgbColor, ec);
130}
131
132String SVGColor::cssText() const
133{
134    switch (m_colorType) {
135    case SVG_COLORTYPE_UNKNOWN:
136        return String();
137    case SVG_COLORTYPE_RGBCOLOR_ICCCOLOR:
138    case SVG_COLORTYPE_RGBCOLOR:
139        // FIXME: No ICC color support.
140        return m_color.serialized();
141    case SVG_COLORTYPE_CURRENTCOLOR:
142        if (m_color.isValid())
143            return m_color.serialized();
144        return "currentColor";
145    }
146
147    ASSERT_NOT_REACHED();
148    return String();
149}
150
151}
152
153#endif // ENABLE(SVG)
154