Coverage Report

Created: 2021-08-22 09:07

/src/skia/include/core/SkPaint.h
Line
Count
Source (jump to first uncovered line)
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/SkRefCnt.h"
14
#include "include/private/SkTOptional.h"
15
#include "include/private/SkTo.h"
16
17
class SkBlender;
18
class SkColorFilter;
19
class SkColorSpace;
20
struct SkRect;
21
class SkImageFilter;
22
class SkMaskFilter;
23
class SkMatrix;
24
class SkPath;
25
class SkPathEffect;
26
class SkShader;
27
28
/** \class SkPaint
29
    SkPaint controls options applied when drawing. SkPaint collects all
30
    options outside of the SkCanvas clip and SkCanvas matrix.
31
32
    Various options apply to strokes and fills, and images.
33
34
    SkPaint collects effects and filters that describe single-pass and multiple-pass
35
    algorithms that alter the drawing geometry, color, and transparency. For instance,
36
    SkPaint does not directly implement dashing or blur, but contains the objects that do so.
37
*/
38
class SK_API SkPaint {
39
public:
40
41
    /** Constructs SkPaint with default values.
42
43
        @return  default initialized SkPaint
44
45
        example: https://fiddle.skia.org/c/@Paint_empty_constructor
46
    */
47
    SkPaint();
48
49
    /** Constructs SkPaint with default values and the given color.
50
51
        Sets alpha and RGB used when stroking and filling. The color is four floating
52
        point values, unpremultiplied. The color values are interpreted as being in
53
        the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
54
        sRGB color space.
55
56
        @param color       unpremultiplied RGBA
57
        @param colorSpace  SkColorSpace describing the encoding of color
58
        @return            SkPaint with the given color
59
    */
60
    explicit SkPaint(const SkColor4f& color, SkColorSpace* colorSpace = nullptr);
61
62
    /** Makes a shallow copy of SkPaint. SkPathEffect, SkShader,
63
        SkMaskFilter, SkColorFilter, and SkImageFilter are shared
64
        between the original paint and the copy. Objects containing SkRefCnt increment
65
        their references by one.
66
67
        The referenced objects SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
68
        and SkImageFilter cannot be modified after they are created.
69
        This prevents objects with SkRefCnt from being modified once SkPaint refers to them.
70
71
        @param paint  original to copy
72
        @return       shallow copy of paint
73
74
        example: https://fiddle.skia.org/c/@Paint_copy_const_SkPaint
75
    */
76
    SkPaint(const SkPaint& paint);
77
78
    /** Implements a move constructor to avoid increasing the reference counts
79
        of objects referenced by the paint.
80
81
        After the call, paint is undefined, and can be safely destructed.
82
83
        @param paint  original to move
84
        @return       content of paint
85
86
        example: https://fiddle.skia.org/c/@Paint_move_SkPaint
87
    */
88
    SkPaint(SkPaint&& paint);
89
90
    /** Decreases SkPaint SkRefCnt of owned objects: SkPathEffect, SkShader,
91
        SkMaskFilter, SkColorFilter, and SkImageFilter. If the
92
        objects containing SkRefCnt go to zero, they are deleted.
93
    */
94
    ~SkPaint();
95
96
    /** Makes a shallow copy of SkPaint. SkPathEffect, SkShader,
97
        SkMaskFilter, SkColorFilter, and SkImageFilter are shared
98
        between the original paint and the copy. Objects containing SkRefCnt in the
99
        prior destination are decreased by one, and the referenced objects are deleted if the
100
        resulting count is zero. Objects containing SkRefCnt in the parameter paint
101
        are increased by one. paint is unmodified.
102
103
        @param paint  original to copy
104
        @return       content of paint
105
106
        example: https://fiddle.skia.org/c/@Paint_copy_operator
107
    */
108
    SkPaint& operator=(const SkPaint& paint);
109
110
    /** Moves the paint to avoid increasing the reference counts
111
        of objects referenced by the paint parameter. Objects containing SkRefCnt in the
112
        prior destination are decreased by one; those objects are deleted if the resulting count
113
        is zero.
114
115
        After the call, paint is undefined, and can be safely destructed.
116
117
        @param paint  original to move
118
        @return       content of paint
119
120
        example: https://fiddle.skia.org/c/@Paint_move_operator
121
    */
122
    SkPaint& operator=(SkPaint&& paint);
123
124
    /** Compares a and b, and returns true if a and b are equivalent. May return false
125
        if SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
126
        or SkImageFilter have identical contents but different pointers.
127
128
        @param a  SkPaint to compare
129
        @param b  SkPaint to compare
130
        @return   true if SkPaint pair are equivalent
131
    */
132
    SK_API friend bool operator==(const SkPaint& a, const SkPaint& b);
133
134
    /** Compares a and b, and returns true if a and b are not equivalent. May return true
135
        if SkPathEffect, SkShader, SkMaskFilter, SkColorFilter,
136
        or SkImageFilter have identical contents but different pointers.
137
138
        @param a  SkPaint to compare
139
        @param b  SkPaint to compare
140
        @return   true if SkPaint pair are not equivalent
141
    */
142
20.8k
    friend bool operator!=(const SkPaint& a, const SkPaint& b) {
143
20.8k
        return !(a == b);
144
20.8k
    }
145
146
    /** Sets all SkPaint contents to their initial values. This is equivalent to replacing
147
        SkPaint with the result of SkPaint().
148
149
        example: https://fiddle.skia.org/c/@Paint_reset
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
    */
156
512k
    bool isAntiAlias() const {
157
512k
        return SkToBool(fBitfields.fAntiAlias);
158
512k
    }
159
160
    /** Requests, but does not require, that edge pixels draw opaque or with
161
        partial transparency.
162
        @param aa  setting for antialiasing
163
    */
164
1.13M
    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
    */
169
2.16M
    bool isDither() const {
170
2.16M
        return SkToBool(fBitfields.fDither);
171
2.16M
    }
172
173
    /** Requests, but does not require, to distribute color error.
174
        @param dither  setting for ditering
175
    */
176
670k
    void setDither(bool dither) { fBitfields.fDither = static_cast<unsigned>(dither); }
177
178
    /** \enum SkPaint::Style
179
        Set Style to fill, stroke, or both fill and stroke geometry.
180
        The stroke and fill
181
        share all paint attributes; for instance, they are drawn with the same color.
182
183
        Use kStrokeAndFill_Style to avoid hitting the same pixels twice with a stroke draw and
184
        a fill draw.
185
    */
186
    enum Style : uint8_t {
187
        kFill_Style,          //!< set to fill geometry
188
        kStroke_Style,        //!< set to stroke geometry
189
        kStrokeAndFill_Style, //!< sets to stroke and fill geometry
190
    };
191
192
    /** May be used to verify that SkPaint::Style is a legal value.
193
    */
194
    static constexpr int kStyleCount = kStrokeAndFill_Style + 1;
195
196
    /** Returns whether the geometry is filled, stroked, or filled and stroked.
197
    */
198
22.5M
    Style getStyle() const { return (Style)fBitfields.fStyle; }
199
200
    /** Sets whether the geometry is filled, stroked, or filled and stroked.
201
        Has no effect if style is not a legal SkPaint::Style value.
202
203
        example: https://fiddle.skia.org/c/@Paint_setStyle
204
        example: https://fiddle.skia.org/c/@Stroke_Width
205
    */
206
    void setStyle(Style style);
207
208
    /**
209
     *  Set paint's style to kStroke if true, or kFill if false.
210
     */
211
    void setStroke(bool);
212
213
    /** Retrieves alpha and RGB, unpremultiplied, packed into 32 bits.
214
        Use helpers SkColorGetA(), SkColorGetR(), SkColorGetG(), and SkColorGetB() to extract
215
        a color component.
216
217
        @return  unpremultiplied ARGB
218
    */
219
10.5M
    SkColor getColor() const { return fColor4f.toSkColor(); }
220
221
    /** Retrieves alpha and RGB, unpremultiplied, as four floating point values. RGB are
222
        extended sRGB values (sRGB gamut, and encoded with the sRGB transfer function).
223
224
        @return  unpremultiplied RGBA
225
    */
226
860k
    SkColor4f getColor4f() const { return fColor4f; }
227
228
    /** Sets alpha and RGB used when stroking and filling. The color is a 32-bit value,
229
        unpremultiplied, packing 8-bit components for alpha, red, blue, and green.
230
231
        @param color  unpremultiplied ARGB
232
233
        example: https://fiddle.skia.org/c/@Paint_setColor
234
    */
235
    void setColor(SkColor color);
236
237
    /** Sets alpha and RGB used when stroking and filling. The color is four floating
238
        point values, unpremultiplied. The color values are interpreted as being in
239
        the colorSpace. If colorSpace is nullptr, then color is assumed to be in the
240
        sRGB color space.
241
242
        @param color       unpremultiplied RGBA
243
        @param colorSpace  SkColorSpace describing the encoding of color
244
    */
245
    void setColor(const SkColor4f& color, SkColorSpace* colorSpace = nullptr);
246
247
15.9k
    void setColor4f(const SkColor4f& color, SkColorSpace* colorSpace = nullptr) {
248
15.9k
        this->setColor(color, colorSpace);
249
15.9k
    }
250
251
    /** Retrieves alpha from the color used when stroking and filling.
252
253
        @return  alpha ranging from zero, fully transparent, to 255, fully opaque
254
    */
255
3.01M
    float getAlphaf() const { return fColor4f.fA; }
256
257
    // Helper that scales the alpha by 255.
258
2.77M
    uint8_t getAlpha() const { return sk_float_round2int(this->getAlphaf() * 255); }
259
260
    /** Replaces alpha, leaving RGB
261
        unchanged. An out of range value triggers an assert in the debug
262
        build. a is a value from 0.0 to 1.0.
263
        a set to zero makes color fully transparent; a set to 1.0 makes color
264
        fully opaque.
265
266
        @param a  alpha component of color
267
    */
268
    void setAlphaf(float a);
269
270
    // Helper that accepts an int between 0 and 255, and divides it by 255.0
271
819k
    void setAlpha(U8CPU a) {
272
819k
        this->setAlphaf(a * (1.0f / 255));
273
819k
    }
274
275
    /** Sets color used when drawing solid fills. The color components range from 0 to 255.
276
        The color is unpremultiplied; alpha sets the transparency independent of RGB.
277
278
        @param a  amount of alpha, from fully transparent (0) to fully opaque (255)
279
        @param r  amount of red, from no red (0) to full red (255)
280
        @param g  amount of green, from no green (0) to full green (255)
281
        @param b  amount of blue, from no blue (0) to full blue (255)
282
283
        example: https://fiddle.skia.org/c/@Paint_setARGB
284
    */
285
    void setARGB(U8CPU a, U8CPU r, U8CPU g, U8CPU b);
286
287
    /** Returns the thickness of the pen used by SkPaint to
288
        outline the shape.
289
290
        @return  zero for hairline, greater than zero for pen thickness
291
    */
292
10.7M
    SkScalar getStrokeWidth() const { return fWidth; }
293
294
    /** Sets the thickness of the pen used by the paint to outline the shape.
295
        A stroke-width of zero is treated as "hairline" width. Hairlines are always exactly one
296
        pixel wide in device space (their thickness does not change as the canvas is scaled).
297
        Negative stroke-widths are invalid; setting a negative width will have no effect.
298
299
        @param width  zero thickness for hairline; greater than zero for pen thickness
300
301
        example: https://fiddle.skia.org/c/@Miter_Limit
302
        example: https://fiddle.skia.org/c/@Paint_setStrokeWidth
303
    */
304
    void setStrokeWidth(SkScalar width);
305
306
    /** Returns the limit at which a sharp corner is drawn beveled.
307
308
        @return  zero and greater miter limit
309
    */
310
628k
    SkScalar getStrokeMiter() const { return fMiterLimit; }
311
312
    /** Sets the limit at which a sharp corner is drawn beveled.
313
        Valid values are zero and greater.
314
        Has no effect if miter is less than zero.
315
316
        @param miter  zero and greater miter limit
317
318
        example: https://fiddle.skia.org/c/@Paint_setStrokeMiter
319
    */
320
    void setStrokeMiter(SkScalar miter);
321
322
    /** \enum SkPaint::Cap
323
        Cap draws at the beginning and end of an open path contour.
324
    */
325
    enum Cap {
326
        kButt_Cap,                  //!< no stroke extension
327
        kRound_Cap,                 //!< adds circle
328
        kSquare_Cap,                //!< adds square
329
        kLast_Cap    = kSquare_Cap, //!< largest Cap value
330
        kDefault_Cap = kButt_Cap,   //!< equivalent to kButt_Cap
331
    };
332
333
    /** May be used to verify that SkPaint::Cap is a legal value.
334
    */
335
    static constexpr int kCapCount = kLast_Cap + 1;
336
337
    /** \enum SkPaint::Join
338
        Join specifies how corners are drawn when a shape is stroked. Join
339
        affects the four corners of a stroked rectangle, and the connected segments in a
340
        stroked path.
341
342
        Choose miter join to draw sharp corners. Choose round join to draw a circle with a
343
        radius equal to the stroke width on top of the corner. Choose bevel join to minimally
344
        connect the thick strokes.
345
346
        The fill path constructed to describe the stroked path respects the join setting but may
347
        not contain the actual join. For instance, a fill path constructed with round joins does
348
        not necessarily include circles at each connected segment.
349
    */
350
    enum Join : uint8_t {
351
        kMiter_Join,                 //!< extends to miter limit
352
        kRound_Join,                 //!< adds circle
353
        kBevel_Join,                 //!< connects outside edges
354
        kLast_Join    = kBevel_Join, //!< equivalent to the largest value for Join
355
        kDefault_Join = kMiter_Join, //!< equivalent to kMiter_Join
356
    };
357
358
    /** May be used to verify that SkPaint::Join is a legal value.
359
    */
360
    static constexpr int kJoinCount = kLast_Join + 1;
361
362
    /** Returns the geometry drawn at the beginning and end of strokes.
363
    */
364
659k
    Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
365
366
    /** Sets the geometry drawn at the beginning and end of strokes.
367
368
        example: https://fiddle.skia.org/c/@Paint_setStrokeCap_a
369
        example: https://fiddle.skia.org/c/@Paint_setStrokeCap_b
370
    */
371
    void setStrokeCap(Cap cap);
372
373
    /** Returns the geometry drawn at the corners of strokes.
374
    */
375
632k
    Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
376
377
    /** Sets the geometry drawn at the corners of strokes.
378
379
        example: https://fiddle.skia.org/c/@Paint_setStrokeJoin
380
    */
381
    void setStrokeJoin(Join join);
382
383
    /** Returns the filled equivalent of the stroked path.
384
385
        @param src       SkPath read to create a filled version
386
        @param dst       resulting SkPath; may be the same as src, but may not be nullptr
387
        @param cullRect  optional limit passed to SkPathEffect
388
        @param resScale  if > 1, increase precision, else if (0 < resScale < 1) reduce precision
389
                         to favor speed and size
390
        @return          true if the path represents style fill, or false if it represents hairline
391
    */
392
    bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
393
                     SkScalar resScale = 1) const;
