Upstream version 6.35.121.0
[platform/framework/web/crosswalk.git] / src / third_party / WebKit / Source / core / html / canvas / CanvasStyle.cpp
1 /*
2  * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
3  * Copyright (C) 2008, 2010 Nokia Corporation and/or its subsidiary(-ies)
4  * Copyright (C) 2007 Alp Toker <alp@atoker.com>
5  * Copyright (C) 2008 Eric Seidel <eric@webkit.org>
6  *
7  * Redistribution and use in source and binary forms, with or without
8  * modification, are permitted provided that the following conditions
9  * are met:
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer.
12  * 2. Redistributions in binary form must reproduce the above copyright
13  *    notice, this list of conditions and the following disclaimer in the
14  *    documentation and/or other materials provided with the distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
17  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
18  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
20  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
21  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
22  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
23  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
24  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "core/html/canvas/CanvasStyle.h"
31
32 #include "CSSPropertyNames.h"
33 #include "core/css/parser/BisonCSSParser.h"
34 #include "core/css/StylePropertySet.h"
35 #include "core/html/HTMLCanvasElement.h"
36 #include "core/html/canvas/CanvasGradient.h"
37 #include "core/html/canvas/CanvasPattern.h"
38 #include "platform/graphics/GraphicsContext.h"
39 #include "wtf/PassRefPtr.h"
40
41 namespace WebCore {
42
43 enum ColorParseResult { ParsedRGBA, ParsedCurrentColor, ParsedSystemColor, ParseFailed };
44
45 static ColorParseResult parseColor(RGBA32& parsedColor, const String& colorString)
46 {
47     if (equalIgnoringCase(colorString, "currentcolor"))
48         return ParsedCurrentColor;
49     if (BisonCSSParser::parseColor(parsedColor, colorString))
50         return ParsedRGBA;
51     if (BisonCSSParser::parseSystemColor(parsedColor, colorString))
52         return ParsedSystemColor;
53     return ParseFailed;
54 }
55
56 RGBA32 currentColor(HTMLCanvasElement* canvas)
57 {
58     if (!canvas || !canvas->inDocument() || !canvas->inlineStyle())
59         return Color::black;
60     RGBA32 rgba = Color::black;
61     BisonCSSParser::parseColor(rgba, canvas->inlineStyle()->getPropertyValue(CSSPropertyColor));
62     return rgba;
63 }
64
65 bool parseColorOrCurrentColor(RGBA32& parsedColor, const String& colorString, HTMLCanvasElement* canvas)
66 {
67     ColorParseResult parseResult = parseColor(parsedColor, colorString);
68     switch (parseResult) {
69     case ParsedRGBA:
70     case ParsedSystemColor:
71         return true;
72     case ParsedCurrentColor:
73         parsedColor = currentColor(canvas);
74         return true;
75     case ParseFailed:
76         return false;
77     default:
78         ASSERT_NOT_REACHED();
79         return false;
80     }
81 }
82
83 CanvasStyle::CanvasStyle(Type type, float overrideAlpha)
84     : m_type(type)
85     , m_overrideAlpha(overrideAlpha)
86 {
87 }
88
89 CanvasStyle::CanvasStyle(RGBA32 rgba)
90     : m_type(RGBA)
91     , m_rgba(rgba)
92 {
93 }
94
95 CanvasStyle::CanvasStyle(float grayLevel, float alpha)
96     : m_type(RGBA)
97     , m_rgba(makeRGBA32FromFloats(grayLevel, grayLevel, grayLevel, alpha))
98 {
99 }
100
101 CanvasStyle::CanvasStyle(float r, float g, float b, float a)
102     : m_type(RGBA)
103     , m_rgba(makeRGBA32FromFloats(r, g, b, a))
104 {
105 }
106
107 CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a)
108     : m_type(CMYKA)
109     , m_rgba(makeRGBAFromCMYKA(c, m, y, k, a))
110     , m_cmyka(c, m, y, k, a)
111 {
112 }
113
114 CanvasStyle::CanvasStyle(PassRefPtr<CanvasGradient> gradient)
115     : m_type(Gradient)
116     , m_gradient(gradient)
117 {
118 }
119
120 CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
121     : m_type(ImagePattern)
122     , m_pattern(pattern)
123 {
124 }
125
126 PassRefPtr<CanvasStyle> CanvasStyle::createFromString(const String& color)
127 {
128     RGBA32 rgba;
129     ColorParseResult parseResult = parseColor(rgba, color);
130     switch (parseResult) {
131     case ParsedRGBA:
132     case ParsedSystemColor:
133         return adoptRef(new CanvasStyle(rgba));
134     case ParsedCurrentColor:
135         return adoptRef(new CanvasStyle(CurrentColor));
136     case ParseFailed:
137         return nullptr;
138     default:
139         ASSERT_NOT_REACHED();
140         return nullptr;
141     }
142 }
143
144 PassRefPtr<CanvasStyle> CanvasStyle::createFromStringWithOverrideAlpha(const String& color, float alpha)
145 {
146     RGBA32 rgba;
147     ColorParseResult parseResult = parseColor(rgba, color);
148     switch (parseResult) {
149     case ParsedRGBA:
150         return adoptRef(new CanvasStyle(colorWithOverrideAlpha(rgba, alpha)));
151     case ParsedCurrentColor:
152         return adoptRef(new CanvasStyle(CurrentColorWithOverrideAlpha, alpha));
153     case ParseFailed:
154         return nullptr;
155     default:
156         ASSERT_NOT_REACHED();
157         return nullptr;
158     }
159 }
160
161 PassRefPtr<CanvasStyle> CanvasStyle::createFromGradient(PassRefPtr<CanvasGradient> gradient)
162 {
163     if (!gradient)
164         return nullptr;
165     return adoptRef(new CanvasStyle(gradient));
166 }
167
168 PassRefPtr<CanvasStyle> CanvasStyle::createFromPattern(PassRefPtr<CanvasPattern> pattern)
169 {
170     if (!pattern)
171         return nullptr;
172     return adoptRef(new CanvasStyle(pattern));
173 }
174
175 bool CanvasStyle::isEquivalentColor(const CanvasStyle& other) const
176 {
177     if (m_type != other.m_type)
178         return false;
179
180     switch (m_type) {
181     case RGBA:
182         return m_rgba == other.m_rgba;
183     case CMYKA:
184         return m_cmyka.c == other.m_cmyka.c
185             && m_cmyka.m == other.m_cmyka.m
186             && m_cmyka.y == other.m_cmyka.y
187             && m_cmyka.k == other.m_cmyka.k
188             && m_cmyka.a == other.m_cmyka.a;
189     case Gradient:
190     case ImagePattern:
191     case CurrentColor:
192     case CurrentColorWithOverrideAlpha:
193         return false;
194     }
195
196     ASSERT_NOT_REACHED();
197     return false;
198 }
199
200 bool CanvasStyle::isEquivalentRGBA(float r, float g, float b, float a) const
201 {
202     if (m_type != RGBA)
203         return false;
204
205     return m_rgba == makeRGBA32FromFloats(r, g, b, a);
206 }
207
208 bool CanvasStyle::isEquivalentCMYKA(float c, float m, float y, float k, float a) const
209 {
210     if (m_type != CMYKA)
211         return false;
212
213     return c == m_cmyka.c
214         && m == m_cmyka.m
215         && y == m_cmyka.y
216         && k == m_cmyka.k
217         && a == m_cmyka.a;
218 }
219
220 void CanvasStyle::applyStrokeColor(GraphicsContext* context)
221 {
222     if (!context)
223         return;
224     switch (m_type) {
225     case RGBA:
226         context->setStrokeColor(m_rgba);
227         break;
228     case CMYKA: {
229         // FIXME: Do this through platform-independent GraphicsContext API.
230         // We'll need a fancier Color abstraction to support CMYKA correctly
231         context->setStrokeColor(m_rgba);
232         break;
233     }
234     case Gradient:
235         context->setStrokeGradient(canvasGradient()->gradient());
236         break;
237     case ImagePattern:
238         context->setStrokePattern(canvasPattern()->pattern());
239         break;
240     case CurrentColor:
241     case CurrentColorWithOverrideAlpha:
242         ASSERT_NOT_REACHED();
243         break;
244     }
245 }
246
247 void CanvasStyle::applyFillColor(GraphicsContext* context)
248 {
249     if (!context)
250         return;
251     switch (m_type) {
252     case RGBA:
253         context->setFillColor(m_rgba);
254         break;
255     case CMYKA: {
256         // FIXME: Do this through platform-independent GraphicsContext API.
257         // We'll need a fancier Color abstraction to support CMYKA correctly
258         context->setFillColor(m_rgba);
259         break;
260     }
261     case Gradient:
262         context->setFillGradient(canvasGradient()->gradient());
263         break;
264     case ImagePattern:
265         context->setFillPattern(canvasPattern()->pattern());
266         break;
267     case CurrentColor:
268     case CurrentColorWithOverrideAlpha:
269         ASSERT_NOT_REACHED();
270         break;
271     }
272 }
273
274 }