• 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