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