File indexing completed on 2024-05-12 15:39:16

0001 /*
0002  * Copyright (C) 2006 Nikolas Zimmermann <zimmermann@kde.org>
0003  *
0004  * Redistribution and use in source and binary forms, with or without
0005  * modification, are permitted provided that the following conditions
0006  * are met:
0007  * 1. Redistributions of source code must retain the above copyright
0008  *    notice, this list of conditions and the following disclaimer.
0009  * 2. Redistributions in binary form must reproduce the above copyright
0010  *    notice, this list of conditions and the following disclaimer in the
0011  *    documentation and/or other materials provided with the distribution.
0012  *
0013  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
0014  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0015  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
0016  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
0017  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
0018  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
0019  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
0020  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
0021  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
0022  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
0023  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
0024  */
0025 
0026 #ifndef SVGPaintServerGradient_h
0027 #define SVGPaintServerGradient_h
0028 
0029 #if ENABLE(SVG)
0030 
0031 #include "AffineTransform.h"
0032 #include "SVGPaintServer.h"
0033 
0034 #include <wtf/RefCounted.h>
0035 #include <wtf/RefPtr.h>
0036 
0037 #if PLATFORM(QT)
0038 #include <qglobal.h>
0039 QT_BEGIN_NAMESPACE
0040 class QGradient;
0041 QT_END_NAMESPACE
0042 #endif
0043 
0044 namespace WebCore
0045 {
0046 
0047 class ImageBuffer;
0048 class SVGGradientElement;
0049 
0050 // FIXME: Remove the spread method enum in SVGGradientElement
0051 enum SVGGradientSpreadMethod {
0052     SPREADMETHOD_PAD = 1,
0053     SPREADMETHOD_REFLECT = 2,
0054     SPREADMETHOD_REPEAT = 3
0055 };
0056 
0057 typedef std::pair<float, QColor> SVGGradientStop;
0058 
0059 class SVGPaintServerGradient : public SVGPaintServer
0060 {
0061 public:
0062     virtual ~SVGPaintServerGradient();
0063 
0064     const Vector<SVGGradientStop> &gradientStops() const;
0065     void setGradientStops(const Vector<SVGGradientStop> &);
0066 
0067     SVGGradientSpreadMethod spreadMethod() const;
0068     void setGradientSpreadMethod(const SVGGradientSpreadMethod &);
0069 
0070     // Gradient start and end points are percentages when used in boundingBox mode.
0071     // For instance start point with value (0,0) is top-left and end point with
0072     // value (100, 100) is bottom-right. BoundingBox mode is enabled by default.
0073     bool boundingBoxMode() const;
0074     void setBoundingBoxMode(bool mode = true);
0075 
0076     AffineTransform gradientTransform() const;
0077     void setGradientTransform(const AffineTransform &);
0078 
0079     /*virtual TextStream& externalRepresentation(TextStream&) const;*/
0080 
0081     bool setup(QPainter *painter, QPainterPath *path, const RenderObject *, SVGPaintTargetType, bool isPaintingText) const override;
0082 #if PLATFORM(CG)
0083     virtual void teardown(GraphicsContext *&, const RenderObject *, SVGPaintTargetType, bool isPaintingText) const;
0084     virtual void renderPath(GraphicsContext *&, const RenderObject *, SVGPaintTargetType) const;
0085 
0086     virtual void invalidate();
0087 
0088     // Helpers
0089     void updateQuartzGradientStopsCache(const Vector<SVGGradientStop> &);
0090     void updateQuartzGradientCache(const SVGPaintServerGradient *);
0091     void handleBoundingBoxModeAndGradientTransformation(GraphicsContext *, const FloatRect &targetRect) const;
0092 #endif
0093 
0094 #if PLATFORM(QT)
0095 protected:
0096     void fillColorArray(QGradient &, const Vector<SVGGradientStop> &, float opacity) const;
0097     virtual QGradient setupGradient(QPainter *painter, QPainterPath *painterPath, const RenderObject *) const = 0;
0098 #endif
0099 
0100 protected:
0101     SVGPaintServerGradient(const SVGGradientElement *owner);
0102 
0103 private:
0104     Vector<SVGGradientStop> m_stops;
0105     SVGGradientSpreadMethod m_spreadMethod;
0106     bool m_boundingBoxMode;
0107     AffineTransform m_gradientTransform;
0108     const SVGGradientElement *m_ownerElement;
0109 
0110 #if PLATFORM(CG)
0111 public:
0112     typedef struct {
0113         CGFloat colorArray[4];
0114         CGFloat offset;
0115         CGFloat previousDeltaInverse;
0116     } QuartzGradientStop;
0117 
0118     struct SharedStopCache : public RefCounted<SharedStopCache> {
0119     public:
0120         static PassRefPtr<SharedStopCache> create()
0121         {
0122             return adoptRef(new SharedStopCache);
0123         }
0124 
0125         Vector<QuartzGradientStop> m_stops;
0126 
0127     private:
0128         SharedStopCache() { }
0129     };
0130 
0131     RefPtr<SharedStopCache> m_stopsCache;
0132 
0133     CGShadingRef m_shadingCache;
0134     mutable GraphicsContext *m_savedContext;
0135     mutable ImageBuffer *m_imageBuffer;
0136 #endif
0137 };
0138 
0139 inline SVGGradientStop makeGradientStop(float offset, const QColor &color)
0140 {
0141     return std::make_pair(offset, color);
0142 }
0143 
0144 } // namespace WebCore
0145 
0146 #endif
0147 
0148 #endif // SVGPaintServerGradient_h