Coverage Report

Created: 2024-05-20 07:14

/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/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
0
    friend bool operator!=(const SkPaint& a, const SkPaint& b) {
149
0
        return !(a == b);
150
0
    }
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
    */
162
760k
    bool isAntiAlias() const {
163
760k
        return SkToBool(fBitfields.fAntiAlias);
164
760k
    }
165
166
    /** Requests, but does not require, that edge pixels draw opaque or with
167
        partial transparency.
168
        @param aa  setting for antialiasing
169
    */
170
615k
    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
    */
175
2.12M
    bool isDither() const {
176
2.12M
        return SkToBool(fBitfields.fDither);
177
2.12M
    }
178
179
    /** Requests, but does not require, to distribute color error.
180
        @param dither  setting for ditering
181
    */
182
196k
    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
    */
204
2.75M
    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
    */
225
176k
    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
    */
232
1.04M
    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
1.96k
    void setColor4f(const SkColor4f& color, SkColorSpace* colorSpace = nullptr) {
254
1.96k
        this->setColor(color, colorSpace);
255
1.96k
    }
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
    */
261
1.26M
    float getAlphaf() const { return fColor4f.fA; }
262
263
    // Helper that scales the alpha by 255.
264
1.14M
    uint8_t getAlpha() const {
265
1.14M
        return static_cast<uint8_t>(sk_float_round2int(this->getAlphaf() * 255));
266
1.14M
    }
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
279
241k
    void setAlpha(U8CPU a) {
280
241k
        this->setAlphaf(a * (1.0f / 255));
281
241k
    }
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
    */
300
1.21M
    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
    */
318
924k
    SkScalar getStrokeMiter() const { return fMiterLimit; }
319
320
    /** Sets the limit at which a sharp corner is drawn beveled.
321
        Valid values are zero and greater.
322
        Has no effect if miter is less than zero.
323
324
        @param miter  zero and greater miter limit
325
326
        example: https://fiddle.skia.org/c/@Paint_setStrokeMiter
327
    */
328
    void setStrokeMiter(SkScalar miter);
329
330
    /** \enum SkPaint::Cap
331
        Cap draws at the beginning and end of an open path contour.
332
    */
333
    enum Cap {
334
        kButt_Cap,                  //!< no stroke extension
335
        kRound_Cap,                 //!< adds circle
336
        kSquare_Cap,                //!< adds square
337
        kLast_Cap    = kSquare_Cap, //!< largest Cap value
338
        kDefault_Cap = kButt_Cap,   //!< equivalent to kButt_Cap
339
    };
340
341
    /** May be used to verify that SkPaint::Cap is a legal value.
342
    */
343
    static constexpr int kCapCount = kLast_Cap + 1;
344
345
    /** \enum SkPaint::Join
346
        Join specifies how corners are drawn when a shape is stroked. Join
347
        affects the four corners of a stroked rectangle, and the connected segments in a
348
        stroked path.
349
350
        Choose miter join to draw sharp corners. Choose round join to draw a circle with a
351
        radius equal to the stroke width on top of the corner. Choose bevel join to minimally
352
        connect the thick strokes.
353
354
        The fill path constructed to describe the stroked path respects the join setting but may
355
        not contain the actual join. For instance, a fill path constructed with round joins does
356
        not necessarily include circles at each connected segment.
357
    */
358
    enum Join : uint8_t {
359
        kMiter_Join,                 //!< extends to miter limit
360
        kRound_Join,                 //!< adds circle
361
        kBevel_Join,                 //!< connects outside edges
362
        kLast_Join    = kBevel_Join, //!< equivalent to the largest value for Join
363
        kDefault_Join = kMiter_Join, //!< equivalent to kMiter_Join
364
    };
365
366
    /** May be used to verify that SkPaint::Join is a legal value.
367
    */
368
    static constexpr int kJoinCount = kLast_Join + 1;
369
370
    /** Returns the geometry drawn at the beginning and end of strokes.
371
    */
372
1.01M
    Cap getStrokeCap() const { return (Cap)fBitfields.fCapType; }
373
374
    /** Sets the geometry drawn at the beginning and end of strokes.
375
376
        example: https://fiddle.skia.org/c/@Paint_setStrokeCap_a
377
        example: https://fiddle.skia.org/c/@Paint_setStrokeCap_b
378
    */
379
    void setStrokeCap(Cap cap);
380
381
    /** Returns the geometry drawn at the corners of strokes.
382
    */
