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