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 dithering 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 /** When stroking a small joinAngle with miter, the miterLength may be very long. 321 When miterLength > maxMiterLength (or joinAngle < minJoinAngle) the join will become bevel. 322 miterLimit = maxMiterLength / strokeWidth or miterLimit = 1 / sin(minJoinAngle / 2). 323 324 This call has no effect if the miterLimit passed is less than zero. 325 Values less than one will be treated as bevel. 326 327 @param miterLimit zero and greater miter limit 328 329 example: https://fiddle.skia.org/c/@Paint_setStrokeMiter 330 */ 331 void setStrokeMiter(SkScalar miterLimit); 332 333 /** \enum SkPaint::Cap 334 Cap draws at the beginning and end of an open path contour. 335 */ 336 enum Cap { 337 kButt_Cap, //!< no stroke extension 338 kRound_Cap, //!< adds circle 339 kSquare_Cap, //!< adds square 340 kLast_Cap = kSquare_Cap, //!< largest Cap value 341 kDefault_Cap = kButt_Cap, //!< equivalent to kButt_Cap 342 }; 343 344 /** May be used to verify that SkPaint::Cap is a legal value. 345 */ 346 static constexpr int kCapCount = kLast_Cap + 1; 347 348 /** \enum SkPaint::Join 349 Join specifies how corners are drawn when a shape is stroked. Join 350 affects the four corners of a stroked rectangle, and the connected segments in a 351 stroked path. 352 353 Choose miter join to draw sharp corners. Choose round join to draw a circle with a 354 radius equal to the stroke width on top of the corner. Choose bevel join to minimally 355 connect the thick strokes. 356 357 The fill path constructed to describe the stroked path respects the join setting but may 358 not contain the actual join. For instance, a fill path constructed with round joins does 359 not necessarily include circles at each connected segment. 360 */ 361 enum Join : uint8_t { 362 kMiter_Join, //!< extends to miter limit 363 kRound_Join, //!< adds circle 364 kBevel_Join, //!< connects outside edges 365 kLast_Join = kBevel_Join, //!< equivalent to the largest value for Join 366 kDefault_Join = kMiter_Join, //!< equivalent to kMiter_Join 367 }; 368 369 /** May be used to verify that SkPaint::Join is a legal value. 370 */ 371 static constexpr int kJoinCount = kLast_Join + 1; 372 373 /** Returns the geometry drawn at the beginning and end of strokes. 374 */ getStrokeCap()375 Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; } 376 377 /** Sets the geometry drawn at the beginning and end of strokes. 378 379 example: https://fiddle.skia.org/c/@Paint_setStrokeCap_a 380 example: https://fiddle.skia.org/c/@Paint_setStrokeCap_b 381 */ 382 void setStrokeCap(Cap cap); 383 384 /** Returns the geometry drawn at the corners of strokes. 385 */ getStrokeJoin()386 Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; } 387 388 /** Sets the geometry drawn at the corners of strokes. 389 390 example: https://fiddle.skia.org/c/@Paint_setStrokeJoin 391 */ 392 void setStrokeJoin(Join join); 393 394 /** Returns optional colors used when filling a path, such as a gradient. 395 396 Does not alter SkShader SkRefCnt. 397 398 @return SkShader if previously set, nullptr otherwise 399 */ getShader()400 SkShader* getShader() const { return fShader.get(); } 401 402 /** Returns optional colors used when filling a path, such as a gradient. 403 404 Increases SkShader SkRefCnt by one. 405 406 @return SkShader if previously set, nullptr otherwise 407 408 example: https://fiddle.skia.org/c/@Paint_refShader 409 */ 410 sk_sp<SkShader> refShader() const; 411 412 /** Sets optional colors used when filling a path, such as a gradient. 413 414 Sets SkShader to shader, decreasing SkRefCnt of the previous SkShader. 415 Increments shader SkRefCnt by one. 416 417 @param shader how geometry is filled with color; if nullptr, color is used instead 418 419 example: https://fiddle.skia.org/c/@Color_Filter_Methods 420 example: https://fiddle.skia.org/c/@Paint_setShader 421 */ 422 void setShader(sk_sp<SkShader> shader); 423 424 /** Returns SkColorFilter if set, or nullptr. 425 Does not alter SkColorFilter SkRefCnt. 426 427 @return SkColorFilter if previously set, nullptr otherwise 428 */ getColorFilter()429 SkColorFilter* getColorFilter() const { return fColorFilter.get(); } 430 431 /** Returns SkColorFilter if set, or nullptr. 432 Increases SkColorFilter SkRefCnt by one. 433 434 @return SkColorFilter if set, or nullptr 435 436 example: https://fiddle.skia.org/c/@Paint_refColorFilter 437 */ 438 sk_sp<SkColorFilter> refColorFilter() const; 439 440 /** Sets SkColorFilter to filter, decreasing SkRefCnt of the previous 441 SkColorFilter. Pass nullptr to clear SkColorFilter. 442 443 Increments filter SkRefCnt by one. 444 445 @param colorFilter SkColorFilter to apply to subsequent draw 446 447 example: https://fiddle.skia.org/c/@Blend_Mode_Methods 448 example: https://fiddle.skia.org/c/@Paint_setColorFilter 449 */ 450 void setColorFilter(sk_sp<SkColorFilter> colorFilter); 451 452 /** If the current blender can be represented as a SkBlendMode enum, this returns that 453 * enum in the optional's value(). If it cannot, then the returned optional does not 454 * contain a value. 455 */ 456 std::optional<SkBlendMode> asBlendMode() const; 457 458 /** 459 * Queries the blender, and if it can be represented as a SkBlendMode, return that mode, 460 * else return the defaultMode provided. 461 */ 462 SkBlendMode getBlendMode_or(SkBlendMode defaultMode) const; 463 464 /** Returns true iff the current blender claims to be equivalent to SkBlendMode::kSrcOver. 465 * 466 * Also returns true of the current blender is nullptr. 467 */ 468 bool isSrcOver() const; 469 470 /** Helper method for calling setBlender(). 471 * 472 * This sets a blender that implements the specified blendmode enum. 473 */ 474 void setBlendMode(SkBlendMode mode); 475 476 /** Returns the user-supplied blend function, if one has been set. 477 * Does not alter SkBlender's SkRefCnt. 478 * 479 * A nullptr blender signifies the default SrcOver behavior. 480 * 481 * @return the SkBlender assigned to this paint, otherwise nullptr 482 */ getBlender()483 SkBlender* getBlender() const { return fBlender.get(); } 484 485 /** Returns the user-supplied blend function, if one has been set. 486 * Increments the SkBlender's SkRefCnt by one. 487 * 488 * A nullptr blender signifies the default SrcOver behavior. 489 * 490 * @return the SkBlender assigned to this paint, otherwise nullptr 491 */ 492 sk_sp<SkBlender> refBlender() const; 493 494 /** Sets the current blender, increasing its refcnt, and if a blender is already 495 * present, decreasing that object's refcnt. 496 * 497 * A nullptr blender signifies the default SrcOver behavior. 498 * 499 * For convenience, you can call setBlendMode() if the blend effect can be expressed 500 * as one of those values. 501 */ 502 void setBlender(sk_sp<SkBlender> blender); 503 504 /** Returns SkPathEffect if set, or nullptr. 505 Does not alter SkPathEffect SkRefCnt. 506 507 @return SkPathEffect if previously set, nullptr otherwise 508 */ getPathEffect()509 SkPathEffect* getPathEffect() const { return fPathEffect.get(); } 510 511 /** Returns SkPathEffect if set, or nullptr. 512 Increases SkPathEffect SkRefCnt by one. 513 514 @return SkPathEffect if previously set, nullptr otherwise 515 516 example: https://fiddle.skia.org/c/@Paint_refPathEffect 517 */ 518 sk_sp<SkPathEffect> refPathEffect() const; 519 520 /** Sets SkPathEffect to pathEffect, decreasing SkRefCnt of the previous 521 SkPathEffect. Pass nullptr to leave the path geometry unaltered. 522 523 Increments pathEffect SkRefCnt by one. 524 525 @param pathEffect replace SkPath with a modification when drawn 526 527 example: https://fiddle.skia.org/c/@Mask_Filter_Methods 528 example: https://fiddle.skia.org/c/@Paint_setPathEffect 529 */ 530 void setPathEffect(sk_sp<SkPathEffect> pathEffect); 531 532 /** Returns SkMaskFilter if set, or nullptr. 533 Does not alter SkMaskFilter SkRefCnt. 534 535 @return SkMaskFilter if previously set, nullptr otherwise 536 */ getMaskFilter()537 SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); } 538 539 /** Returns SkMaskFilter if set, or nullptr. 540 541 Increases SkMaskFilter SkRefCnt by one. 542 543 @return SkMaskFilter if previously set, nullptr otherwise 544 545 example: https://fiddle.skia.org/c/@Paint_refMaskFilter 546 */ 547 sk_sp<SkMaskFilter> refMaskFilter() const; 548 549 /** Sets SkMaskFilter to maskFilter, decreasing SkRefCnt of the previous 550 SkMaskFilter. Pass nullptr to clear SkMaskFilter and leave SkMaskFilter effect on 551 mask alpha unaltered. 552 553 Increments maskFilter SkRefCnt by one. 554 555 @param maskFilter modifies clipping mask generated from drawn geometry 556 557 example: https://fiddle.skia.org/c/@Paint_setMaskFilter 558 example: https://fiddle.skia.org/c/@Typeface_Methods 559 */ 560 void setMaskFilter(sk_sp<SkMaskFilter> maskFilter); 561 562 /** Returns SkImageFilter if set, or nullptr. 563 Does not alter SkImageFilter SkRefCnt. 564 565 @return SkImageFilter if previously set, nullptr otherwise 566 */ getImageFilter()567 SkImageFilter* getImageFilter() const { return fImageFilter.get(); } 568 569 /** Returns SkImageFilter if set, or nullptr. 570 Increases SkImageFilter SkRefCnt by one. 571 572 @return SkImageFilter if previously set, nullptr otherwise 573 574 example: https://fiddle.skia.org/c/@Paint_refImageFilter 575 */ 576 sk_sp<SkImageFilter> refImageFilter() const; 577 578 /** Sets SkImageFilter to imageFilter, decreasing SkRefCnt of the previous 579 SkImageFilter. Pass nullptr to clear SkImageFilter, and remove SkImageFilter effect 580 on drawing. 581 582 Increments imageFilter SkRefCnt by one. 583 584 @param imageFilter how SkImage is sampled when transformed 585 586 example: https://fiddle.skia.org/c/@Paint_setImageFilter 587 */ 588 void setImageFilter(sk_sp<SkImageFilter> imageFilter); 589 590 /** Returns true if SkPaint prevents all drawing; 591 otherwise, the SkPaint may or may not allow drawing. 592 593 Returns true if, for example, SkBlendMode combined with alpha computes a 594 new alpha of zero. 595 596 @return true if SkPaint prevents all drawing 597 598 example: https://fiddle.skia.org/c/@Paint_nothingToDraw 599 */ 600 bool nothingToDraw() const; 601 602 /** (to be made private) 603 Returns true if SkPaint does not include elements requiring extensive computation 604 to compute device bounds of drawn geometry. For instance, SkPaint with SkPathEffect 605 always returns false. 606 607 @return true if SkPaint allows for fast computation of bounds 608 */ 609 bool canComputeFastBounds() const; 610 611 /** (to be made private) 612 Only call this if canComputeFastBounds() returned true. This takes a 613 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic 614 effects in the paint (e.g. stroking). If needed, it uses the storage 615 parameter. It returns the adjusted bounds that can then be used 616 for SkCanvas::quickReject tests. 617 618 The returned SkRect will either be orig or storage, thus the caller 619 should not rely on storage being set to the result, but should always 620 use the returned value. It is legal for orig and storage to be the same 621 SkRect. 622 For example: 623 if (!path.isInverseFillType() && paint.canComputeFastBounds()) { 624 SkRect storage; 625 if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) { 626 return; // do not draw the path 627 } 628 } 629 // draw the path 630 631 @param orig geometry modified by SkPaint when drawn 632 @param storage computed bounds of geometry; may not be nullptr 633 @return fast computed bounds 634 */ 635 const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const; 636 637 /** (to be made private) 638 639 @param orig geometry modified by SkPaint when drawn 640 @param storage computed bounds of geometry 641 @return fast computed bounds 642 */ computeFastStrokeBounds(const SkRect & orig,SkRect * storage)643 const SkRect& computeFastStrokeBounds(const SkRect& orig, 644 SkRect* storage) const { 645 return this->doComputeFastBounds(orig, storage, kStroke_Style); 646 } 647 648 /** (to be made private) 649 Computes the bounds, overriding the SkPaint SkPaint::Style. This can be used to 650 account for additional width required by stroking orig, without 651 altering SkPaint::Style set to fill. 652 653 @param orig geometry modified by SkPaint when drawn 654 @param storage computed bounds of geometry 655 @param style overrides SkPaint::Style 656 @return fast computed bounds 657 */ 658 const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage, 659 Style style) const; 660 661 using sk_is_trivially_relocatable = std::true_type; 662 663 private: 664 sk_sp<SkPathEffect> fPathEffect; 665 sk_sp<SkShader> fShader; 666 sk_sp<SkMaskFilter> fMaskFilter; 667 sk_sp<SkColorFilter> fColorFilter; 668 sk_sp<SkImageFilter> fImageFilter; 669 sk_sp<SkBlender> fBlender; 670 671 SkColor4f fColor4f; 672 SkScalar fWidth; 673 SkScalar fMiterLimit; 674 union { 675 struct { 676 unsigned fAntiAlias : 1; 677 unsigned fDither : 1; 678 unsigned fCapType : 2; 679 unsigned fJoinType : 2; 680 unsigned fStyle : 2; 681 unsigned fPadding : 24; // 24 == 32 -1-1-2-2-2 682 } fBitfields; 683 uint32_t fBitfieldsUInt; 684 }; 685 686 static_assert(::sk_is_trivially_relocatable<decltype(fPathEffect)>::value); 687 static_assert(::sk_is_trivially_relocatable<decltype(fShader)>::value); 688 static_assert(::sk_is_trivially_relocatable<decltype(fMaskFilter)>::value); 689 static_assert(::sk_is_trivially_relocatable<decltype(fColorFilter)>::value); 690 static_assert(::sk_is_trivially_relocatable<decltype(fImageFilter)>::value); 691 static_assert(::sk_is_trivially_relocatable<decltype(fBlender)>::value); 692 static_assert(::sk_is_trivially_relocatable<decltype(fColor4f)>::value); 693 static_assert(::sk_is_trivially_relocatable<decltype(fBitfields)>::value); 694 695 friend class SkPaintPriv; 696 }; 697 698 #endif 699