383
925k
    Join getStrokeJoin() const { return (Join)fBitfields.fJoinType; }
384
385
    /** Sets the geometry drawn at the corners of strokes.
386
387
        example: https://fiddle.skia.org/c/@Paint_setStrokeJoin
388
    */
389
    void setStrokeJoin(Join join);
390
391
    /** Returns optional colors used when filling a path, such as a gradient.
392
393
        Does not alter SkShader SkRefCnt.
394
395
        @return  SkShader if previously set, nullptr otherwise
396
    */
397
1.44M
    SkShader* getShader() const { return fShader.get(); }
398
399
    /** Returns optional colors used when filling a path, such as a gradient.
400
401
        Increases SkShader SkRefCnt by one.
402
403
        @return  SkShader if previously set, nullptr otherwise
404
405
        example: https://fiddle.skia.org/c/@Paint_refShader
406
    */
407
    sk_sp<SkShader> refShader() const;
408
409
    /** Sets optional colors used when filling a path, such as a gradient.
410
411
        Sets SkShader to shader, decreasing SkRefCnt of the previous SkShader.
412
        Increments shader SkRefCnt by one.
413
414
        @param shader  how geometry is filled with color; if nullptr, color is used instead
415
416
        example: https://fiddle.skia.org/c/@Color_Filter_Methods
417
        example: https://fiddle.skia.org/c/@Paint_setShader
418
    */
419
    void setShader(sk_sp<SkShader> shader);
420
421
    /** Returns SkColorFilter if set, or nullptr.
422
        Does not alter SkColorFilter SkRefCnt.
423
424
        @return  SkColorFilter if previously set, nullptr otherwise
425
    */
426
2.18M
    SkColorFilter* getColorFilter() const { return fColorFilter.get(); }
427
428
    /** Returns SkColorFilter if set, or nullptr.
429
        Increases SkColorFilter SkRefCnt by one.
430
431
        @return  SkColorFilter if set, or nullptr
432
433
        example: https://fiddle.skia.org/c/@Paint_refColorFilter
434
    */
435
    sk_sp<SkColorFilter> refColorFilter() const;
436
437
    /** Sets SkColorFilter to filter, decreasing SkRefCnt of the previous
438
        SkColorFilter. Pass nullptr to clear SkColorFilter.
439
440
        Increments filter SkRefCnt by one.
441
442
        @param colorFilter  SkColorFilter to apply to subsequent draw
443
444
        example: https://fiddle.skia.org/c/@Blend_Mode_Methods
445
        example: https://fiddle.skia.org/c/@Paint_setColorFilter
446
    */
447
    void setColorFilter(sk_sp<SkColorFilter> colorFilter);
448
449
    /** If the current blender can be represented as a SkBlendMode enum, this returns that
450
     *  enum in the optional's value(). If it cannot, then the returned optional does not
451
     *  contain a value.
452
     */
453
    std::optional<SkBlendMode> asBlendMode() const;
454
455
    /**
456
     *  Queries the blender, and if it can be represented as a SkBlendMode, return that mode,
457
     *  else return the defaultMode provided.
458
     */
459
    SkBlendMode getBlendMode_or(SkBlendMode defaultMode) const;
460
461
    /** Returns true iff the current blender claims to be equivalent to SkBlendMode::kSrcOver.
462
     *
463
     *  Also returns true of the current blender is nullptr.
464
     */
465
    bool isSrcOver() const;
466
467
    /** Helper method for calling setBlender().
468
     *
469
     *  This sets a blender that implements the specified blendmode enum.
470
     */
471
    void setBlendMode(SkBlendMode mode);
472
473
    /** Returns the user-supplied blend function, if one has been set.
474
     *  Does not alter SkBlender's SkRefCnt.
475
     *
476
     *  A nullptr blender signifies the default SrcOver behavior.
477
     *
478
     *  @return  the SkBlender assigned to this paint, otherwise nullptr
479
     */
480
175k
    SkBlender* getBlender() const { return fBlender.get(); }
481
482
    /** Returns the user-supplied blend function, if one has been set.
483
     *  Increments the SkBlender's SkRefCnt by one.
484
     *
485
     *  A nullptr blender signifies the default SrcOver behavior.
486
     *
487
     *  @return  the SkBlender assigned to this paint, otherwise nullptr
488
     */
489
    sk_sp<SkBlender> refBlender() const;
