OLD | NEW |
1 /* | 1 /* |
2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. | 2 * Copyright (C) 2006, 2007, 2008, 2010 Apple Inc. All rights reserved. |
3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> | 3 * Copyright (C) 2007 Alp Toker <alp@atoker.com> |
4 * Copyright (C) 2013 Google Inc. All rights reserved. | 4 * Copyright (C) 2013 Google Inc. All rights reserved. |
5 * | 5 * |
6 * Redistribution and use in source and binary forms, with or without | 6 * Redistribution and use in source and binary forms, with or without |
7 * modification, are permitted provided that the following conditions | 7 * modification, are permitted provided that the following conditions |
8 * are met: | 8 * are met: |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 11 matching lines...) Expand all Loading... |
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
26 */ | 26 */ |
27 | 27 |
28 #include "config.h" | 28 #include "config.h" |
29 #include "platform/graphics/Gradient.h" | 29 #include "platform/graphics/Gradient.h" |
30 | 30 |
31 #include "platform/geometry/FloatRect.h" | 31 #include "platform/geometry/FloatRect.h" |
32 #include "platform/graphics/Color.h" | |
33 #include "platform/graphics/GraphicsContext.h" | 32 #include "platform/graphics/GraphicsContext.h" |
34 #include "platform/graphics/skia/SkiaUtils.h" | 33 #include "platform/graphics/skia/SkiaUtils.h" |
| 34 #include "third_party/skia/include/core/SkColor.h" |
35 #include "third_party/skia/include/core/SkColorShader.h" | 35 #include "third_party/skia/include/core/SkColorShader.h" |
36 #include "third_party/skia/include/core/SkShader.h" | 36 #include "third_party/skia/include/core/SkShader.h" |
37 #include "third_party/skia/include/effects/SkGradientShader.h" | 37 #include "third_party/skia/include/effects/SkGradientShader.h" |
38 | 38 |
39 namespace WebCore { | 39 namespace WebCore { |
40 | 40 |
41 Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1) | 41 Gradient::Gradient(const FloatPoint& p0, const FloatPoint& p1) |
42 : m_p0(p0) | 42 : m_p0(p0) |
43 , m_p1(p1) | 43 , m_p1(p1) |
44 , m_r0(0) | 44 , m_r0(0) |
(...skipping 18 matching lines...) Expand all Loading... |
63 , m_spreadMethod(SpreadMethodPad) | 63 , m_spreadMethod(SpreadMethodPad) |
64 { | 64 { |
65 } | 65 } |
66 | 66 |
67 Gradient::~Gradient() | 67 Gradient::~Gradient() |
68 { | 68 { |
69 } | 69 } |
70 | 70 |
71 void Gradient::addColorStop(float value, const Color& color) | 71 void Gradient::addColorStop(float value, const Color& color) |
72 { | 72 { |
73 float r; | 73 m_stops.append(ColorStop(value, color)); |
74 float g; | |
75 float b; | |
76 float a; | |
77 color.getRGBA(r, g, b, a); | |
78 m_stops.append(ColorStop(value, r, g, b, a)); | |
79 | 74 |
80 m_stopsSorted = false; | 75 m_stopsSorted = false; |
81 m_gradient.clear(); | 76 m_gradient.clear(); |
82 } | 77 } |
83 | 78 |
84 void Gradient::addColorStop(const Gradient::ColorStop& stop) | 79 void Gradient::addColorStop(const Gradient::ColorStop& stop) |
85 { | 80 { |
86 m_stops.append(stop); | 81 m_stops.append(stop); |
87 | 82 |
88 m_stopsSorted = false; | 83 m_stopsSorted = false; |
(...skipping 14 matching lines...) Expand all Loading... |
103 | 98 |
104 if (!m_stops.size()) | 99 if (!m_stops.size()) |
105 return; | 100 return; |
106 | 101 |
107 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); | 102 std::stable_sort(m_stops.begin(), m_stops.end(), compareStops); |
108 } | 103 } |
109 | 104 |
110 bool Gradient::hasAlpha() const | 105 bool Gradient::hasAlpha() const |
111 { | 106 { |
112 for (size_t i = 0; i < m_stops.size(); i++) { | 107 for (size_t i = 0; i < m_stops.size(); i++) { |
113 if (m_stops[i].alpha < 1) | 108 if (m_stops[i].color.hasAlpha()) |
114 return true; | 109 return true; |
115 } | 110 } |
116 | 111 |
117 return false; | 112 return false; |
118 } | 113 } |
119 | 114 |
120 void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod) | 115 void Gradient::setSpreadMethod(GradientSpreadMethod spreadMethod) |
121 { | 116 { |
122 // FIXME: Should it become necessary, allow calls to this method after m_gra
dient has been set. | 117 // FIXME: Should it become necessary, allow calls to this method after m_gra
dient has been set. |
123 ASSERT(!m_gradient); | 118 ASSERT(!m_gradient); |
(...skipping 16 matching lines...) Expand all Loading... |
140 void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTra
nsformation) | 135 void Gradient::setGradientSpaceTransform(const AffineTransform& gradientSpaceTra
nsformation) |
141 { | 136 { |
142 if (m_gradientSpaceTransformation == gradientSpaceTransformation) | 137 if (m_gradientSpaceTransformation == gradientSpaceTransformation) |
143 return; | 138 return; |
144 | 139 |
145 m_gradientSpaceTransformation = gradientSpaceTransformation; | 140 m_gradientSpaceTransformation = gradientSpaceTransformation; |
146 if (m_gradient) | 141 if (m_gradient) |
147 m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTran
sformation)); | 142 m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTran
sformation)); |
148 } | 143 } |
149 | 144 |
150 static inline U8CPU F2B(float x) | |
151 { | |
152 return static_cast<int>(x * 255); | |
153 } | |
154 | |
155 static SkColor makeSkColor(float a, float r, float g, float b) | |
156 { | |
157 return SkColorSetARGB(F2B(a), F2B(r), F2B(g), F2B(b)); | |
158 } | |
159 | |
160 // Determine the total number of stops needed, including pseudo-stops at the | 145 // Determine the total number of stops needed, including pseudo-stops at the |
161 // ends as necessary. | 146 // ends as necessary. |
162 static size_t totalStopsNeeded(const Gradient::ColorStop* stopData, size_t count
) | 147 static size_t totalStopsNeeded(const Gradient::ColorStop* stopData, size_t count
) |
163 { | 148 { |
164 // N.B.: The tests in this function should kept in sync with the ones in | 149 // N.B.: The tests in this function should kept in sync with the ones in |
165 // fillStops(), or badness happens. | 150 // fillStops(), or badness happens. |
166 const Gradient::ColorStop* stop = stopData; | 151 const Gradient::ColorStop* stop = stopData; |
167 size_t countUsed = count; | 152 size_t countUsed = count; |
168 if (count < 1 || stop->stop > 0.0) | 153 if (count < 1 || stop->stop > 0.0) |
169 countUsed++; | 154 countUsed++; |
170 stop += count - 1; | 155 stop += count - 1; |
171 if (count < 1 || stop->stop < 1.0) | 156 if (count < 1 || stop->stop < 1.0) |
172 countUsed++; | 157 countUsed++; |
173 return countUsed; | 158 return countUsed; |
174 } | 159 } |
175 | 160 |
| 161 // FIXME: This would be more at home as Color::operator SkColor. |
| 162 static inline SkColor makeSkColor(const Color& c) |
| 163 { |
| 164 return SkColorSetARGB(c.alpha(), c.red(), c.green(), c.blue()); |
| 165 } |
| 166 |
176 // Collect sorted stop position and color information into the pos and colors | 167 // Collect sorted stop position and color information into the pos and colors |
177 // buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large | 168 // buffers, ensuring stops at both 0.0 and 1.0. The buffers must be large |
178 // enough to hold information for all stops, including the new endpoints if | 169 // enough to hold information for all stops, including the new endpoints if |
179 // stops at 0.0 and 1.0 aren't already included. | 170 // stops at 0.0 and 1.0 aren't already included. |
180 static void fillStops(const Gradient::ColorStop* stopData, | 171 static void fillStops(const Gradient::ColorStop* stopData, |
181 size_t count, SkScalar* pos, SkColor* colors) | 172 size_t count, SkScalar* pos, SkColor* colors) |
182 { | 173 { |
183 const Gradient::ColorStop* stop = stopData; | 174 const Gradient::ColorStop* stop = stopData; |
184 size_t start = 0; | 175 size_t start = 0; |
185 if (count < 1) { | 176 if (count < 1) { |
186 // A gradient with no stops must be transparent black. | 177 // A gradient with no stops must be transparent black. |
187 pos[0] = WebCoreFloatToSkScalar(0.0); | 178 pos[0] = WebCoreFloatToSkScalar(0.0); |
188 colors[0] = makeSkColor(0.0, 0.0, 0.0, 0.0); | 179 colors[0] = SK_ColorTRANSPARENT; |
189 start = 1; | 180 start = 1; |
190 } else if (stop->stop > 0.0) { | 181 } else if (stop->stop > 0.0) { |
191 // Copy the first stop to 0.0. The first stop position may have a slight | 182 // Copy the first stop to 0.0. The first stop position may have a slight |
192 // rounding error, but we don't care in this float comparison, since | 183 // rounding error, but we don't care in this float comparison, since |
193 // 0.0 comes through cleanly and people aren't likely to want a gradient | 184 // 0.0 comes through cleanly and people aren't likely to want a gradient |
194 // with a stop at (0 + epsilon). | 185 // with a stop at (0 + epsilon). |
195 pos[0] = WebCoreFloatToSkScalar(0.0); | 186 pos[0] = WebCoreFloatToSkScalar(0.0); |
196 colors[0] = makeSkColor(stop->alpha, stop->red, stop->green, stop->blue)
; | 187 colors[0] = makeSkColor(stop->color); |
197 start = 1; | 188 start = 1; |
198 } | 189 } |
199 | 190 |
200 for (size_t i = start; i < start + count; i++) { | 191 for (size_t i = start; i < start + count; i++) { |
201 pos[i] = WebCoreFloatToSkScalar(stop->stop); | 192 pos[i] = WebCoreFloatToSkScalar(stop->stop); |
202 colors[i] = makeSkColor(stop->alpha, stop->red, stop->green, stop->blue)
; | 193 colors[i] = makeSkColor(stop->color); |
203 ++stop; | 194 ++stop; |
204 } | 195 } |
205 | 196 |
206 // Copy the last stop to 1.0 if needed. See comment above about this float | 197 // Copy the last stop to 1.0 if needed. See comment above about this float |
207 // comparison. | 198 // comparison. |
208 if (count < 1 || (--stop)->stop < 1.0) { | 199 if (count < 1 || (--stop)->stop < 1.0) { |
209 pos[start + count] = WebCoreFloatToSkScalar(1.0); | 200 pos[start + count] = WebCoreFloatToSkScalar(1.0); |
210 colors[start + count] = colors[start + count - 1]; | 201 colors[start + count] = colors[start + count - 1]; |
211 } | 202 } |
212 } | 203 } |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
273 if (!m_gradient) { | 264 if (!m_gradient) { |
274 // use last color, since our "geometry" was degenerate (e.g. radius==0) | 265 // use last color, since our "geometry" was degenerate (e.g. radius==0) |
275 m_gradient = adoptRef(new SkColorShader(colors[countUsed - 1])); | 266 m_gradient = adoptRef(new SkColorShader(colors[countUsed - 1])); |
276 } else { | 267 } else { |
277 m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTran
sformation)); | 268 m_gradient->setLocalMatrix(affineTransformToSkMatrix(m_gradientSpaceTran
sformation)); |
278 } | 269 } |
279 return m_gradient.get(); | 270 return m_gradient.get(); |
280 } | 271 } |
281 | 272 |
282 } //namespace | 273 } //namespace |
OLD | NEW |