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
17class SkColorFilter;
18class SkColorSpace;
19struct SkRect;
20class SkImageFilter;
21class SkMaskFilter;
22class SkPath;
23class SkPathEffect;
24class 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*/
36class SK_API SkPaint {
37public:
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 /** Retrieves alpha and RGB, unpremultiplied, packed into 32 bits.
239 Use helpers SkColorGetA(), SkColorGetR(), SkColorGetG(), and SkColorGetB() to extract
240 a color component.
241
242 @return unpremultiplied ARGB
243 */
244 SkColor getColor() const { return fColor4f.toSkColor(); }
245
246 /** Retrieves alpha and RGB, unpremultiplied, as four floating point values. RGB are
247 are extended sRGB values (sRGB gamut, and encoded with the sRGB transfer function).
248
249 @return unpremultiplied RGBA
250 */
251 SkColor4f getColor4f() const { return fColor4f; }
252
253 /** Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
254 unpremultiplied, packing 8-bit components for alpha, red, blue, and green.
255
256 @param color unpremultiplied ARGB
257
258 example: https://fiddle.skia.org/c/@Paint_setColor
259 */
260 void setColor(SkColor color);
261
262 /** Sets alpha and RGB used when stroking and filling. The color is four floating
263 point values, unpremultiplied. The color values are interpreted as being in
264 the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
265 sRGB color space.
266
267 @param color unpremultiplied RGBA
268 @param colorSpace SkColorSpace describing the encoding of color
269 */
270 void setColor(const SkColor4f& color, SkColorSpace* colorSpace = nullptr);
271
272 void setColor4f(const SkColor4f& color, SkColorSpace* colorSpace = nullptr) {
273 this->setColor(color, colorSpace);
274 }
275
276 /** Retrieves alpha from the color used when stroking and filling.
277
278 @return alpha ranging from zero, fully transparent, to 255, fully opaque
279 */
280 float getAlphaf() const { return fColor4f.fA; }
281
282 // Helper that scales the alpha by 255.
283 uint8_t getAlpha() const { return sk_float_round2int(this->getAlphaf() * 255); }
284
285 /** Replaces alpha, leaving RGB
286 unchanged. An out of range value triggers an assert in the debug
287 build. a is a value from 0.0 to 1.0.
288 a set to zero makes color fully transparent; a set to 1.0 makes color
289 fully opaque.
290
291 @param a alpha component of color
292 */
293 void setAlphaf(float a);
294
295 // Helper that accepts an int between 0 and 255, and divides it by 255.0
296 void setAlpha(U8CPU a) {
297 this->setAlphaf(a * (1.0f / 255));
298 }
299
300 /** Sets color used when drawing solid fills. The color components range from 0 to 255.
301 The color is unpremultiplied; alpha sets the transparency independent of RGB.
302
303 @param a amount of alpha, from fully transparent (0) to fully opaque (255)
304 @param r amount of red, from no red (0) to full red (255)
305 @param g amount of green, from no green (0) to full green (255)
306 @param b amount of blue, from no blue (0) to full blue (255)
307
308 example: https://fiddle.skia.org/c/@Paint_setARGB
309 */
310 void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
311
312 /** Returns the thickness of the pen used by SkPaint to
313 outline the shape.
314
315 @return zero for hairline, greater than zero for pen thickness
316 */
317 SkScalar getStrokeWidth() const { return fWidth; }
318
319 /** Sets the thickness of the pen used by the paint to
320 outline the shape.
321 Has no effect if width is less than zero.
322
323 @param width zero thickness for hairline; greater than zero for pen thickness
324
325 example: https://fiddle.skia.org/c/@Miter_Limit
326 example: https://fiddle.skia.org/c/@Paint_setStrokeWidth
327 */
328 void setStrokeWidth(SkScalar width);
329
330 /** Returns the limit at which a sharp corner is drawn beveled.
331
332 @return zero and greater miter limit
333 */
334 SkScalar getStrokeMiter() const { return fMiterLimit; }
335
336 /** Sets the limit at which a sharp corner is drawn beveled.
337 Valid values are zero and greater.
338 Has no effect if miter is less than zero.
339
340 @param miter zero and greater miter limit
341
342 example: https://fiddle.skia.org/c/@Paint_setStrokeMiter
343 */
344 void setStrokeMiter(SkScalar miter);
345
346 /** \enum SkPaint::Cap
347 Cap draws at the beginning and end of an open path contour.
348 */
349 enum Cap {
350 kButt_Cap, //!< no stroke extension
351 kRound_Cap, //!< adds circle
352 kSquare_Cap, //!< adds square
353 kLast_Cap = kSquare_Cap, //!< largest Cap value
354 kDefault_Cap = kButt_Cap, //!< equivalent to kButt_Cap
355 };
356
357 /** May be used to verify that SkPaint::Cap is a legal value.
358 */
359 static constexpr int kCapCount = kLast_Cap + 1;
360
361 /** \enum SkPaint::Join
362 Join specifies how corners are drawn when a shape is stroked. Join
363 affects the four corners of a stroked rectangle, and the connected segments in a
364 stroked path.
365
366 Choose miter join to draw sharp corners. Choose round join to draw a circle with a
367 radius equal to the stroke width on top of the corner. Choose bevel join to minimally
368 connect the thick strokes.
369
370 The fill path constructed to describe the stroked path respects the join setting but may
371 not contain the actual join. For instance, a fill path constructed with round joins does
372 not necessarily include circles at each connected segment.
373 */
374 enum Join : uint8_t {
375 kMiter_Join, //!< extends to miter limit
376 kRound_Join, //!< adds circle
377 kBevel_Join, //!< connects outside edges
378 kLast_Join = kBevel_Join, //!< equivalent to the largest value for Join
379 kDefault_Join = kMiter_Join, //!< equivalent to kMiter_Join
380 };
381
382 /** May be used to verify that SkPaint::Join is a legal value.
383 */
384 static constexpr int kJoinCount = kLast_Join + 1;
385
386 /** Returns the geometry drawn at the beginning and end of strokes.
387 */
388 Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
389
390 /** Sets the geometry drawn at the beginning and end of strokes.
391
392 example: https://fiddle.skia.org/c/@Paint_setStrokeCap_a
393 example: https://fiddle.skia.org/c/@Paint_setStrokeCap_b
394 */
395 void setStrokeCap(Cap cap);
396
397 /** Returns the geometry drawn at the corners of strokes.
398 */
399 Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
400
401 /** Sets the geometry drawn at the corners of strokes.
402
403 example: https://fiddle.skia.org/c/@Paint_setStrokeJoin
404 */
405 void setStrokeJoin(Join join);
406
407 /** Returns the filled equivalent of the stroked path.
408
409 @param src SkPath read to create a filled version
410 @param dst resulting SkPath; may be the same as src, but may not be nullptr
411 @param cullRect optional limit passed to SkPathEffect
412 @param resScale if > 1, increase precision, else if (0 < resScale < 1) reduce precision
413 to favor speed and size
414 @return true if the path represents style fill, or false if it represents hairline
415 */
416 bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
417 SkScalar resScale = 1) const;
418
419 /** Returns the filled equivalent of the stroked path.
420
421 Replaces dst with the src path modified by SkPathEffect and style stroke.
422 SkPathEffect, if any, is not culled. stroke width is created with default precision.
423
424 @param src SkPath read to create a filled version
425 @param dst resulting SkPath dst may be the same as src, but may not be nullptr
426 @return true if the path represents style fill, or false if it represents hairline
427 */
428 bool getFillPath(const SkPath& src, SkPath* dst) const {
429 return this->getFillPath(src, dst, nullptr, 1);
430 }
431
432 /** Returns optional colors used when filling a path, such as a gradient.
433
434 Does not alter SkShader SkRefCnt.
435
436 @return SkShader if previously set, nullptr otherwise
437 */
438 SkShader* getShader() const { return fShader.get(); }
439
440 /** Returns optional colors used when filling a path, such as a gradient.
441
442 Increases SkShader SkRefCnt by one.
443
444 @return SkShader if previously set, nullptr otherwise
445
446 example: https://fiddle.skia.org/c/@Paint_refShader
447 */
448 sk_sp<SkShader> refShader() const;
449
450 /** Sets optional colors used when filling a path, such as a gradient.
451
452 Sets SkShader to shader, decreasing SkRefCnt of the previous SkShader.
453 Increments shader SkRefCnt by one.
454
455 @param shader how geometry is filled with color; if nullptr, color is used instead
456
457 example: https://fiddle.skia.org/c/@Color_Filter_Methods
458 example: https://fiddle.skia.org/c/@Paint_setShader
459 */
460 void setShader(sk_sp<SkShader> shader);
461
462 /** Returns SkColorFilter if set, or nullptr.
463 Does not alter SkColorFilter SkRefCnt.
464
465 @return SkColorFilter if previously set, nullptr otherwise
466 */
467 SkColorFilter* getColorFilter() const { return fColorFilter.get(); }
468
469 /** Returns SkColorFilter if set, or nullptr.
470 Increases SkColorFilter SkRefCnt by one.
471
472 @return SkColorFilter if set, or nullptr
473
474 example: https://fiddle.skia.org/c/@Paint_refColorFilter
475 */
476 sk_sp<SkColorFilter> refColorFilter() const;
477
478 /** Sets SkColorFilter to filter, decreasing SkRefCnt of the previous
479 SkColorFilter. Pass nullptr to clear SkColorFilter.
480
481 Increments filter SkRefCnt by one.
482
483 @param colorFilter SkColorFilter to apply to subsequent draw
484
485 example: https://fiddle.skia.org/c/@Blend_Mode_Methods
486 example: https://fiddle.skia.org/c/@Paint_setColorFilter
487 */
488 void setColorFilter(sk_sp<SkColorFilter> colorFilter);
489
490 /** Returns SkBlendMode.
491 By default, returns SkBlendMode::kSrcOver.
492
493 @return mode used to combine source color with destination color
494 */
495 SkBlendMode getBlendMode() const { return (SkBlendMode)fBitfields.fBlendMode; }
496
497 /** Returns true if SkBlendMode is SkBlendMode::kSrcOver, the default.
498
499 @return true if SkBlendMode is SkBlendMode::kSrcOver
500 */
501 bool isSrcOver() const { return (SkBlendMode)fBitfields.fBlendMode == SkBlendMode::kSrcOver; }
502
503 /** Sets SkBlendMode to mode.
504 Does not check for valid input.
505
506 @param mode SkBlendMode used to combine source color and destination
507 */
508 void setBlendMode(SkBlendMode mode) { fBitfields.fBlendMode = (unsigned)mode; }
509
510 /** Returns SkPathEffect if set, or nullptr.
511 Does not alter SkPathEffect SkRefCnt.
512
513 @return SkPathEffect if previously set, nullptr otherwise
514 */
515 SkPathEffect* getPathEffect() const { return fPathEffect.get(); }
516
517 /** Returns SkPathEffect if set, or nullptr.
518 Increases SkPathEffect SkRefCnt by one.
519
520 @return SkPathEffect if previously set, nullptr otherwise
521
522 example: https://fiddle.skia.org/c/@Paint_refPathEffect
523 */
524 sk_sp<SkPathEffect> refPathEffect() const;
525
526 /** Sets SkPathEffect to pathEffect, decreasing SkRefCnt of the previous
527 SkPathEffect. Pass nullptr to leave the path geometry unaltered.
528
529 Increments pathEffect SkRefCnt by one.
530
531 @param pathEffect replace SkPath with a modification when drawn
532
533 example: https://fiddle.skia.org/c/@Mask_Filter_Methods
534 example: https://fiddle.skia.org/c/@Paint_setPathEffect
535 */
536 void setPathEffect(sk_sp<SkPathEffect> pathEffect);
537
538 /** Returns SkMaskFilter if set, or nullptr.
539 Does not alter SkMaskFilter SkRefCnt.
540
541 @return SkMaskFilter if previously set, nullptr otherwise
542 */
543 SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }
544
545 /** Returns SkMaskFilter if set, or nullptr.
546
547 Increases SkMaskFilter SkRefCnt by one.
548
549 @return SkMaskFilter if previously set, nullptr otherwise
550
551 example: https://fiddle.skia.org/c/@Paint_refMaskFilter
552 */
553 sk_sp<SkMaskFilter> refMaskFilter() const;
554
555 /** Sets SkMaskFilter to maskFilter, decreasing SkRefCnt of the previous
556 SkMaskFilter. Pass nullptr to clear SkMaskFilter and leave SkMaskFilter effect on
557 mask alpha unaltered.
558
559 Increments maskFilter SkRefCnt by one.
560
561 @param maskFilter modifies clipping mask generated from drawn geometry
562
563 example: https://fiddle.skia.org/c/@Paint_setMaskFilter
564 example: https://fiddle.skia.org/c/@Typeface_Methods
565 */
566 void setMaskFilter(sk_sp<SkMaskFilter> maskFilter);
567
568 /** Returns SkImageFilter if set, or nullptr.
569 Does not alter SkImageFilter SkRefCnt.
570
571 @return SkImageFilter if previously set, nullptr otherwise
572 */
573 SkImageFilter* getImageFilter() const { return fImageFilter.get(); }
574
575 /** Returns SkImageFilter if set, or nullptr.
576 Increases SkImageFilter SkRefCnt by one.
577
578 @return SkImageFilter if previously set, nullptr otherwise
579
580 example: https://fiddle.skia.org/c/@Paint_refImageFilter
581 */
582 sk_sp<SkImageFilter> refImageFilter() const;
583
584 /** Sets SkImageFilter to imageFilter, decreasing SkRefCnt of the previous
585 SkImageFilter. Pass nullptr to clear SkImageFilter, and remove SkImageFilter effect
586 on drawing.
587
588 Increments imageFilter SkRefCnt by one.
589
590 @param imageFilter how SkImage is sampled when transformed
591
592 example: https://fiddle.skia.org/c/@Draw_Looper_Methods
593 example: https://fiddle.skia.org/c/@Paint_setImageFilter
594 */
595 void setImageFilter(sk_sp<SkImageFilter> imageFilter);
596
597 /** Returns true if SkPaint prevents all drawing;
598 otherwise, the SkPaint may or may not allow drawing.
599
600 Returns true if, for example, SkBlendMode combined with alpha computes a
601 new alpha of zero.
602
603 @return true if SkPaint prevents all drawing
604
605 example: https://fiddle.skia.org/c/@Paint_nothingToDraw
606 */
607 bool nothingToDraw() const;
608
609 /** (to be made private)
610 Returns true if SkPaint does not include elements requiring extensive computation
611 to compute SkBaseDevice bounds of drawn geometry. For instance, SkPaint with SkPathEffect
612 always returns false.
613
614 @return true if SkPaint allows for fast computation of bounds
615 */
616 bool canComputeFastBounds() const;
617
618 /** (to be made private)
619 Only call this if canComputeFastBounds() returned true. This takes a
620 raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
621 effects in the paint (e.g. stroking). If needed, it uses the storage
622 parameter. It returns the adjusted bounds that can then be used
623 for SkCanvas::quickReject tests.
624
625 The returned SkRect will either be orig or storage, thus the caller
626 should not rely on storage being set to the result, but should always
627 use the returned value. It is legal for orig and storage to be the same
628 SkRect.
629 For example:
630 if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
631 SkRect storage;
632 if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) {
633 return; // do not draw the path
634 }
635 }
636 // draw the path
637
638 @param orig geometry modified by SkPaint when drawn
639 @param storage computed bounds of geometry; may not be nullptr
640 @return fast computed bounds
641 */
642 const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
643 // Things like stroking, etc... will do math on the bounds rect, assuming that it's sorted.
644 SkASSERT(orig.isSorted());
645 SkPaint::Style style = this->getStyle();
646 // ultra fast-case: filling with no effects that affect geometry
647 if (kFill_Style == style) {
648 uintptr_t effects = 0;
649 effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
650 effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
651 effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
652 if (!effects) {
653 return orig;
654 }
655 }
656
657 return this->doComputeFastBounds(orig, storage, style);
658 }
659
660 /** (to be made private)
661
662 @param orig geometry modified by SkPaint when drawn
663 @param storage computed bounds of geometry
664 @return fast computed bounds
665 */
666 const SkRect& computeFastStrokeBounds(const SkRect& orig,
667 SkRect* storage) const {
668 return this->doComputeFastBounds(orig, storage, kStroke_Style);
669 }
670
671 /** (to be made private)
672 Computes the bounds, overriding the SkPaint SkPaint::Style. This can be used to
673 account for additional width required by stroking orig, without
674 altering SkPaint::Style set to fill.
675
676 @param orig geometry modified by SkPaint when drawn
677 @param storage computed bounds of geometry
678 @param style overrides SkPaint::Style
679 @return fast computed bounds
680 */
681 const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
682 Style style) const;
683
684private:
685 sk_sp<SkPathEffect> fPathEffect;
686 sk_sp<SkShader> fShader;
687 sk_sp<SkMaskFilter> fMaskFilter;
688 sk_sp<SkColorFilter> fColorFilter;
689 sk_sp<SkImageFilter> fImageFilter;
690
691 SkColor4f fColor4f;
692 SkScalar fWidth;
693 SkScalar fMiterLimit;
694 union {
695 struct {
696 unsigned fAntiAlias : 1;
697 unsigned fDither : 1;
698 unsigned fCapType : 2;
699 unsigned fJoinType : 2;
700 unsigned fStyle : 2;
701 unsigned fFilterQuality : 2;
702 unsigned fBlendMode : 8; // only need 5-6?
703 unsigned fPadding : 14; // 14==32-1-1-2-2-2-2-8
704 } fBitfields;
705 uint32_t fBitfieldsUInt;
706 };
707};
708
709#endif
710