490
491
    /** Sets the current blender, increasing its refcnt, and if a blender is already
492
     *  present, decreasing that object's refcnt.
493
     *
494
     *  A nullptr blender signifies the default SrcOver behavior.
495
     *
496
     *  For convenience, you can call setBlendMode() if the blend effect can be expressed
497
     *  as one of those values.
498
     */
499
    void setBlender(sk_sp<SkBlender> blender);
500
501
    /** Returns SkPathEffect if set, or nullptr.
502
        Does not alter SkPathEffect SkRefCnt.
503
504
        @return  SkPathEffect if previously set, nullptr otherwise
505
    */
506
2.91M
    SkPathEffect* getPathEffect() const { return fPathEffect.get(); }
507
508
    /** Returns SkPathEffect if set, or nullptr.
509
        Increases SkPathEffect SkRefCnt by one.
510
511
        @return  SkPathEffect if previously set, nullptr otherwise
512
513
        example: https://fiddle.skia.org/c/@Paint_refPathEffect
514
    */
515
    sk_sp<SkPathEffect> refPathEffect() const;
516
517
    /** Sets SkPathEffect to pathEffect, decreasing SkRefCnt of the previous
518
        SkPathEffect. Pass nullptr to leave the path geometry unaltered.
519
520
        Increments pathEffect SkRefCnt by one.
521
522
        @param pathEffect  replace SkPath with a modification when drawn
523
524
        example: https://fiddle.skia.org/c/@Mask_Filter_Methods
525
        example: https://fiddle.skia.org/c/@Paint_setPathEffect
526
    */
527
    void setPathEffect(sk_sp<SkPathEffect> pathEffect);
528
529
    /** Returns SkMaskFilter if set, or nullptr.
530
        Does not alter SkMaskFilter SkRefCnt.
531
532
        @return  SkMaskFilter if previously set, nullptr otherwise
533
    */
534
3.74M
    SkMaskFilter* getMaskFilter() const { return fMaskFilter.get(); }
535
536
    /** Returns SkMaskFilter if set, or nullptr.
537
538
        Increases SkMaskFilter SkRefCnt by one.
539
540
        @return  SkMaskFilter if previously set, nullptr otherwise
541
542
        example: https://fiddle.skia.org/c/@Paint_refMaskFilter
543
    */
544
    sk_sp<SkMaskFilter> refMaskFilter() const;
545
546
    /** Sets SkMaskFilter to maskFilter, decreasing SkRefCnt of the previous
547
        SkMaskFilter. Pass nullptr to clear SkMaskFilter and leave SkMaskFilter effect on
548
        mask alpha unaltered.
549
550
        Increments maskFilter SkRefCnt by one.
551
552
        @param maskFilter  modifies clipping mask generated from drawn geometry
553
554
        example: https://fiddle.skia.org/c/@Paint_setMaskFilter
555
        example: https://fiddle.skia.org/c/@Typeface_Methods
556
    */
557
    void setMaskFilter(sk_sp<SkMaskFilter> maskFilter);
558
559
    /** Returns SkImageFilter if set, or nullptr.
560
        Does not alter SkImageFilter SkRefCnt.
561
562
        @return  SkImageFilter if previously set, nullptr otherwise
563
    */
564
2.54M
    SkImageFilter* getImageFilter() const { return fImageFilter.get(); }
565
566
    /** Returns SkImageFilter if set, or nullptr.
567
        Increases SkImageFilter SkRefCnt by one.
568
569
        @return  SkImageFilter if previously set, nullptr otherwise
570
571
        example: https://fiddle.skia.org/c/@Paint_refImageFilter
572
    */
573
    sk_sp<SkImageFilter> refImageFilter() const;
574
575
    /** Sets SkImageFilter to imageFilter, decreasing SkRefCnt of the previous
576
        SkImageFilter. Pass nullptr to clear SkImageFilter, and remove SkImageFilter effect
577
        on drawing.
578
579
        Increments imageFilter SkRefCnt by one.
580
581
        @param imageFilter  how SkImage is sampled when transformed
582
583
        example: https://fiddle.skia.org/c/@Paint_setImageFilter
584
    */
585
    void setImageFilter(sk_sp<SkImageFilter> imageFilter);
586
587
    /** Returns true if SkPaint prevents all drawing;
588
        otherwise, the SkPaint may or may not allow drawing.
589
590
        Returns true if, for example, SkBlendMode combined with alpha computes a
591
        new alpha of zero.
592
593
        @return  true if SkPaint prevents all drawing
594
595
        example: https://fiddle.skia.org/c/@Paint_nothingToDraw
596
    */
