SkPaint.h 26 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  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 SkPaint_DEFINED
  8. #define SkPaint_DEFINED
  9. #include "include/core/SkBlendMode.h"
  10. #include "include/core/SkColor.h"
  11. #include "include/core/SkFilterQuality.h"
  12. #include "include/core/SkRefCnt.h"
  13. #include "include/private/SkTo.h"
  14. class SkColorFilter;
  15. class SkColorSpace;
  16. class SkDrawLooper;
  17. struct SkRect;
  18. class SkImageFilter;
  19. class SkMaskFilter;
  20. class SkPath;
  21. class SkPathEffect;
  22. class SkShader;
  23. /** \class SkPaint
  24. SkPaint controls options applied when drawing. SkPaint collects all
  25. options outside of the SkCanvas clip and SkCanvas matrix.
  26. Various options apply to strokes and fills, and images.
  27. SkPaint collects effects and filters that describe single-pass and multiple-pass
  28. algorithms that alter the drawing geometry, color, and transparency. For instance,
  29. SkPaint does not directly implement dashing or blur, but contains the objects that do so.
  30. */
  31. class SK_API SkPaint {
  32. public:
  33. /** Constructs SkPaint with default values.
  34. @return default initialized SkPaint
  35. */
  36. SkPaint();
  37. /** Constructs SkPaint with default values and the given color.
  38. Sets alpha and RGB used when stroking and filling. The color is four floating
  39. point values, unpremultiplied. The color values are interpreted as being in
  40. the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
  41. sRGB color space.
  42. @param color unpremultiplied RGBA
  43. @param colorSpace SkColorSpace describing the encoding of color
  44. @return SkPaint with the given color
  45. */
  46. explicit SkPaint(const SkColor4f& color, SkColorSpace* colorSpace = nullptr);
  47. /** Makes a shallow copy of SkPaint. SkPathEffect, SkShader,
  48. SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter are shared
  49. between the original paint and the copy. Objects containing SkRefCnt increment
  50. their references by one.
  51. The referenced objects SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
  52. SkDrawLooper, and SkImageFilter cannot be modified after they are created.
  53. This prevents objects with SkRefCnt from being modified once SkPaint refers to them.
  54. @param paint original to copy
  55. @return shallow copy of paint
  56. */
  57. SkPaint(const SkPaint& paint);
  58. /** Implements a move constructor to avoid increasing the reference counts
  59. of objects referenced by the paint.
  60. After the call, paint is undefined, and can be safely destructed.
  61. @param paint original to move
  62. @return content of paint
  63. */
  64. SkPaint(SkPaint&& paint);
  65. /** Decreases SkPaint SkRefCnt of owned objects: SkPathEffect, SkShader,
  66. SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter. If the
  67. objects containing SkRefCnt go to zero, they are deleted.
  68. */
  69. ~SkPaint();
  70. /** Makes a shallow copy of SkPaint. SkPathEffect, SkShader,
  71. SkMaskFilter, SkColorFilter, SkDrawLooper, and SkImageFilter are shared
  72. between the original paint and the copy. Objects containing SkRefCnt in the
  73. prior destination are decreased by one, and the referenced objects are deleted if the
  74. resulting count is zero. Objects containing SkRefCnt in the parameter paint
  75. are increased by one. paint is unmodified.
  76. @param paint original to copy
  77. @return content of paint
  78. */
  79. SkPaint& operator=(const SkPaint& paint);
  80. /** Moves the paint to avoid increasing the reference counts
  81. of objects referenced by the paint parameter. Objects containing SkRefCnt in the
  82. prior destination are decreased by one; those objects are deleted if the resulting count
  83. is zero.
  84. After the call, paint is undefined, and can be safely destructed.
  85. @param paint original to move
  86. @return content of paint
  87. */
  88. SkPaint& operator=(SkPaint&& paint);
  89. /** Compares a and b, and returns true if a and b are equivalent. May return false
  90. if SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
  91. SkDrawLooper, or SkImageFilter have identical contents but different pointers.
  92. @param a SkPaint to compare
  93. @param b SkPaint to compare
  94. @return true if SkPaint pair are equivalent
  95. */
  96. SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
  97. /** Compares a and b, and returns true if a and b are not equivalent. May return true
  98. if SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
  99. SkDrawLooper, or SkImageFilter have identical contents but different pointers.
  100. @param a SkPaint to compare
  101. @param b SkPaint to compare
  102. @return true if SkPaint pair are not equivalent
  103. */
  104. friend bool operator!=(const SkPaint& a, const SkPaint& b) {
  105. return !(a == b);
  106. }
  107. /** Returns a hash generated from SkPaint values and pointers.
  108. Identical hashes guarantee that the paints are
  109. equivalent, but differing hashes do not guarantee that the paints have differing
  110. contents.
  111. If operator==(const SkPaint& a, const SkPaint& b) returns true for two paints,
  112. their hashes are also equal.
  113. The hash returned is platform and implementation specific.
  114. @return a shallow hash
  115. */
  116. uint32_t getHash() const;
  117. /** Sets all SkPaint contents to their initial values. This is equivalent to replacing
  118. SkPaint with the result of SkPaint().
  119. */
  120. void reset();
  121. /** Returns true if pixels on the active edges of SkPath may be drawn with partial transparency.
  122. @return antialiasing state
  123. */
  124. bool isAntiAlias() const {
  125. return SkToBool(fBitfields.fAntiAlias);
  126. }
  127. /** Requests, but does not require, that edge pixels draw opaque or with
  128. partial transparency.
  129. @param aa setting for antialiasing
  130. */
  131. void setAntiAlias(bool aa) { fBitfields.fAntiAlias = static_cast<unsigned>(aa); }
  132. /** Returns true if color error may be distributed to smooth color transition.
  133. @return dithering state
  134. */
  135. bool isDither() const {
  136. return SkToBool(fBitfields.fDither);
  137. }
  138. /** Requests, but does not require, to distribute color error.
  139. @param dither setting for ditering
  140. */
  141. void setDither(bool dither) { fBitfields.fDither = static_cast<unsigned>(dither); }
  142. /** Returns SkFilterQuality, the image filtering level. A lower setting
  143. draws faster; a higher setting looks better when the image is scaled.
  144. @return one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
  145. kMedium_SkFilterQuality, kHigh_SkFilterQuality
  146. */
  147. SkFilterQuality getFilterQuality() const {
  148. return (SkFilterQuality)fBitfields.fFilterQuality;
  149. }
  150. /** Sets SkFilterQuality, the image filtering level. A lower setting
  151. draws faster; a higher setting looks better when the image is scaled.
  152. Does not check to see if quality is valid.
  153. @param quality one of: kNone_SkFilterQuality, kLow_SkFilterQuality,
  154. kMedium_SkFilterQuality, kHigh_SkFilterQuality
  155. */
  156. void setFilterQuality(SkFilterQuality quality);
  157. /** \enum SkPaint::Style
  158. Set Style to fill, stroke, or both fill and stroke geometry.
  159. The stroke and fill
  160. share all paint attributes; for instance, they are drawn with the same color.
  161. Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
  162. a fill draw.
  163. */
  164. enum Style : uint8_t {
  165. kFill_Style, //!< set to fill geometry
  166. kStroke_Style, //!< set to stroke geometry
  167. kStrokeAndFill_Style, //!< sets to stroke and fill geometry
  168. };
  169. /** May be used to verify that SkPaint::Style is a legal value.
  170. */
  171. static constexpr int kStyleCount = kStrokeAndFill_Style + 1;
  172. /** Returns whether the geometry is filled, stroked, or filled and stroked.
  173. @return one of:kFill_Style, kStroke_Style, kStrokeAndFill_Style
  174. */
  175. Style getStyle() const { return (Style)fBitfields.fStyle; }
  176. /** Sets whether the geometry is filled, stroked, or filled and stroked.
  177. Has no effect if style is not a legal SkPaint::Style value.
  178. @param style one of: kFill_Style, kStroke_Style, kStrokeAndFill_Style
  179. */
  180. void setStyle(Style style);
  181. /** Retrieves alpha and RGB, unpremultiplied, packed into 32 bits.
  182. Use helpers SkColorGetA(), SkColorGetR(), SkColorGetG(), and SkColorGetB() to extract
  183. a color component.
  184. @return unpremultiplied ARGB
  185. */
  186. SkColor getColor() const { return fColor4f.toSkColor(); }
  187. /** Retrieves alpha and RGB, unpremultiplied, as four floating point values. RGB are
  188. are extended sRGB values (sRGB gamut, and encoded with the sRGB transfer function).
  189. @return unpremultiplied RGBA
  190. */
  191. SkColor4f getColor4f() const { return fColor4f; }
  192. /** Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
  193. unpremultiplied, packing 8-bit components for alpha, red, blue, and green.
  194. @param color unpremultiplied ARGB
  195. */
  196. void setColor(SkColor color);
  197. /** Sets alpha and RGB used when stroking and filling. The color is four floating
  198. point values, unpremultiplied. The color values are interpreted as being in
  199. the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
  200. sRGB color space.
  201. @param color unpremultiplied RGBA
  202. @param colorSpace SkColorSpace describing the encoding of color
  203. */
  204. void setColor(const SkColor4f& color, SkColorSpace* colorSpace = nullptr);
  205. void setColor4f(const SkColor4f& color, SkColorSpace* colorSpace = nullptr) {
  206. this->setColor(color, colorSpace);
  207. }
  208. /** Retrieves alpha from the color used when stroking and filling.
  209. @return alpha ranging from zero, fully transparent, to 255, fully opaque
  210. */
  211. float getAlphaf() const { return fColor4f.fA; }
  212. // Helper that scales the alpha by 255.
  213. uint8_t getAlpha() const { return sk_float_round2int(this->getAlphaf() * 255); }
  214. /** Replaces alpha, leaving RGB
  215. unchanged. An out of range value triggers an assert in the debug
  216. build. a is a value from 0.0 to 1.0.
  217. a set to zero makes color fully transparent; a set to 1.0 makes color
  218. fully opaque.
  219. @param a alpha component of color
  220. */
  221. void setAlphaf(float a);
  222. // Helper that accepts an int between 0 and 255, and divides it by 255.0
  223. void setAlpha(U8CPU a) {
  224. this->setAlphaf(a * (1.0f / 255));
  225. }
  226. /** Sets color used when drawing solid fills. The color components range from 0 to 255.
  227. The color is unpremultiplied; alpha sets the transparency independent of RGB.
  228. @param a amount of alpha, from fully transparent (0) to fully opaque (255)
  229. @param r amount of red, from no red (0) to full red (255)
  230. @param g amount of green, from no green (0) to full green (255)
  231. @param b amount of blue, from no blue (0) to full blue (255)
  232. */
  233. void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
  234. /** Returns the thickness of the pen used by SkPaint to
  235. outline the shape.
  236. @return zero for hairline, greater than zero for pen thickness
  237. */
  238. SkScalar getStrokeWidth() const { return fWidth; }
  239. /** Sets the thickness of the pen used by the paint to
  240. outline the shape.
  241. Has no effect if width is less than zero.
  242. @param width zero thickness for hairline; greater than zero for pen thickness
  243. */
  244. void setStrokeWidth(SkScalar width);
  245. /** Returns the limit at which a sharp corner is drawn beveled.
  246. @return zero and greater miter limit
  247. */
  248. SkScalar getStrokeMiter() const { return fMiterLimit; }
  249. /** Sets the limit at which a sharp corner is drawn beveled.
  250. Valid values are zero and greater.
  251. Has no effect if miter is less than zero.
  252. @param miter zero and greater miter limit
  253. */
  254. void setStrokeMiter(SkScalar miter);
  255. /** \enum SkPaint::Cap
  256. Cap draws at the beginning and end of an open path contour.
  257. */
  258. enum Cap {
  259. kButt_Cap, //!< no stroke extension
  260. kRound_Cap, //!< adds circle
  261. kSquare_Cap, //!< adds square
  262. kLast_Cap = kSquare_Cap, //!< largest Cap value
  263. kDefault_Cap = kButt_Cap, //!< equivalent to kButt_Cap
  264. };
  265. /** May be used to verify that SkPaint::Cap is a legal value.
  266. */
  267. static constexpr int kCapCount = kLast_Cap + 1;
  268. /** \enum SkPaint::Join
  269. Join specifies how corners are drawn when a shape is stroked. Join
  270. affects the four corners of a stroked rectangle, and the connected segments in a
  271. stroked path.
  272. Choose miter join to draw sharp corners. Choose round join to draw a circle with a
  273. radius equal to the stroke width on top of the corner. Choose bevel join to minimally
  274. connect the thick strokes.
  275. The fill path constructed to describe the stroked path respects the join setting but may
  276. not contain the actual join. For instance, a fill path constructed with round joins does
  277. not necessarily include circles at each connected segment.
  278. */
  279. enum Join : uint8_t {
  280. kMiter_Join, //!< extends to miter limit
  281. kRound_Join, //!< adds circle
  282. kBevel_Join, //!< connects outside edges
  283. kLast_Join = kBevel_Join, //!< equivalent to the largest value for Join
  284. kDefault_Join = kMiter_Join, //!< equivalent to kMiter_Join
  285. };
  286. /** May be used to verify that SkPaint::Join is a legal value.
  287. */
  288. static constexpr int kJoinCount = kLast_Join + 1;
  289. /** Returns the geometry drawn at the beginning and end of strokes.
  290. @return one of: kButt_Cap, kRound_Cap, kSquare_Cap
  291. */
  292. Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
  293. /** Sets the geometry drawn at the beginning and end of strokes.
  294. @param cap one of: kButt_Cap, kRound_Cap, kSquare_Cap;
  295. has no effect if cap is not valid
  296. */
  297. void setStrokeCap(Cap cap);
  298. /** Returns the geometry drawn at the corners of strokes.
  299. @return one of: kMiter_Join, kRound_Join, kBevel_Join
  300. */
  301. Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
  302. /** Sets the geometry drawn at the corners of strokes.
  303. @param join one of: kMiter_Join, kRound_Join, kBevel_Join;
  304. otherwise, has no effect
  305. */
  306. void setStrokeJoin(Join join);
  307. /** Returns the filled equivalent of the stroked path.
  308. @param src SkPath read to create a filled version
  309. @param dst resulting SkPath; may be the same as src, but may not be nullptr
  310. @param cullRect optional limit passed to SkPathEffect
  311. @param resScale if > 1, increase precision, else if (0 < resScale < 1) reduce precision
  312. to favor speed and size
  313. @return true if the path represents style fill, or false if it represents hairline
  314. */
  315. bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
  316. SkScalar resScale = 1) const;
  317. /** Returns the filled equivalent of the stroked path.
  318. Replaces dst with the src path modified by SkPathEffect and style stroke.
  319. SkPathEffect, if any, is not culled. stroke width is created with default precision.
  320. @param src SkPath read to create a filled version
  321. @param dst resulting SkPath dst may be the same as src, but may not be nullptr
  322. @return true if the path represents style fill, or false if it represents hairline
  323. */
  324. bool getFillPath(const SkPath& src, SkPath* dst) const {
  325. return this->getFillPath(src, dst, nullptr, 1);
  326. }
  327. /** Returns optional colors used when filling a path, such as a gradient.
  328. Does not alter SkShader SkRefCnt.
  329. @return SkShader if previously set, nullptr otherwise
  330. */
  331. SkShader* getShader() const { return fShader.get(); }
  332. /** Returns optional colors used when filling a path, such as a gradient.
  333. Increases SkShader SkRefCnt by one.
  334. @return SkShader if previously set, nullptr otherwise
  335. */
  336. sk_sp<SkShader> refShader() const;
  337. /** Sets optional colors used when filling a path, such as a gradient.
  338. Sets SkShader to shader, decreasing SkRefCnt of the previous SkShader.
  339. Increments shader SkRefCnt by one.
  340. @param shader how geometry is filled with color; if nullptr, color is used instead
  341. */
  342. void setShader(sk_sp<SkShader> shader);
  343. /** Returns SkColorFilter if set, or nullptr.
  344. Does not alter SkColorFilter SkRefCnt.
  345. @return SkColorFilter if previously set, nullptr otherwise
  346. */
  347. SkColorFilter* getColorFilter() const { return fColorFilter.get(); }
  348. /** Returns SkColorFilter if set, or nullptr.
  349. Increases SkColorFilter SkRefCnt by one.
  350. @return SkColorFilter if set, or nullptr
  351. */
  352. sk_sp<SkColorFilter> refColorFilter() const;
  353. /** Sets SkColorFilter to filter, decreasing SkRefCnt of the previous
  354. SkColorFilter. Pass nullptr to clear SkColorFilter.
  355. Increments filter SkRefCnt by one.
  356. @param colorFilter SkColorFilter to apply to subsequent draw
  357. */
  358. void setColorFilter(sk_sp<SkColorFilter> colorFilter);
  359. /** Returns SkBlendMode.
  360. By default, returns SkBlendMode::kSrcOver.
  361. @return mode used to combine source color with destination color
  362. */
  363. SkBlendMode getBlendMode() const { return (SkBlendMode)fBitfields.fBlendMode; }
  364. /** Returns true if SkBlendMode is SkBlendMode::kSrcOver, the default.
  365. @return true if SkBlendMode is SkBlendMode::kSrcOver
  366. */
  367. bool isSrcOver() const { return (SkBlendMode)fBitfields.fBlendMode == SkBlendMode::kSrcOver; }
  368. /** Sets SkBlendMode to mode.
  369. Does not check for valid input.
  370. @param mode SkBlendMode used to combine source color and destination
  371. */
  372. void setBlendMode(SkBlendMode mode) { fBitfields.fBlendMode = (unsigned)mode; }
  373. /** Returns SkPathEffect if set, or nullptr.
  374. Does not alter SkPathEffect SkRefCnt.
  375. @return SkPathEffect if previously set, nullptr otherwise
  376. */
  377. SkPathEffect* getPathEffect() const { return fPathEffect.get(); }
  378. /** Returns SkPathEffect if set, or nullptr.
  379. Increases SkPathEffect SkRefCnt by one.
  380. @return SkPathEffect if previously set, nullptr otherwise
  381. */
  382. sk_sp<SkPathEffect> refPathEffect() const;
  383. /** Sets SkPathEffect to pathEffect, decreasing SkRefCnt of the previous
  384. SkPathEffect. Pass nullptr to leave the path geometry unaltered.
  385. Increments pathEffect SkRefCnt by one.
  386. @param pathEffect replace SkPath with a modification when drawn
  387. */
  388. void setPathEffect(sk_sp<SkPathEffect> pathEffect);
  389. /** Returns SkMaskFilter if set, or nullptr.
  390. Does not alter SkMaskFilter SkRefCnt.
  391. @return SkMaskFilter if previously set, nullptr otherwise
  392. */
  393. SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }
  394. /** Returns SkMaskFilter if set, or nullptr.
  395. Increases SkMaskFilter SkRefCnt by one.
  396. @return SkMaskFilter if previously set, nullptr otherwise
  397. */
  398. sk_sp<SkMaskFilter> refMaskFilter() const;
  399. /** Sets SkMaskFilter to maskFilter, decreasing SkRefCnt of the previous
  400. SkMaskFilter. Pass nullptr to clear SkMaskFilter and leave SkMaskFilter effect on
  401. mask alpha unaltered.
  402. Increments maskFilter SkRefCnt by one.
  403. @param maskFilter modifies clipping mask generated from drawn geometry
  404. */
  405. void setMaskFilter(sk_sp<SkMaskFilter> maskFilter);
  406. /** Returns SkImageFilter if set, or nullptr.
  407. Does not alter SkImageFilter SkRefCnt.
  408. @return SkImageFilter if previously set, nullptr otherwise
  409. */
  410. SkImageFilter* getImageFilter() const { return fImageFilter.get(); }
  411. /** Returns SkImageFilter if set, or nullptr.
  412. Increases SkImageFilter SkRefCnt by one.
  413. @return SkImageFilter if previously set, nullptr otherwise
  414. */
  415. sk_sp<SkImageFilter> refImageFilter() const;
  416. /** Sets SkImageFilter to imageFilter, decreasing SkRefCnt of the previous
  417. SkImageFilter. Pass nullptr to clear SkImageFilter, and remove SkImageFilter effect
  418. on drawing.
  419. Increments imageFilter SkRefCnt by one.
  420. @param imageFilter how SkImage is sampled when transformed
  421. */
  422. void setImageFilter(sk_sp<SkImageFilter> imageFilter);
  423. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  424. /** Returns SkDrawLooper if set, or nullptr.
  425. Does not alter SkDrawLooper SkRefCnt.
  426. @return SkDrawLooper if previously set, nullptr otherwise
  427. */
  428. SkDrawLooper* getDrawLooper() const { return fDrawLooper.get(); }
  429. /** Returns SkDrawLooper if set, or nullptr.
  430. Increases SkDrawLooper SkRefCnt by one.
  431. @return SkDrawLooper if previously set, nullptr otherwise
  432. */
  433. sk_sp<SkDrawLooper> refDrawLooper() const;
  434. /** Deprecated.
  435. (see skbug.com/6259)
  436. */
  437. SkDrawLooper* getLooper() const { return fDrawLooper.get(); }
  438. /** Sets SkDrawLooper to drawLooper, decreasing SkRefCnt of the previous
  439. drawLooper. Pass nullptr to clear SkDrawLooper and leave SkDrawLooper effect on
  440. drawing unaltered.
  441. Increments drawLooper SkRefCnt by one.
  442. @param drawLooper iterates through drawing one or more time, altering SkPaint
  443. */
  444. void setDrawLooper(sk_sp<SkDrawLooper> drawLooper);
  445. /** Deprecated.
  446. (see skbug.com/6259)
  447. */
  448. void setLooper(sk_sp<SkDrawLooper> drawLooper);
  449. #endif
  450. /** Returns true if SkPaint prevents all drawing;
  451. otherwise, the SkPaint may or may not allow drawing.
  452. Returns true if, for example, SkBlendMode combined with alpha computes a
  453. new alpha of zero.
  454. @return true if SkPaint prevents all drawing
  455. */
  456. bool nothingToDraw() const;
  457. /** (to be made private)
  458. Returns true if SkPaint does not include elements requiring extensive computation
  459. to compute SkBaseDevice bounds of drawn geometry. For instance, SkPaint with SkPathEffect
  460. always returns false.
  461. @return true if SkPaint allows for fast computation of bounds
  462. */
  463. bool canComputeFastBounds() const;
  464. /** (to be made private)
  465. Only call this if canComputeFastBounds() returned true. This takes a
  466. raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
  467. effects in the paint (e.g. stroking). If needed, it uses the storage
  468. parameter. It returns the adjusted bounds that can then be used
  469. for SkCanvas::quickReject tests.
  470. The returned SkRect will either be orig or storage, thus the caller
  471. should not rely on storage being set to the result, but should always
  472. use the returned value. It is legal for orig and storage to be the same
  473. SkRect.
  474. For example:
  475. if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
  476. SkRect storage;
  477. if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) {
  478. return; // do not draw the path
  479. }
  480. }
  481. // draw the path
  482. @param orig geometry modified by SkPaint when drawn
  483. @param storage computed bounds of geometry; may not be nullptr
  484. @return fast computed bounds
  485. */
  486. const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
  487. // Things like stroking, etc... will do math on the bounds rect, assuming that it's sorted.
  488. SkASSERT(orig.isSorted());
  489. SkPaint::Style style = this->getStyle();
  490. // ultra fast-case: filling with no effects that affect geometry
  491. if (kFill_Style == style) {
  492. uintptr_t effects = 0;
  493. #ifdef SK_SUPPORT_LEGACY_DRAWLOOPER
  494. effects |= reinterpret_cast<uintptr_t>(this->getLooper());
  495. #endif
  496. effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
  497. effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
  498. effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
  499. if (!effects) {
  500. return orig;
  501. }
  502. }
  503. return this->doComputeFastBounds(orig, storage, style);
  504. }
  505. /** (to be made private)
  506. @param orig geometry modified by SkPaint when drawn
  507. @param storage computed bounds of geometry
  508. @return fast computed bounds
  509. */
  510. const SkRect& computeFastStrokeBounds(const SkRect& orig,
  511. SkRect* storage) const {
  512. return this->doComputeFastBounds(orig, storage, kStroke_Style);
  513. }
  514. /** (to be made private)
  515. Computes the bounds, overriding the SkPaint SkPaint::Style. This can be used to
  516. account for additional width required by stroking orig, without
  517. altering SkPaint::Style set to fill.
  518. @param orig geometry modified by SkPaint when drawn
  519. @param storage computed bounds of geometry
  520. @param style overrides SkPaint::Style
  521. @return fast computed bounds
  522. */
  523. const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
  524. Style style) const;
  525. private:
  526. sk_sp<SkPathEffect> fPathEffect;
  527. sk_sp<SkShader> fShader;
  528. sk_sp<SkMaskFilter> fMaskFilter;
  529. sk_sp<SkColorFilter> fColorFilter;
  530. sk_sp<SkDrawLooper> fDrawLooper;
  531. sk_sp<SkImageFilter> fImageFilter;
  532. SkColor4f fColor4f;
  533. SkScalar fWidth;
  534. SkScalar fMiterLimit;
  535. union {
  536. struct {
  537. unsigned fAntiAlias : 1;
  538. unsigned fDither : 1;
  539. unsigned fCapType : 2;
  540. unsigned fJoinType : 2;
  541. unsigned fStyle : 2;
  542. unsigned fFilterQuality : 2;
  543. unsigned fBlendMode : 8; // only need 5-6?
  544. unsigned fPadding : 14; // 14==32-1-1-2-2-2-2-8
  545. } fBitfields;
  546. uint32_t fBitfieldsUInt;
  547. };
  548. };
  549. #endif