15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)/*
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2006, 2007, 2008, 2011 Apple Inc. All rights reserved.
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2007 Alp Toker <alp@atoker.com>
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Copyright (C) 2008 Torch Mobile, Inc.
553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles) * Copyright (C) 2013 Google Inc. All rights reserved.
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * Redistribution and use in source and binary forms, with or without
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * modification, are permitted provided that the following conditions
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * are met:
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 1. Redistributions of source code must retain the above copyright
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer.
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * 2. Redistributions in binary form must reproduce the above copyright
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    notice, this list of conditions and the following disclaimer in the
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *    documentation and/or other materials provided with the distribution.
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) *
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2602772c6a72f1ee0b226341a4f4439970c29fc861Ben Murdoch * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles) */
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#ifndef Gradient_h
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#define Gradient_h
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
3253e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/FloatPoint.h"
3353e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/GraphicsTypes.h"
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)#include "core/platform/graphics/transforms/AffineTransform.h"
3593ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/PassRefPtr.h"
3693ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/RefCounted.h"
3793ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/RefPtr.h"
3893ac45cfc74041c8ae536ce58a9534d46db2024eTorne (Richard Coles)#include "wtf/Vector.h"
395c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class SkShader;
415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
425c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace WebCore {
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class Color;
455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class FloatRect;
465267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class IntSize;
475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)class Gradient : public RefCounted<Gradient> {
495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)public:
505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    static PassRefPtr<Gradient> create(const FloatPoint& p0, const FloatPoint& p1)
515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    {
525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return adoptRef(new Gradient(p0, p1));
535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    static PassRefPtr<Gradient> create(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio = 1)
555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    {
565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        return adoptRef(new Gradient(p0, r0, p1, r1, aspectRatio));
575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
585267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    ~Gradient();
595267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    struct ColorStop {
615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        float stop;
625267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        float red;
635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        float green;
645267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        float blue;
655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        float alpha;
665267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
675267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        ColorStop() : stop(0), red(0), green(0), blue(0), alpha(0) { }
685267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        ColorStop(float s, float r, float g, float b, float a) : stop(s), red(r), green(g), blue(b), alpha(a) { }
695c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    };
705267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void addColorStop(const ColorStop&);
715267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void addColorStop(float, const Color&);
725267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
735267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    bool hasAlpha() const;
745267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
755267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    bool isRadial() const { return m_radial; }
765267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    bool isZeroSize() const { return m_p0.x() == m_p1.x() && m_p0.y() == m_p1.y() && (!m_radial || m_r0 == m_r1); }
775267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
785267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    const FloatPoint& p0() const { return m_p0; }
795267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    const FloatPoint& p1() const { return m_p1; }
805267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
815267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void setP0(const FloatPoint& p)
825267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    {
835267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (m_p0 == p)
845267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            return;
855267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
865267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        m_p0 = p;
875267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        invalidateHash();
885267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
895267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
905267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void setP1(const FloatPoint& p)
915267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    {
925267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (m_p1 == p)
935267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            return;
945267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
955267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        m_p1 = p;
965267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        invalidateHash();
975267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
985267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
995267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    float startRadius() const { return m_r0; }
1005267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    float endRadius() const { return m_r1; }
1015267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1025267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void setStartRadius(float r)
1035267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    {
1045267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (m_r0 == r)
1055267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            return;
1065267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1075267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        m_r0 = r;
1085267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        invalidateHash();
1095267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
1105267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1115267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void setEndRadius(float r)
1125267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    {
1135267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        if (m_r1 == r)
1145267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)            return;
1155267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1165267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        m_r1 = r;
1175267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)        invalidateHash();
1185267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    }
1195267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1205267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    float aspectRatio() const { return m_aspectRatio; }
1215267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1225267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    SkShader* shader();
1235267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1245267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void setStopsSorted(bool s) { m_stopsSorted = s; }
1255267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
126521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    void setDrawsInPMColorSpace(bool drawInPMColorSpace);
127521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
1285267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void setSpreadMethod(GradientSpreadMethod);
1295267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    GradientSpreadMethod spreadMethod() { return m_spreadMethod; }
1305267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void setGradientSpaceTransform(const AffineTransform& gradientSpaceTransformation);
1315267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    AffineTransform gradientSpaceTransform() { return m_gradientSpaceTransformation; }
1325267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1335267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void adjustParametersForTiledDrawing(IntSize&, FloatRect&);
1345267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1355267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    unsigned hash() const;
1365267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void invalidateHash() { m_cachedHash = 0; }
1375267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1385267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)private:
1395267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    Gradient(const FloatPoint& p0, const FloatPoint& p1);
1405267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    Gradient(const FloatPoint& p0, float r0, const FloatPoint& p1, float r1, float aspectRatio);
1415267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1425267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void destroyShader();
1435267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1445267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    void sortStopsIfNecessary();
1455267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
1465267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    // Keep any parameters relevant to rendering in sync with the structure in Gradient::hash().
1475267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    bool m_radial;
1485267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    FloatPoint m_p0;
1495267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    FloatPoint m_p1;
1505267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    float m_r0;
1515267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    float m_r1;
1525267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    float m_aspectRatio; // For elliptical gradient, width / height.
1535267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    mutable Vector<ColorStop, 2> m_stops;
1545267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    mutable bool m_stopsSorted;
1555267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    GradientSpreadMethod m_spreadMethod;
1565267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    AffineTransform m_gradientSpaceTransformation;
1575267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
158521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)    bool m_drawInPMColorSpace;
159521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)
1605267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)    mutable unsigned m_cachedHash;
1615267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)
162e69819bd8e388ea4ad1636a19aa6b2eed4952191Ben Murdoch    RefPtr<SkShader> m_gradient;
1635267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)};
1645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1655267f701546148b83dfbe1d151cb184385bb5c22Torne (Richard Coles)} // namespace WebCore
1665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
1675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#endif
168