1 /*
2  * Copyright 2016 Google Inc.
3  *
4  * Use of this source code is governed by a BSD-style license that can be
5  * found in the LICENSE file.
6  */
7 
8 #ifndef Sk4fGradientBase_DEFINED
9 #define Sk4fGradientBase_DEFINED
10 
11 #include "Sk4fGradientPriv.h"
12 #include "SkColor.h"
13 #include "SkGradientShaderPriv.h"
14 #include "SkMatrix.h"
15 #include "SkNx.h"
16 #include "SkPM4f.h"
17 #include "SkShader.h"
18 #include "SkTArray.h"
19 
20 struct Sk4fGradientInterval {
21     Sk4fGradientInterval(const Sk4f& c0, SkScalar p0,
22                          const Sk4f& c1, SkScalar p1);
23 
containsSk4fGradientInterval24     bool contains(SkScalar t) const {
25         // True if t is in [p0,p1].  Note: this helper assumes a
26         // natural/increasing interval - so it's not usable in Sk4fLinearGradient.
27         SkASSERT(fP0 < fP1);
28         return t >= fP0 && t <= fP1;
29     }
30 
31     SkPM4f   fC0, fDc;
32     SkScalar fP0, fP1;
33     bool     fZeroRamp;
34 };
35 
36 class Sk4fGradientIntervalBuffer {
37 public:
38     void init(const SkColor colors[], const SkScalar pos[], int count,
39               SkShader::TileMode tileMode, bool premulColors, SkScalar alpha, bool reverse);
40 
41     const Sk4fGradientInterval* find(SkScalar t) const;
42     const Sk4fGradientInterval* findNext(SkScalar t, const Sk4fGradientInterval* prev,
43                                          bool increasing) const;
44 
45     using BufferType = SkSTArray<8, Sk4fGradientInterval, true>;
46 
47     const BufferType* operator->() const { return &fIntervals; }
48 
49 private:
50     BufferType fIntervals;
51 };
52 
53 class SkGradientShaderBase::
54 GradientShaderBase4fContext : public SkShader::Context {
55 public:
56     GradientShaderBase4fContext(const SkGradientShaderBase&,
57                                 const ContextRec&);
58 
getFlags()59     uint32_t getFlags() const override { return fFlags; }
60 
61     void shadeSpan(int x, int y, SkPMColor dst[], int count) override;
62     void shadeSpan4f(int x, int y, SkPM4f dst[], int count) override;
63 
64     bool isValid() const;
65 
66 protected:
67     virtual void mapTs(int x, int y, SkScalar ts[], int count) const = 0;
68 
69     Sk4fGradientIntervalBuffer fIntervals;
70     SkMatrix                   fDstToPos;
71     SkMatrix::MapXYProc        fDstToPosProc;
72     uint8_t                    fDstToPosClass;
73     uint8_t                    fFlags;
74     bool                       fDither;
75     bool                       fColorsArePremul;
76 
77 private:
78     using INHERITED = SkShader::Context;
79 
80     void addMirrorIntervals(const SkGradientShaderBase&,
81                             const Sk4f& componentScale, bool reverse);
82 
83     template<DstType, ApplyPremul, SkShader::TileMode tileMode>
84     class TSampler;
85 
86     template <DstType dstType, ApplyPremul premul>
87     void shadePremulSpan(int x, int y, typename DstTraits<dstType, premul>::Type[],
88                          int count) const;
89 
90     template <DstType dstType, ApplyPremul premul, SkShader::TileMode tileMode>
91     void shadeSpanInternal(int x, int y, typename DstTraits<dstType, premul>::Type[],
92                            int count) const;
93 };
94 
95 #endif // Sk4fGradientBase_DEFINED
96