1 /*
2 * Copyright (C) 2006, 2008 Apple Inc. All rights reserved.
3 * Copyright (C) 2008 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 "CanvasStyle.h"
31
32 #include "CSSParser.h"
33 #include "CanvasGradient.h"
34 #include "CanvasPattern.h"
35 #include "GraphicsContext.h"
36 #include <wtf/PassRefPtr.h>
37
38 #if PLATFORM(CG)
39 #include <CoreGraphics/CGContext.h>
40 #endif
41
42 #if PLATFORM(QT)
43 #include <QPainter>
44 #include <QBrush>
45 #include <QPen>
46 #include <QColor>
47 #endif
48
49 namespace WebCore {
50
CanvasStyle(const String & color)51 CanvasStyle::CanvasStyle(const String& color)
52 : m_type(ColorString)
53 , m_color(color)
54 {
55 }
56
CanvasStyle(float grayLevel)57 CanvasStyle::CanvasStyle(float grayLevel)
58 : m_type(GrayLevel)
59 , m_alpha(1)
60 , m_grayLevel(grayLevel)
61 {
62 }
63
CanvasStyle(const String & color,float alpha)64 CanvasStyle::CanvasStyle(const String& color, float alpha)
65 : m_type(ColorStringWithAlpha)
66 , m_color(color)
67 , m_alpha(alpha)
68 {
69 }
70
CanvasStyle(float grayLevel,float alpha)71 CanvasStyle::CanvasStyle(float grayLevel, float alpha)
72 : m_type(GrayLevel)
73 , m_alpha(alpha)
74 , m_grayLevel(grayLevel)
75 {
76 }
77
CanvasStyle(float r,float g,float b,float a)78 CanvasStyle::CanvasStyle(float r, float g, float b, float a)
79 : m_type(RGBA)
80 , m_alpha(a)
81 , m_red(r)
82 , m_green(g)
83 , m_blue(b)
84 {
85 }
86
CanvasStyle(float c,float m,float y,float k,float a)87 CanvasStyle::CanvasStyle(float c, float m, float y, float k, float a)
88 : m_type(CMYKA)
89 , m_alpha(a)
90 , m_cyan(c)
91 , m_magenta(m)
92 , m_yellow(y)
93 , m_black(k)
94 {
95 }
96
CanvasStyle(PassRefPtr<CanvasGradient> gradient)97 CanvasStyle::CanvasStyle(PassRefPtr<CanvasGradient> gradient)
98 : m_type(gradient ? Gradient : ColorString)
99 , m_gradient(gradient)
100 {
101 }
102
CanvasStyle(PassRefPtr<CanvasPattern> pattern)103 CanvasStyle::CanvasStyle(PassRefPtr<CanvasPattern> pattern)
104 : m_type(pattern ? ImagePattern : ColorString)
105 , m_pattern(pattern)
106 {
107 }
108
applyStrokeColor(GraphicsContext * context)109 void CanvasStyle::applyStrokeColor(GraphicsContext* context)
110 {
111 if (!context)
112 return;
113 switch (m_type) {
114 case ColorString: {
115 Color c = Color(m_color);
116 if (c.isValid()) {
117 context->setStrokeColor(c.rgb());
118 break;
119 }
120 RGBA32 color = 0; // default is transparent black
121 if (CSSParser::parseColor(color, m_color))
122 context->setStrokeColor(color);
123 break;
124 }
125 case ColorStringWithAlpha: {
126 Color c = Color(m_color);
127 if (c.isValid()) {
128 context->setStrokeColor(colorWithOverrideAlpha(c.rgb(), m_alpha));
129 break;
130 }
131 RGBA32 color = 0; // default is transparent black
132 if (CSSParser::parseColor(color, m_color))
133 context->setStrokeColor(colorWithOverrideAlpha(color, m_alpha));
134 break;
135 }
136 case GrayLevel:
137 // We're only supporting 255 levels of gray here. Since this isn't
138 // even part of HTML5, I don't expect anyone will care. If they do
139 // we'll make a fancier Color abstraction.
140 context->setStrokeColor(Color(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha));
141 break;
142 case RGBA:
143 context->setStrokeColor(Color(m_red, m_green, m_blue, m_alpha));
144 break;
145 case CMYKA: {
146 // FIXME: Do this through platform-independent GraphicsContext API.
147 // We'll need a fancier Color abstraction to support CYMKA correctly
148 #if PLATFORM(CG)
149 CGContextSetCMYKStrokeColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha);
150 #elif PLATFORM(QT)
151 QPen currentPen = context->platformContext()->pen();
152 QColor clr;
153 clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
154 currentPen.setColor(clr);
155 context->platformContext()->setPen(currentPen);
156 #else
157 context->setStrokeColor(Color(m_cyan, m_magenta, m_yellow, m_black, m_alpha));
158 #endif
159 break;
160 }
161 case Gradient:
162 context->setStrokeGradient(canvasGradient()->gradient());
163 break;
164 case ImagePattern:
165 context->setStrokePattern(canvasPattern()->pattern());
166 break;
167 }
168 }
169
applyFillColor(GraphicsContext * context)170 void CanvasStyle::applyFillColor(GraphicsContext* context)
171 {
172 if (!context)
173 return;
174 switch (m_type) {
175 case ColorString: {
176 Color c = Color(m_color);
177 if (c.isValid()) {
178 context->setFillColor(c.rgb());
179 break;
180 }
181 RGBA32 rgba = 0; // default is transparent black
182 if (CSSParser::parseColor(rgba, m_color))
183 context->setFillColor(rgba);
184 break;
185 }
186 case ColorStringWithAlpha: {
187 Color c = Color(m_color);
188 if (c.isValid()) {
189 context->setFillColor(colorWithOverrideAlpha(c.rgb(), m_alpha));
190 break;
191 }
192 RGBA32 color = 0; // default is transparent black
193 if (CSSParser::parseColor(color, m_color))
194 context->setFillColor(colorWithOverrideAlpha(color, m_alpha));
195 break;
196 }
197 case GrayLevel:
198 // We're only supporting 255 levels of gray here. Since this isn't
199 // even part of HTML5, I don't expect anyone will care. If they do
200 // we'll make a fancier Color abstraction.
201 context->setFillColor(Color(m_grayLevel, m_grayLevel, m_grayLevel, m_alpha));
202 break;
203 case RGBA:
204 context->setFillColor(Color(m_red, m_green, m_blue, m_alpha));
205 break;
206 case CMYKA: {
207 // FIXME: Do this through platform-independent GraphicsContext API.
208 // We'll need a fancier Color abstraction to support CYMKA correctly
209 #if PLATFORM(CG)
210 CGContextSetCMYKFillColor(context->platformContext(), m_cyan, m_magenta, m_yellow, m_black, m_alpha);
211 #elif PLATFORM(QT)
212 QBrush currentBrush = context->platformContext()->brush();
213 QColor clr;
214 clr.setCmykF(m_cyan, m_magenta, m_yellow, m_black, m_alpha);
215 currentBrush.setColor(clr);
216 context->platformContext()->setBrush(currentBrush);
217 #else
218 context->setFillColor(Color(m_cyan, m_magenta, m_yellow, m_black, m_alpha));
219 #endif
220 break;
221 }
222 case Gradient:
223 context->setFillGradient(canvasGradient()->gradient());
224 break;
225 case ImagePattern:
226 context->setFillPattern(canvasPattern()->pattern());
227 break;
228 }
229 }
230
231 }
232