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 40typedef struct CGContext* CGContextRef; 41 42typedef struct CGGradient* CGGradientRef; 43typedef CGGradientRef PlatformGradient; 44 45#elif USE(CAIRO) 46typedef struct _cairo_pattern cairo_pattern_t; 47typedef cairo_pattern_t* PlatformGradient; 48#else 49typedef void* PlatformGradient; 50#endif 51 52namespace WebCore { 53 54 class Color; 55 class FloatRect; 56 class GraphicsContext; 57 58 class Gradient : public RefCounted<Gradient> { 59 public: 60 static PassRefPtr<Gradient> create(const FloatPoint& p0, const FloatPoint& p1) 61 { 62 return adoptRef(new Gradient(p0, p1)); 63 } 64 static PassRefPtr<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 ~Gradient(); 69 70 struct ColorStop; 71 void addColorStop(const ColorStop&); 72 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 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 201