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