1 | /* |
2 | * Copyright (C) 2006, 2007, 2008, 2011, 2012, 2013 Apple Inc. All rights reserved. |
3 | * Copyright (C) 2007 Alp Toker <[email protected]> |
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 | #pragma once |
29 | |
30 | #include "AffineTransform.h" |
31 | #include "Color.h" |
32 | #include "FloatPoint.h" |
33 | #include "GraphicsTypes.h" |
34 | #include <wtf/RefCounted.h> |
35 | #include <wtf/Variant.h> |
36 | #include <wtf/Vector.h> |
37 | |
38 | #if USE(CG) |
39 | typedef struct CGContext* CGContextRef; |
40 | typedef struct CGGradient* CGGradientRef; |
41 | typedef CGGradientRef PlatformGradient; |
42 | #elif USE(DIRECT2D) |
43 | interface ID2D1Brush; |
44 | interface ID2D1RenderTarget; |
45 | typedef ID2D1Brush* PlatformGradient; |
46 | #elif USE(CAIRO) |
47 | typedef struct _cairo_pattern cairo_pattern_t; |
48 | typedef cairo_pattern_t* PlatformGradient; |
49 | #else |
50 | typedef void* PlatformGradient; |
51 | #endif |
52 | |
53 | namespace WebCore { |
54 | |
55 | class Color; |
56 | class FloatRect; |
57 | class GraphicsContext; |
58 | |
59 | class Gradient : public RefCounted<Gradient> { |
60 | public: |
61 | // FIXME: ExtendedColor - A color stop needs a notion of color space. |
62 | struct ColorStop { |
63 | float offset { 0 }; |
64 | Color color; |
65 | |
66 | ColorStop() = default; |
67 | ColorStop(float offset, const Color& color) |
68 | : offset(offset) |
69 | , color(color) |
70 | { |
71 | } |
72 | }; |
73 | |
74 | using ColorStopVector = Vector<ColorStop, 2>; |
75 | |
76 | struct LinearData { |
77 | FloatPoint point0; |
78 | FloatPoint point1; |
79 | }; |
80 | |
81 | struct RadialData { |
82 | FloatPoint point0; |
83 | FloatPoint point1; |
84 | float startRadius; |
85 | float endRadius; |
86 | float aspectRatio; // For elliptical gradient, width / height. |
87 | }; |
88 | |
89 | struct ConicData { |
90 | FloatPoint point0; |
91 | float angleRadians; |
92 | }; |
93 | |
94 | using Data = Variant<LinearData, RadialData, ConicData>; |
95 | |
96 | enum class Type { Linear, Radial, Conic }; |
97 | |
98 | static Ref<Gradient> create(LinearData&&); |
99 | static Ref<Gradient> create(RadialData&&); |
100 | static Ref<Gradient> create(ConicData&&); |
101 | |
102 | WEBCORE_EXPORT ~Gradient(); |
103 | |
104 | Type type() const; |
105 | |
106 | bool hasAlpha() const; |
107 | bool isZeroSize() const; |
108 | |
109 | const Data& data() const { return m_data; } |
110 | |
111 | WEBCORE_EXPORT void addColorStop(const ColorStop&); |
112 | WEBCORE_EXPORT void addColorStop(float, const Color&); |
113 | void setSortedColorStops(ColorStopVector&&); |
114 | |
115 | const ColorStopVector& stops() const { return m_stops; } |
116 | |
117 | void setSpreadMethod(GradientSpreadMethod); |
118 | GradientSpreadMethod spreadMethod() const { return m_spreadMethod; } |
119 | |
120 | // CG needs to transform the gradient at draw time. |
121 | void setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation); |
122 | const AffineTransform& gradientSpaceTransform() const { return m_gradientSpaceTransformation; } |
123 | |
124 | void fill(GraphicsContext&, const FloatRect&); |
125 | void adjustParametersForTiledDrawing(FloatSize&, FloatRect&, const FloatSize& spacing); |
126 | |
127 | unsigned hash() const; |
128 | void invalidateHash() { m_cachedHash = 0; } |
129 | |
130 | #if USE(CG) |
131 | void paint(GraphicsContext&); |
132 | void paint(CGContextRef); |
133 | #elif USE(DIRECT2D) |
134 | PlatformGradient createPlatformGradientIfNecessary(ID2D1RenderTarget*); |
135 | #elif USE(CAIRO) |
136 | PlatformGradient createPlatformGradient(float globalAlpha); |
137 | #endif |
138 | |
139 | private: |
140 | Gradient(LinearData&&); |
141 | Gradient(RadialData&&); |
142 | Gradient(ConicData&&); |
143 | |
144 | PlatformGradient platformGradient(); |
145 | void platformInit() { m_gradient = nullptr; } |
146 | void platformDestroy(); |
147 | |
148 | void sortStopsIfNecessary(); |
149 | |
150 | #if USE(DIRECT2D) |
151 | void generateGradient(ID2D1RenderTarget*); |
152 | #endif |
153 | |
154 | Data m_data; |
155 | |
156 | mutable ColorStopVector m_stops; |
157 | mutable bool m_stopsSorted { false }; |
158 | GradientSpreadMethod m_spreadMethod { SpreadMethodPad }; |
159 | AffineTransform m_gradientSpaceTransformation; |
160 | |
161 | mutable unsigned m_cachedHash { 0 }; |
162 | |
163 | PlatformGradient m_gradient; |
164 | }; |
165 | |
166 | } |
167 | |