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