xref: /aosp_15_r20/external/skia/src/core/SkPathUtils.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1 /*
2  * Copyright 2022 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 #include "include/core/SkPathUtils.h"
9 
10 #include "include/core/SkMatrix.h"
11 #include "include/core/SkPaint.h"
12 #include "include/core/SkPath.h"
13 #include "include/core/SkPathEffect.h"
14 #include "include/core/SkStrokeRec.h"
15 #include "src/core/SkMatrixPriv.h"
16 
17 namespace skpathutils {
18 
FillPathWithPaint(const SkPath & src,const SkPaint & paint,SkPath * dst)19 bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPath* dst) {
20     return skpathutils::FillPathWithPaint(src, paint, dst, nullptr, 1);
21 }
22 
FillPathWithPaint(const SkPath & src,const SkPaint & paint,SkPath * dst,const SkRect * cullRect,SkScalar resScale)23 bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPath* dst,
24                        const SkRect* cullRect, SkScalar resScale) {
25     return skpathutils::FillPathWithPaint(src, paint, dst, cullRect,
26                                           SkMatrix::Scale(resScale, resScale));
27 }
28 
FillPathWithPaint(const SkPath & src,const SkPaint & paint,SkPath * dst,const SkRect * cullRect,const SkMatrix & ctm)29 bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPath* dst,
30                        const SkRect* cullRect, const SkMatrix& ctm) {
31     if (!src.isFinite()) {
32         dst->reset();
33         return false;
34     }
35 
36     const SkScalar resScale = SkMatrixPriv::ComputeResScaleForStroking(ctm);
37     SkStrokeRec rec(paint, resScale);
38 
39 #if defined(SK_BUILD_FOR_FUZZER)
40     // Prevent lines with small widths from timing out.
41     if (rec.getStyle() == SkStrokeRec::Style::kStroke_Style && rec.getWidth() < 0.001) {
42         return false;
43     }
44 #endif
45 
46     const SkPath* srcPtr = &src;
47     SkPath tmpPath;
48 
49     SkPathEffect* pe = paint.getPathEffect();
50     if (pe && pe->filterPath(&tmpPath, src, &rec, cullRect, ctm)) {
51         srcPtr = &tmpPath;
52     }
53 
54     if (!rec.applyToPath(dst, *srcPtr)) {
55         if (srcPtr == &tmpPath) {
56             // If path's were copy-on-write, this trick would not be needed.
57             // As it is, we want to save making a deep-copy from tmpPath -> dst
58             // since we know we're just going to delete tmpPath when we return,
59             // so the swap saves that copy.
60             dst->swap(tmpPath);
61         } else {
62             *dst = *srcPtr;
63         }
64     }
65 
66     if (!dst->isFinite()) {
67         dst->reset();
68         return false;
69     }
70     return !rec.isHairlineStyle();
71 }
72 
73 } // namespace skpathutils
74 
FillPathWithPaint(const SkPath & src,const SkPaint & paint,SkPath * dst,const SkRect * cullRect,SkScalar resScale)75 bool FillPathWithPaint(const SkPath& src,
76                        const SkPaint& paint,
77                        SkPath* dst,
78                        const SkRect* cullRect,
79                        SkScalar resScale) {
80     return skpathutils::FillPathWithPaint(src, paint, dst, cullRect, resScale);
81 }
82 
FillPathWithPaint(const SkPath & src,const SkPaint & paint,SkPath * dst,const SkRect * cullRect,const SkMatrix & ctm)83 bool FillPathWithPaint(const SkPath& src,
84                        const SkPaint& paint,
85                        SkPath* dst,
86                        const SkRect* cullRect,
87                        const SkMatrix& ctm) {
88     return skpathutils::FillPathWithPaint(src, paint, dst, cullRect, ctm);
89 }
90 
FillPathWithPaint(const SkPath & src,const SkPaint & paint,SkPath * dst)91 bool FillPathWithPaint(const SkPath& src, const SkPaint& paint, SkPath* dst) {
92     return skpathutils::FillPathWithPaint(src, paint, dst);
93 }
94