SkShader.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276
  1. /*
  2. * Copyright 2006 The Android Open Source Project
  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. #ifndef SkShader_DEFINED
  8. #define SkShader_DEFINED
  9. #include "SkBlendMode.h"
  10. #include "SkColor.h"
  11. #include "SkFilterQuality.h"
  12. #include "SkFlattenable.h"
  13. #include "SkImageInfo.h"
  14. #include "SkMatrix.h"
  15. class SkArenaAlloc;
  16. class SkBitmap;
  17. class SkColorFilter;
  18. class SkColorSpace;
  19. class SkColorSpaceXformer;
  20. class SkImage;
  21. class SkPath;
  22. class SkPicture;
  23. class SkRasterPipeline;
  24. class GrContext;
  25. class GrFragmentProcessor;
  26. /** \class SkShader
  27. *
  28. * Shaders specify the source color(s) for what is being drawn. If a paint
  29. * has no shader, then the paint's color is used. If the paint has a
  30. * shader, then the shader's color(s) are use instead, but they are
  31. * modulated by the paint's alpha. This makes it easy to create a shader
  32. * once (e.g. bitmap tiling or gradient) and then change its transparency
  33. * w/o having to modify the original shader... only the paint's alpha needs
  34. * to be modified.
  35. */
  36. class SK_API SkShader : public SkFlattenable {
  37. public:
  38. enum TileMode {
  39. /** replicate the edge color if the shader draws outside of its
  40. * original bounds
  41. */
  42. kClamp_TileMode,
  43. /** repeat the shader's image horizontally and vertically */
  44. kRepeat_TileMode,
  45. /** repeat the shader's image horizontally and vertically, alternating
  46. * mirror images so that adjacent images always seam
  47. */
  48. kMirror_TileMode,
  49. /**
  50. * Only draw within the original domain, return transparent-black everywhere else.
  51. * EXPERIMENTAL -- DO NOT USE YET
  52. */
  53. kDecal_TileMode,
  54. kLast_TileMode = kDecal_TileMode,
  55. };
  56. static constexpr int kTileModeCount = kLast_TileMode + 1;
  57. /**
  58. * Returns the local matrix.
  59. *
  60. * FIXME: This can be incorrect for a Shader with its own local matrix
  61. * that is also wrapped via CreateLocalMatrixShader.
  62. */
  63. const SkMatrix& getLocalMatrix() const;
  64. /**
  65. * Returns true if the shader is guaranteed to produce only opaque
  66. * colors, subject to the SkPaint using the shader to apply an opaque
  67. * alpha value. Subclasses should override this to allow some
  68. * optimizations.
  69. */
  70. virtual bool isOpaque() const { return false; }
  71. /**
  72. * Iff this shader is backed by a single SkImage, return its ptr (the caller must ref this
  73. * if they want to keep it longer than the lifetime of the shader). If not, return nullptr.
  74. */
  75. SkImage* isAImage(SkMatrix* localMatrix, TileMode xy[2]) const;
  76. bool isAImage() const {
  77. return this->isAImage(nullptr, nullptr) != nullptr;
  78. }
  79. /**
  80. * If the shader subclass can be represented as a gradient, asAGradient
  81. * returns the matching GradientType enum (or kNone_GradientType if it
  82. * cannot). Also, if info is not null, asAGradient populates info with
  83. * the relevant (see below) parameters for the gradient. fColorCount
  84. * is both an input and output parameter. On input, it indicates how
  85. * many entries in fColors and fColorOffsets can be used, if they are
  86. * non-NULL. After asAGradient has run, fColorCount indicates how
  87. * many color-offset pairs there are in the gradient. If there is
  88. * insufficient space to store all of the color-offset pairs, fColors
  89. * and fColorOffsets will not be altered. fColorOffsets specifies
  90. * where on the range of 0 to 1 to transition to the given color.
  91. * The meaning of fPoint and fRadius is dependant on the type of gradient.
  92. *
  93. * None:
  94. * info is ignored.
  95. * Color:
  96. * fColorOffsets[0] is meaningless.
  97. * Linear:
  98. * fPoint[0] and fPoint[1] are the end-points of the gradient
  99. * Radial:
  100. * fPoint[0] and fRadius[0] are the center and radius
  101. * Conical:
  102. * fPoint[0] and fRadius[0] are the center and radius of the 1st circle
  103. * fPoint[1] and fRadius[1] are the center and radius of the 2nd circle
  104. * Sweep:
  105. * fPoint[0] is the center of the sweep.
  106. */
  107. enum GradientType {
  108. kNone_GradientType,
  109. kColor_GradientType,
  110. kLinear_GradientType,
  111. kRadial_GradientType,
  112. kSweep_GradientType,
  113. kConical_GradientType,
  114. kLast_GradientType = kConical_GradientType,
  115. };
  116. struct GradientInfo {
  117. int fColorCount; //!< In-out parameter, specifies passed size
  118. // of fColors/fColorOffsets on input, and
  119. // actual number of colors/offsets on
  120. // output.
  121. SkColor* fColors; //!< The colors in the gradient.
  122. SkScalar* fColorOffsets; //!< The unit offset for color transitions.
  123. SkPoint fPoint[2]; //!< Type specific, see above.
  124. SkScalar fRadius[2]; //!< Type specific, see above.
  125. TileMode fTileMode; //!< The tile mode used.
  126. uint32_t fGradientFlags; //!< see SkGradientShader::Flags
  127. };
  128. virtual GradientType asAGradient(GradientInfo* info) const;
  129. #ifdef SK_BUILD_FOR_ANDROID_FRAMEWORK
  130. struct ComposeRec {
  131. const SkShader* fShaderA;
  132. const SkShader* fShaderB;
  133. SkBlendMode fBlendMode;
  134. };
  135. virtual bool asACompose(ComposeRec*) const { return false; }
  136. #endif
  137. //////////////////////////////////////////////////////////////////////////
  138. // Methods to create combinations or variants of shaders
  139. /**
  140. * Return a shader that will apply the specified localMatrix to this shader.
  141. * The specified matrix will be applied before any matrix associated with this shader.
  142. */
  143. sk_sp<SkShader> makeWithLocalMatrix(const SkMatrix&) const;
  144. /**
  145. * Create a new shader that produces the same colors as invoking this shader and then applying
  146. * the colorfilter.
  147. */
  148. sk_sp<SkShader> makeWithColorFilter(sk_sp<SkColorFilter>) const;
  149. //////////////////////////////////////////////////////////////////////////
  150. // Factory methods for stock shaders
  151. /**
  152. * Call this to create a new "empty" shader, that will not draw anything.
  153. */
  154. static sk_sp<SkShader> MakeEmptyShader();
  155. /**
  156. * Call this to create a new shader that just draws the specified color. This should always
  157. * draw the same as a paint with this color (and no shader).
  158. */
  159. static sk_sp<SkShader> MakeColorShader(SkColor);
  160. /**
  161. * Create a shader that draws the specified color (in the specified colorspace).
  162. *
  163. * This works around the limitation that SkPaint::setColor() only takes byte values, and does
  164. * not support specific colorspaces.
  165. */
  166. static sk_sp<SkShader> MakeColorShader(const SkColor4f&, sk_sp<SkColorSpace>);
  167. /**
  168. * Compose two shaders together, using two operators: mode and lerp. The resulting colors
  169. * are computed by first combining the src and dst shaders using mode, and then linearly
  170. * interpolating between the dst and result colors using lerp.
  171. *
  172. * result = dst * (1 - lerp) + (src (mode) dst) * lerp
  173. *
  174. * If either shader is nullptr, then this returns nullptr.
  175. * If lerp is NaN then this returns nullptr, otherwise lerp is clamped to [0..1].
  176. */
  177. static sk_sp<SkShader> MakeCompose(sk_sp<SkShader> dst, sk_sp<SkShader> src,
  178. SkBlendMode mode, float lerp = 1);
  179. /*
  180. * DEPRECATED: call MakeCompose.
  181. */
  182. static sk_sp<SkShader> MakeComposeShader(sk_sp<SkShader> dst, sk_sp<SkShader> src,
  183. SkBlendMode mode) {
  184. return MakeCompose(std::move(dst), std::move(src), mode, 1);
  185. }
  186. /**
  187. * Compose two shaders together using a weighted average.
  188. *
  189. * result = dst * (1 - lerp) + src * lerp
  190. *
  191. * If either shader is nullptr, then this returns nullptr.
  192. * If lerp is NaN then this returns nullptr, otherwise lerp is clamped to [0..1].
  193. */
  194. static sk_sp<SkShader> MakeMixer(sk_sp<SkShader> dst, sk_sp<SkShader> src, float lerp) {
  195. return MakeCompose(std::move(dst), std::move(src), SkBlendMode::kSrc, lerp);
  196. }
  197. /** Call this to create a new shader that will draw with the specified bitmap.
  198. *
  199. * If the bitmap cannot be used (e.g. has no pixels, or its dimensions
  200. * exceed implementation limits (currently at 64K - 1)) then SkEmptyShader
  201. * may be returned.
  202. *
  203. * If the src is kA8_Config then that mask will be colorized using the color on
  204. * the paint.
  205. *
  206. * @param src The bitmap to use inside the shader
  207. * @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
  208. * @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
  209. * @return Returns a new shader object. Note: this function never returns null.
  210. */
  211. static sk_sp<SkShader> MakeBitmapShader(const SkBitmap& src, TileMode tmx, TileMode tmy,
  212. const SkMatrix* localMatrix = nullptr);
  213. // NOTE: You can create an SkImage Shader with SkImage::newShader().
  214. /** Call this to create a new shader that will draw with the specified picture.
  215. *
  216. * @param src The picture to use inside the shader (if not NULL, its ref count
  217. * is incremented). The SkPicture must not be changed after
  218. * successfully creating a picture shader.
  219. * @param tmx The tiling mode to use when sampling the bitmap in the x-direction.
  220. * @param tmy The tiling mode to use when sampling the bitmap in the y-direction.
  221. * @param tile The tile rectangle in picture coordinates: this represents the subset
  222. * (or superset) of the picture used when building a tile. It is not
  223. * affected by localMatrix and does not imply scaling (only translation
  224. * and cropping). If null, the tile rect is considered equal to the picture
  225. * bounds.
  226. * @return Returns a new shader object. Note: this function never returns null.
  227. */
  228. static sk_sp<SkShader> MakePictureShader(sk_sp<SkPicture> src, TileMode tmx, TileMode tmy,
  229. const SkMatrix* localMatrix, const SkRect* tile);
  230. /**
  231. * If this shader can be represented by another shader + a localMatrix, return that shader and
  232. * the localMatrix. If not, return nullptr and ignore the localMatrix parameter.
  233. */
  234. // TODO: clean up clients, move to SkShaderBase.
  235. virtual sk_sp<SkShader> makeAsALocalMatrixShader(SkMatrix* localMatrix) const;
  236. private:
  237. SkShader() = default;
  238. friend class SkShaderBase;
  239. typedef SkFlattenable INHERITED;
  240. };
  241. #endif