394
395
    bool getFillPath(const SkPath& src, SkPath* dst, const SkRect* cullRect,
396
                     const SkMatrix& ctm) const;
397
398
    /** Returns the filled equivalent of the stroked path.
399
400
        Replaces dst with the src path modified by SkPathEffect and style stroke.
401
        SkPathEffect, if any, is not culled. stroke width is created with default precision.
402
403
        @param src  SkPath read to create a filled version
404
        @param dst  resulting SkPath dst may be the same as src, but may not be nullptr
405
        @return     true if the path represents style fill, or false if it represents hairline
406
    */
407
2.16k
    bool getFillPath(const SkPath& src, SkPath* dst) const {
408
2.16k
        return this->getFillPath(src, dst, nullptr, 1);
409
2.16k
    }
410
411
    /** Returns optional colors used when filling a path, such as a gradient.
412
413
        Does not alter SkShader SkRefCnt.
414
415
        @return  SkShader if previously set, nullptr otherwise
416
    */
417
11.9M
    SkShader* getShader() const { return fShader.get(); }
418
419
    /** Returns optional colors used when filling a path, such as a gradient.
420
421
        Increases SkShader SkRefCnt by one.
422
423
        @return  SkShader if previously set, nullptr otherwise
424
425
        example: https://fiddle.skia.org/c/@Paint_refShader
426
    */
