• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2023 Google LLC
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 SkDrawBase_DEFINED
9 #define SkDrawBase_DEFINED
10 
11 #include "include/core/SkCanvas.h"
12 #include "include/core/SkPaint.h"
13 #include "include/core/SkPixmap.h"
14 #include "include/core/SkRefCnt.h"
15 #include "include/core/SkSamplingOptions.h"
16 #include "include/core/SkStrokeRec.h"
17 #include "include/private/base/SkDebug.h"
18 #include "src/base/SkZip.h"
19 #include "src/core/SkDrawTypes.h"
20 #include "src/core/SkGlyphRunPainter.h"
21 #include "src/core/SkMask.h"
22 
23 #include <cstddef>
24 
25 class SkArenaAlloc;
26 class SkBitmap;
27 class SkBlitter;
28 class SkDevice;
29 class SkGlyph;
30 class SkMaskFilter;
31 class SkMatrix;
32 class SkPath;
33 class SkRRect;
34 class SkRasterClip;
35 class SkShader;
36 class SkSurfaceProps;
37 struct SkIRect;
38 struct SkPoint;
39 struct SkRect;
40 
41 class SkDrawBase : public SkGlyphRunListPainterCPU::BitmapDevicePainter {
42 public:
43     SkDrawBase();
44 
45     void drawPaint(const SkPaint&) const;
46     void drawRect(const SkRect& prePaintRect, const SkPaint&, const SkMatrix* paintMatrix,
47                      const SkRect* postPaintRect) const;
drawRect(const SkRect & rect,const SkPaint & paint)48     void drawRect(const SkRect& rect, const SkPaint& paint) const {
49         this->drawRect(rect, paint, nullptr, nullptr);
50     }
51     void drawRRect(const SkRRect&, const SkPaint&) const;
52     /**
53      *  To save on mallocs, we allow a flag that tells us that srcPath is
54      *  mutable, so that we don't have to make copies of it as we transform it.
55      *
56      *  If prePathMatrix is not null, it should logically be applied before any
57      *  stroking or other effects. If there are no effects on the paint that
58      *  affect the geometry/rasterization, then the pre matrix can just be
59      *  pre-concated with the current matrix.
60      */
drawPath(const SkPath & path,const SkPaint & paint,const SkMatrix * prePathMatrix,bool pathIsMutable)61     void drawPath(const SkPath& path, const SkPaint& paint,
62                   const SkMatrix* prePathMatrix, bool pathIsMutable) const {
63         this->drawPath(path, paint, prePathMatrix, pathIsMutable, SkDrawCoverage::kNo);
64     }
65 
66     /**
67      *  Overwrite the target with the path's coverage (i.e. its mask).
68      *  Will overwrite the entire device, so it need not be zero'd first.
69      *
70      *  Only device A8 is supported right now.
71      */
72     void drawPathCoverage(const SkPath& src, const SkPaint& paint,
73                           SkBlitter* customBlitter = nullptr) const {
74         bool isHairline = paint.getStyle() == SkPaint::kStroke_Style &&
75                           paint.getStrokeWidth() == 0;
76         this->drawPath(src,
77                        paint,
78                        nullptr,
79                        false,
80                        isHairline ? SkDrawCoverage::kNo : SkDrawCoverage::kYes,
81                        customBlitter);
82     }
83 
84     void drawDevicePoints(SkCanvas::PointMode, size_t count, const SkPoint[], const SkPaint&,
85                           SkDevice*) const;
86 
87     /** Helper function that creates a mask from a path and a required maskfilter.
88         Note however, that the resulting mask will not have been actually filtered,
89         that must be done afterwards (by calling filterMask). The maskfilter is provided
90         solely to assist in computing the mask's bounds (if the mode requests that).
91     */
92     static bool DrawToMask(const SkPath& devPath, const SkIRect& clipBounds,
93                            const SkMaskFilter*, const SkMatrix* filterMatrix,
94                            SkMaskBuilder* dst, SkMaskBuilder::CreateMode mode,
95                            SkStrokeRec::InitStyle style);
96 
97     enum RectType {
98         kHair_RectType,
99         kFill_RectType,
100         kStroke_RectType,
101         kPath_RectType
102     };
103 
104     /**
105      *  Based on the paint's style, strokeWidth, and the matrix, classify how
106      *  to draw the rect. If no special-case is available, returns
107      *  kPath_RectType.
108      *
109      *  Iff RectType == kStroke_RectType, then strokeSize is set to the device
110      *  width and height of the stroke.
111      */
112     static RectType ComputeRectType(const SkRect&, const SkPaint&, const SkMatrix&,
113                                     SkPoint* strokeSize);
114 
115     using BlitterChooser = SkBlitter*(const SkPixmap& dst,
116                                       const SkMatrix& ctm,
117                                       const SkPaint&,
118                                       SkArenaAlloc*,
119                                       SkDrawCoverage drawCoverage,
120                                       sk_sp<SkShader> clipShader,
121                                       const SkSurfaceProps&);
122 
123 private:
124     // not supported
125     void paintMasks(SkZip<const SkGlyph*, SkPoint> accepted, const SkPaint& paint) const override;
126     void drawBitmap(const SkBitmap&, const SkMatrix&, const SkRect* dstOrNull,
127                     const SkSamplingOptions&, const SkPaint&) const override;
128 
129     void drawPath(const SkPath&,
130                   const SkPaint&,
131                   const SkMatrix* preMatrix,
132                   bool pathIsMutable,
133                   SkDrawCoverage drawCoverage,
134                   SkBlitter* customBlitter = nullptr) const;
135 
136     void drawLine(const SkPoint[2], const SkPaint&) const;
137 
138     void drawDevPath(const SkPath& devPath,
139                      const SkPaint& paint,
140                      SkDrawCoverage drawCoverage,
141                      SkBlitter* customBlitter,
142                      bool doFill) const;
143     /**
144      *  Return the current clip bounds, in local coordinates, with slop to account
145      *  for antialiasing or hairlines (i.e. device-bounds outset by 1, and then
146      *  run through the inverse of the matrix).
147      *
148      *  If the matrix cannot be inverted, or the current clip is empty, return
149      *  false and ignore bounds parameter.
150      */
151     [[nodiscard]] bool computeConservativeLocalClipBounds(SkRect* bounds) const;
152 
153 public:
154     SkPixmap                fDst;
155     BlitterChooser*         fBlitterChooser{nullptr};  // required
156     const SkMatrix*         fCTM{nullptr};             // required
157     const SkRasterClip*     fRC{nullptr};              // required
158     const SkSurfaceProps*   fProps{nullptr};           // optional
159 
160 #ifdef SK_DEBUG
161     void validate() const;
162 #else
validate()163     void validate() const {}
164 #endif
165 };
166 
167 #endif  // SkDrawBase_DEFINED
168