• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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