427
    sk_sp<SkShader> refShader() const;
428
429
    /** Sets optional colors used when filling a path, such as a gradient.
430
431
        Sets SkShader to shader, decreasing SkRefCnt of the previous SkShader.
432
        Increments shader SkRefCnt by one.
433
434
        @param shader  how geometry is filled with color; if nullptr, color is used instead
435
436
        example: https://fiddle.skia.org/c/@Color_Filter_Methods
437
        example: https://fiddle.skia.org/c/@Paint_setShader
438
    */
439
    void setShader(sk_sp<SkShader> shader);
440
441
    /** Returns SkColorFilter if set, or nullptr.
442
        Does not alter SkColorFilter SkRefCnt.
443
444
        @return  SkColorFilter if previously set, nullptr otherwise
445
    */
446
11.3M
    SkColorFilter* getColorFilter() const { return fColorFilter.get(); }
447
448
    /** Returns SkColorFilter if set, or nullptr.
449
        Increases SkColorFilter SkRefCnt by one.
450
451
        @return  SkColorFilter if set, or nullptr
452
453
        example: https://fiddle.skia.org/c/@Paint_refColorFilter
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
        example: https://fiddle.skia.org/c/@Blend_Mode_Methods
465
        example: https://fiddle.skia.org/c/@Paint_setColorFilter
466
    */
