• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef SkShader_DEFINED
18 #define SkShader_DEFINED
19 
20 #include "SkBitmap.h"
21 #include "SkFlattenable.h"
22 #include "SkMask.h"
23 #include "SkMatrix.h"
24 #include "SkPaint.h"
25 
26 class SkPath;
27 
28 /** \class SkShader
29 
30     SkShader is the based class for objects that return horizontal spans of colors during drawing.
31     A subclass of SkShader is installed in a SkPaint calling paint.setShader(shader). After that
32     any object (other than a bitmap) that is drawn with that paint will get its color(s) from the
33     shader.
34 */
35 class SkShader : public SkFlattenable {
36 public:
37             SkShader();
38     virtual ~SkShader();
39 
40     /** Return true if the shader has a non-identity local matrix.
41         @param localM   Optional: If not null, return the shader's local matrix
42         @return true if the shader has a non-identity local matrix.
43     */
44     bool getLocalMatrix(SkMatrix* localM) const;
45     /** Set the shader's local matrix.
46         @param localM   The shader's new local matrix.
47     */
48     void setLocalMatrix(const SkMatrix& localM);
49     /** Reset the shader's local matrix to identity.
50     */
51     void resetLocalMatrix();
52 
53     enum TileMode {
54         kClamp_TileMode,    //!< replicate the edge color if the shader draws outside of its original bounds
55         kRepeat_TileMode,   //!< repeat the shader's image horizontally and vertically
56         kMirror_TileMode,   //!< repeat the shader's image horizontally and vertically, alternating mirror images so that adjacent images always seam
57 
58         kTileModeCount
59     };
60 
61     // override these in your subclass
62 
63     enum Flags {
64         //!< set if all of the colors will be opaque
65         kOpaqueAlpha_Flag   = 0x01,
66         //! set if this shader's shadeSpan16() method can be called
67         kHasSpan16_Flag     = 0x02,
68         /** Set this bit if the shader's native data type is instrinsically 16
69             bit, meaning that calling the 32bit shadeSpan() entry point will
70             mean the the impl has to up-sample 16bit data into 32bit. Used as a
71             a means of clearing a dither request if the it will have no effect
72         */
73         kIntrinsicly16_Flag = 0x04
74     };
75 
76     /** Called sometimes before drawing with this shader.
77         Return the type of alpha your shader will return.
78         The default implementation returns 0. Your subclass should override if it can
79         (even sometimes) report a non-zero value, since that will enable various blitters
80         to perform faster.
81     */
getFlags()82     virtual uint32_t getFlags() { return 0; }
83 
84     /** Return the alpha associated with the data returned by shadeSpan16(). If
85         kHasSpan16_Flag is not set, this value is meaningless.
86     */
getSpan16Alpha()87     virtual uint8_t getSpan16Alpha() const { return fPaintAlpha; }
88 
89     /** Called once before drawing, with the current paint and
90         device matrix. Return true if your shader supports these
91         parameters, or false if not. If false is returned, nothing
92         will be drawn.
93     */
94     virtual bool    setContext( const SkBitmap& device,
95                                 const SkPaint& paint,
96                                 const SkMatrix& matrix);
97 
98     /** Called for each span of the object being drawn. Your subclass
99         should set the appropriate colors (with premultiplied alpha) that
100         correspond to the specified device coordinates.
101     */
102     virtual void    shadeSpan(int x, int y, SkPMColor[], int count) = 0;
103     /** Called only for 16bit devices when getFlags() returns kOpaqueAlphaFlag | kHasSpan16_Flag
104     */
105     virtual void    shadeSpan16(int x, int y, uint16_t[], int count);
106     /** Similar to shadeSpan, but only returns the alpha-channel for a span.
107         The default implementation calls shadeSpan() and then extracts the alpha
108         values from the returned colors.
109     */
110     virtual void    shadeSpanAlpha(int x, int y, uint8_t alpha[], int count);
111 
112     /** Helper function that returns true if this shader's shadeSpan16() method can
113         be called.
114     */
canCallShadeSpan16()115     bool canCallShadeSpan16()
116     {
117         return SkShader::CanCallShadeSpan16(this->getFlags());
118     }
119 
120     /** Helper to check the flags to know if it is legal to call shadeSpan16()
121     */
CanCallShadeSpan16(uint32_t flags)122     static bool CanCallShadeSpan16(uint32_t flags) {
123         return (flags & kHasSpan16_Flag) != 0;
124     }
125 
126     /** Called before a session using the shader begins. Some shaders override
127         this to defer some of their work (like calling bitmap.lockPixels()).
128         Must be balanced by a call to endSession.
129     */
130     virtual void beginSession();
131     virtual void endSession();
132 
133     /** Optional methods for shaders that can pretend to be a bitmap/texture
134         to play along with opengl. Default just returns false and ignores
135         the out parameters.
136     */
137     virtual bool asABitmap(SkBitmap* outTexture, SkMatrix* outMatrix,
138                            TileMode xy[2]);
139 
140     //////////////////////////////////////////////////////////////////////////
141     //  Factory methods for stock shaders
142 
143     /** Call this to create a new shader that will draw with the specified bitmap.
144         @param src  The bitmap to use inside the shader
145         @param tmx  The tiling mode to use when sampling the bitmap in the x-direction.
146         @param tmy  The tiling mode to use when sampling the bitmap in the y-direction.
147         @return     Returns a new shader object. Note: this function never returns null.
148     */
149     static SkShader* CreateBitmapShader(const SkBitmap& src,
150                                         TileMode tmx, TileMode tmy);
151 
152     virtual void flatten(SkFlattenableWriteBuffer& );
153 protected:
154     enum MatrixClass {
155         kLinear_MatrixClass,            // no perspective
156         kFixedStepInX_MatrixClass,      // fast perspective, need to call fixedStepInX() each scanline
157         kPerspective_MatrixClass        // slow perspective, need to mappoints each pixel
158     };
159     static MatrixClass ComputeMatrixClass(const SkMatrix&);
160 
161     // These can be called by your subclass after setContext() has been called
getPaintAlpha()162     uint8_t             getPaintAlpha() const { return fPaintAlpha; }
getDeviceConfig()163     SkBitmap::Config    getDeviceConfig() const { return (SkBitmap::Config)fDeviceConfig; }
getTotalInverse()164     const SkMatrix&     getTotalInverse() const { return fTotalInverse; }
getInverseClass()165     MatrixClass         getInverseClass() const { return (MatrixClass)fTotalInverseClass; }
166 
167     SkShader(SkFlattenableReadBuffer& );
168 private:
169     SkMatrix*           fLocalMatrix;
170     SkMatrix            fTotalInverse;
171     uint8_t             fPaintAlpha;
172     uint8_t             fDeviceConfig;
173     uint8_t             fTotalInverseClass;
174     SkDEBUGCODE(SkBool8 fInSession;)
175 
176     static SkShader* CreateBitmapShader(const SkBitmap& src,
177                                         TileMode, TileMode,
178                                         void* storage, size_t storageSize);
179     friend class SkAutoBitmapShaderInstall;
180     typedef SkFlattenable INHERITED;
181 };
182 
183 #endif
184 
185