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