467
    void setColorFilter(sk_sp<SkColorFilter> colorFilter);
468
469
    /** If the current blender can be represented as a SkBlendMode enum, this returns that
470
     *  enum in the optional's value(). If it cannot, then the returned optional does not
471
     *  contain a value.
472
     */
473
    skstd::optional<SkBlendMode> asBlendMode() const;
474
475
    /**
476
     *  Queries the blender, and if it can be represented as a SkBlendMode, return that mode,
477
     *  else return the defaultMode provided.
478
     */
479
    SkBlendMode getBlendMode_or(SkBlendMode defaultMode) const;
480
481
    /** Returns true iff the current blender claims to be equivalent to SkBlendMode::kSrcOver.
482
     *
483
     *  Also returns true of the current blender is nullptr.
484
     */
485
    bool isSrcOver() const;
486
487
    /** Helper method for calling setBlender().
488
     *
489
     *  This sets a blender that implements the specified blendmode enum.
490
     */
491
    void setBlendMode(SkBlendMode mode);
492
493
    /** Returns the user-supplied blend function, if one has been set.
494
     *  Does not alter SkBlender's SkRefCnt.
495
     *
496
     *  A nullptr blender signifies the default SrcOver behavior.
497
     *
498
     *  @return  the SkBlender assigned to this paint, otherwise nullptr
499
     */