597
    bool nothingToDraw() const;
598
599
    /**     (to be made private)
600
        Returns true if SkPaint does not include elements requiring extensive computation
601
        to compute device bounds of drawn geometry. For instance, SkPaint with SkPathEffect
602
        always returns false.
603
604
        @return  true if SkPaint allows for fast computation of bounds
605
    */
606
    bool canComputeFastBounds() const;
607
608
    /**     (to be made private)
609
        Only call this if canComputeFastBounds() returned true. This takes a
610
        raw rectangle (the raw bounds of a shape), and adjusts it for stylistic
611
        effects in the paint (e.g. stroking). If needed, it uses the storage
612
        parameter. It returns the adjusted bounds that can then be used
613
        for SkCanvas::quickReject tests.
614
615
        The returned SkRect will either be orig or storage, thus the caller
616
        should not rely on storage being set to the result, but should always
617
        use the returned value. It is legal for orig and storage to be the same
618
        SkRect.
619
            For example:
620
            if (!path.isInverseFillType() && paint.canComputeFastBounds()) {
621
                SkRect storage;
622
                if (canvas->quickReject(paint.computeFastBounds(path.getBounds(), &storage))) {
623
                    return; // do not draw the path
624
                }
625
            }
626
            // draw the path
627
628
        @param orig     geometry modified by SkPaint when drawn
629
        @param storage  computed bounds of geometry; may not be nullptr
630
        @return         fast computed bounds
631
    */
632
    const SkRect& computeFastBounds(const SkRect& orig, SkRect* storage) const;
633
634
    /**     (to be made private)
635
636
        @param orig     geometry modified by SkPaint when drawn
637
        @param storage  computed bounds of geometry
638
        @return         fast computed bounds
639
    */
640
    const SkRect& computeFastStrokeBounds(const SkRect& orig,
641
0
                                          SkRect* storage) const {
642
0
        return this->doComputeFastBounds(orig, storage, kStroke_Style);
643
0
    }
644
645
    /**     (to be made private)
646
        Computes the bounds, overriding the SkPaint SkPaint::Style. This can be used to
647
        account for additional width required by stroking orig, without
648
        altering SkPaint::Style set to fill.
649
650
        @param orig     geometry modified by SkPaint when drawn
651
        @param storage  computed bounds of geometry
652
        @param style    overrides SkPaint::Style
653
        @return         fast computed bounds
654
    */
655
    const SkRect& doComputeFastBounds(const SkRect& orig, SkRect* storage,
656
                                      Style style) const;
657
658
    using sk_is_trivially_relocatable = std::true_type;
659
660
private:
661
    sk_sp<SkPathEffect>   fPathEffect;
662
    sk_sp<SkShader>       fShader;
663
    sk_sp<SkMaskFilter>   fMaskFilter;
664
    sk_sp<SkColorFilter>  fColorFilter;
665
    sk_sp<SkImageFilter>  fImageFilter;
666
    sk_sp<SkBlender>      fBlender;
667
668
    SkColor4f       fColor4f;
669
    SkScalar        fWidth;
670
    SkScalar        fMiterLimit;
671
    union {
672
        struct {
673
            unsigned    fAntiAlias : 1;
674
            unsigned    fDither : 1;
675
            unsigned    fCapType : 2;
676
            unsigned    fJoinType : 2;
677
            unsigned    fStyle : 2;
678
            unsigned    fPadding : 24;  // 24 == 32 -1-1-2-2-2
679
        } fBitfields;
680
        uint32_t fBitfieldsUInt;
681
    };
682
683
    static_assert(::sk_is_trivially_relocatable<decltype(fPathEffect)>::value);
684
    static_assert(::sk_is_trivially_relocatable<decltype(fShader)>::value);
685
    static_assert(::sk_is_trivially_relocatable<decltype(fMaskFilter)>::value);
686
    static_assert(::sk_is_trivially_relocatable<decltype(fColorFilter)>::value);
687
    static_assert(::sk_is_trivially_relocatable<decltype(fImageFilter)>::value);
688
    static_assert(::sk_is_trivially_relocatable<decltype(fBlender)>::value);
689
    static_assert(::sk_is_trivially_relocatable<decltype(fColor4f)>::value);
690
    static_assert(::sk_is_trivially_relocatable<decltype(fBitfields)>::value);
691
692
    friend class SkPaintPriv;
693
};
694
695
#endif