a4213465c612da1cbf767cdeb944ae9af7b65bad
[WebKit-https.git] / Source / WebCore / platform / graphics / Gradient.h
1 /*
2  * Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013 Apple Inc. All rights reserved.
3  * Copyright (C) 2007 Alp Toker <alp@atoker.com>
4  * Copyright (C) 2008 Torch Mobile, Inc.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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. 
26  */
27
28 #ifndef Gradient_h
29 #define Gradient_h
30
31 #include "AffineTransform.h"
32 #include "FloatPoint.h"
33 #include "GraphicsTypes.h"
34 #include <wtf/PassRefPtr.h>
35 #include <wtf/RefCounted.h>
36 #include <wtf/Vector.h>
37
38 #if USE(CG)
39
40 typedef struct CGContext* CGContextRef;
41
42 typedef struct CGGradient* CGGradientRef;
43 typedef CGGradientRef PlatformGradient;
44
45 #elif USE(CAIRO)
46 typedef struct _cairo_pattern cairo_pattern_t;
47 typedef cairo_pattern_t* PlatformGradient;
48 #else
49 typedef void* PlatformGradient;
50 #endif
51
52 namespace WebCore {
53
54     class Color;
55     class FloatRect;
56     class GraphicsContext;
57
58     class Gradient : public RefCounted<Gradient> {
59     public:
60         static Ref<Gradient> create(const FloatPoint& p0, const FloatPoint& p1)
61         {
62             return adoptRef(*new Gradient(p0, p1));
63         }
64         static Ref<Gradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio = 1)
65         {
66             return adoptRef(*new Gradient(p0, r0, p1, r1, aspectRatio));
67         }
68         WEBCORE_EXPORT ~Gradient();
69
70         struct ColorStop;
71         WEBCORE_EXPORT void addColorStop(const ColorStop&);
72         WEBCORE_EXPORT void addColorStop(float, const Color&);
73
74         bool hasAlpha() const;
75
76         bool isRadial() const { return m_radial; }
77         bool isZeroSize() const { return m_p0.x() == m_p1.x() && m_p0.y() == m_p1.y() && (!m_radial || m_r0 == m_r1); }
78
79         const FloatPoint& p0() const { return m_p0; }
80         const FloatPoint& p1() const { return m_p1; }
81
82         void setP0(const FloatPoint& p)
83         {
84             if (m_p0 == p)
85                 return;
86             
87             m_p0 = p;
88             
89             invalidateHash();
90         }
91         
92         void setP1(const FloatPoint& p)
93         {
94             if (m_p1 == p)
95                 return;
96             
97             m_p1 = p;
98             
99             invalidateHash();
100         }
101
102         float startRadius() const { return m_r0; }
103         float endRadius() const { return m_r1; }
104
105         void setStartRadius(float r)
106         {
107             if (m_r0 == r)
108                 return;
109
110             m_r0 = r;
111
112             invalidateHash();
113         }
114
115         void setEndRadius(float r)
116         {
117             if (m_r1 == r)
118                 return;
119
120             m_r1 = r;
121
122             invalidateHash();
123         }
124
125         float aspectRatio() const { return m_aspectRatio; }
126
127 #if USE(WINGDI)
128         const Vector<ColorStop, 2>& getStops() const;
129 #else
130         PlatformGradient platformGradient();
131 #endif
132
133         struct ColorStop {
134             float stop;
135             float red;
136             float green;
137             float blue;
138             float alpha;
139
140             ColorStop() : stop(0), red(0), green(0), blue(0), alpha(0) { }
141             ColorStop(float s, float r, float g, float b, float a) : stop(s), red(r), green(g), blue(b), alpha(a) { }
142         };
143
144         void setStopsSorted(bool s) { m_stopsSorted = s; }
145         
146         void setSpreadMethod(GradientSpreadMethod);
147         GradientSpreadMethod spreadMethod() { return m_spreadMethod; }
148         void setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation);
149         // Qt and CG transform the gradient at draw time
150         AffineTransform gradientSpaceTransform() { return m_gradientSpaceTransformation; }
151
152         void fill(GraphicsContext*, const FloatRect&);
153         void adjustParametersForTiledDrawing(FloatSize&, FloatRect&);
154
155         void setPlatformGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation);
156
157         unsigned hash() const;
158         void invalidateHash() { m_cachedHash = 0; }
159
160 #if USE(CG)
161         void paint(CGContextRef);
162         void paint(GraphicsContext*);
163 #elif USE(CAIRO)
164         PlatformGradient platformGradient(float globalAlpha);
165 #endif
166
167     private:
168         WEBCORE_EXPORT Gradient(const FloatPoint& p0, const FloatPoint& p1);
169         Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio);
170
171         void platformInit() { m_gradient = 0; }
172         void platformDestroy();
173
174         void sortStopsIfNecessary();
175
176         // Keep any parameters relevant to rendering in sync with the structure in Gradient::hash().
177         bool m_radial;
178         FloatPoint m_p0;
179         FloatPoint m_p1;
180         float m_r0;
181         float m_r1;
182         float m_aspectRatio; // For elliptical gradient, width / height.
183         mutable Vector<ColorStop, 2> m_stops;
184         mutable bool m_stopsSorted;
185         GradientSpreadMethod m_spreadMethod;
186         AffineTransform m_gradientSpaceTransformation;
187
188         mutable unsigned m_cachedHash;
189
190         PlatformGradient m_gradient;
191
192 #if USE(CAIRO)
193         float m_platformGradientAlpha;
194 #endif
195
196     };
197
198 } //namespace
199
200 #endif