500
13.9k
    SkBlender* getBlender() const { return fBlender.get(); }
501
502
    /** Returns the user-supplied blend function, if one has been set.
503
     *  Increments the SkBlender's SkRefCnt by one.
504
     *
505
     *  A nullptr blender signifies the default SrcOver behavior.
506
     *
507
     *  @return  the SkBlender assigned to this paint, otherwise nullptr
508
     */
509
    sk_sp<SkBlender> refBlender() const;
510
511
    /** Sets the current blender, increasing its refcnt, and if a blender is already
512
     *  present, decreasing that object's refcnt.
513
     *
514
     *  A nullptr blender signifies the default SrcOver behavior.
515
     *
516
     *  For convenience, you can call setBlendMode() if the blend effect can be expressed
517
     *  as one of those values.
518
     */
519
    void setBlender(sk_sp<SkBlender> blender);
520
521
    /** Returns SkPathEffect if set, or nullptr.
522
        Does not alter SkPathEffect SkRefCnt.
523
524
        @return  SkPathEffect if previously set, nullptr otherwise
525
    */
526
12.6M
    SkPathEffect* getPathEffect() const { return fPathEffect.get(); }
527
528
    /** Returns SkPathEffect if set, or nullptr.
529
        Increases SkPathEffect SkRefCnt by one.
530
531
        @return  SkPathEffect if previously set, nullptr otherwise
532
533
        example: https://fiddle.skia.org/c/@Paint_refPathEffect
534
    */
