• 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/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