535
    sk_sp<SkPathEffect> refPathEffect() const;
536
537
    /** Sets SkPathEffect to pathEffect, decreasing SkRefCnt of the previous
538
        SkPathEffect. Pass nullptr to leave the path geometry unaltered.
539
540
        Increments pathEffect SkRefCnt by one.
541
542
        @param pathEffect  replace SkPath with a modification when drawn
543
544
        example: https://fiddle.skia.org/c/@Mask_Filter_Methods
545
        example: https://fiddle.skia.org/c/@Paint_setPathEffect
546
    */
547
    void setPathEffect(sk_sp<SkPathEffect> pathEffect);
548
549
    /** Returns SkMaskFilter if set, or nullptr.
550
        Does not alter SkMaskFilter SkRefCnt.
551
552
        @return  SkMaskFilter if previously set, nullptr otherwise
553
    */
554
12.5M
    SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }
555
556
    /** Returns SkMaskFilter if set, or nullptr.
557
558
        Increases SkMaskFilter SkRefCnt by one.
559
560
        @return  SkMaskFilter if previously set, nullptr otherwise
561
562
        example: https://fiddle.skia.org/c/@Paint_refMaskFilter
563
    */
564
    sk_sp<SkMaskFilter> refMaskFilter() const;
565
566
    /** Sets SkMaskFilter to maskFilter, decreasing SkRefCnt of the previous
567
        SkMaskFilter. Pass nullptr to clear SkMaskFilter and leave SkMaskFilter effect on
568
        mask alpha unaltered.
569
570
        Increments maskFilter SkRefCnt by one.
571
572
        @param maskFilter  modifies clipping mask generated from drawn geometry
573
574
        example: https://fiddle.skia.org/c/@Paint_setMaskFilter
575
        example: https://fiddle.skia.org/c/@Typeface_Methods
576
    */
577
    void setMaskFilter(sk_sp<SkMaskFilter> maskFilter);
578
579
    /** Returns SkImageFilter if set, or nullptr.
580
        Does not alter SkImageFilter SkRefCnt.
581
582
        @return  SkImageFilter if previously set, nullptr otherwise
583
    */
584
3.55M
    SkImageFilter* getImageFilter() const { return fImageFilter.get(); }
585
586
    /** Returns SkImageFilter if set, or nullptr.
587
        Increases SkImageFilter SkRefCnt by one.
588
589
        @return  SkImageFilter if previously set, nullptr otherwise
590
591
        example: https://fiddle.skia.org/c/@Paint_refImageFilter
592
    */
593
    sk_sp<SkImageFilter> refImageFilter() const;
594
595
    /** Sets SkImageFilter to imageFilter, decreasing SkRefCnt of the previous
596
        SkImageFilter. Pass nullptr to clear SkImageFilter, and remove SkImageFilter effect
597
        on drawing.
598
599
        Increments imageFilter SkRefCnt by one.
600
601
        @param imageFilter  how SkImage is sampled when transformed
602
603
        example: https://fiddle.skia.org/c/@Paint_setImageFilter
604
    */
605
    void setImageFilter(sk_sp<SkImageFilter> imageFilter);
606
607
    /** Returns true if SkPaint prevents all drawing;
608
        otherwise, the SkPaint may or may not allow drawing.
609
610
        Returns true if, for example, SkBlendMode combined with alpha computes a
611
        new alpha of zero.
612
613
        @return  true if SkPaint prevents all drawing
614
615
        example: https://fiddle.skia.org/c/@Paint_nothingToDraw
616
    */
617
    bool nothingToDraw() const;
618
619
    /**     (to be made private)
620
        Returns true if SkPaint does not include elements requiring extensive computation
621
        to compute SkBaseDevice bounds of drawn geometry. For instance, SkPaint with SkPathEffect
622
        always returns false.
623
624
        @return  true if SkPaint allows for fast computation of bounds
625
    */
626
    bool canComputeFastBounds() const;
627
628
    /**     (to be made private)
629
        Only call this if canComputeFastBounds() returned true. This takes a
630
        raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
631
        effects in the paint (e.g. stroking). If needed, it uses the storage
632
        parameter. It returns the adjusted bounds that can then be used
633
        for SkCanvas::quickReject tests.
634
635
        The returned SkRect will either be orig or storage, thus the caller
636
        should not rely on storage being set to the result, but should always
637
        use the returned value. It is legal for orig and storage to be the same
638
        SkRect.
639
            For example:
640
            if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
641
                SkRect storage;
642
                if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) {
643
                    return; // do not draw the path
644
                }
645
            }
646
            // draw the path
647
648
        @param orig     geometry modified by SkPaint when drawn
649
        @param storage  computed bounds of geometry; may not be nullptr
650
        @return         fast computed bounds
651
    */
652
1.22M
    const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const {
653
        // Things like stroking, etc... will do math on the bounds rect, assuming that it's sorted.
654
1.22M
        SkASSERT(orig.isSorted());
655
1.22M
        SkPaint::Style style = this->getStyle();
656
        // ultra fast-case: filling with no effects that affect geometry
657
1.22M
        if (kFill_Style == style) {
658
1.15M
            uintptr_t effects = 0;
659
1.15M
            effects |= reinterpret_cast<uintptr_t>(this->getMaskFilter());
660
1.15M
            effects |= reinterpret_cast<uintptr_t>(this->getPathEffect());
661
1.15M
            effects |= reinterpret_cast<uintptr_t>(this->getImageFilter());
662
1.15M
            if (!effects) {
663
1.12M
                return orig;
664
1.12M
            }
665
94.3k
        }
666
667
94.3k
        return this->doComputeFastBounds(orig, storage, style);
668
94.3k
    }
669
670
    /**     (to be made private)
671
672
        @param orig     geometry modified by SkPaint when drawn
673
        @param storage  computed bounds of geometry
674
        @return         fast computed bounds
675
    */
676
    const SkRect& computeFastStrokeBounds(const SkRect& orig,
677
0
                                          SkRect* storage) const {
678
0
        return this->doComputeFastBounds(orig, storage, kStroke_Style);
679
0
    }
680
681
    /**     (to be made private)
682
        Computes the bounds, overriding the SkPaint SkPaint::Style. This can be used to
683
        account for additional width required by stroking orig, without
684
        altering SkPaint::Style set to fill.
685
686
        @param orig     geometry modified by SkPaint when drawn
687
        @param storage  computed bounds of geometry
688
        @param style    overrides SkPaint::Style
689
        @return         fast computed bounds
690
    */
691
    const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
692
                                      Style style) const;
693
694
private:
695
    sk_sp<SkPathEffect>   fPathEffect;
696
    sk_sp<SkShader>       fShader;
697
    sk_sp<SkMaskFilter>   fMaskFilter;
698
    sk_sp<SkColorFilter>  fColorFilter;
699
    sk_sp<SkImageFilter>  fImageFilter;
700
    sk_sp<SkBlender>      fBlender;
701
702
    SkColor4f       fColor4f;
703
    SkScalar        fWidth;
704
    SkScalar        fMiterLimit;
705
    union {
706
        struct {
707
            unsigned    fAntiAlias : 1;
708
            unsigned    fDither : 1;
709
            unsigned    fCapType : 2;
710
            unsigned    fJoinType : 2;
711
            unsigned    fStyle : 2;
712
            unsigned    fPadding : 24;  // 24 == 32 -1-1-2-2-2
713
        } fBitfields;
714
        uint32_t fBitfieldsUInt;
715
    };
716
717
    friend class SkPaintPriv;
718
};
719
720
#endif