1 /*
2  * Copyright 2018 Google Inc.
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/SkStrokeRec.h"
9 #include "src/core/SkReadBuffer.h"
10 #include "src/core/SkWriteBuffer.h"
11 #include "src/effects/SkOpPE.h"
12 
Make(sk_sp<SkPathEffect> one,sk_sp<SkPathEffect> two,SkPathOp op)13 sk_sp<SkPathEffect> SkMergePathEffect::Make(sk_sp<SkPathEffect> one, sk_sp<SkPathEffect> two,
14                                             SkPathOp op) {
15     return sk_sp<SkPathEffect>(new SkOpPE(std::move(one), std::move(two), op));
16 }
17 
SkOpPE(sk_sp<SkPathEffect> one,sk_sp<SkPathEffect> two,SkPathOp op)18 SkOpPE::SkOpPE(sk_sp<SkPathEffect> one, sk_sp<SkPathEffect> two, SkPathOp op)
19     : fOne(std::move(one)), fTwo(std::move(two)), fOp(op) {}
20 
onFilterPath(SkPath * dst,const SkPath & src,SkStrokeRec * rec,const SkRect * cull) const21 bool SkOpPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec* rec,
22                           const SkRect* cull) const {
23     SkPath one, two;
24     if (fOne) {
25         if (!fOne->filterPath(&one, src, rec, cull)) {
26             return false;
27         }
28     } else {
29         one = src;
30     }
31     if (fTwo) {
32         if (!fTwo->filterPath(&two, src, rec, cull)) {
33             return false;
34         }
35     } else {
36         two = src;
37     }
38     return Op(one, two, fOp, dst);
39 }
40 
flatten(SkWriteBuffer & buffer) const41 void SkOpPE::flatten(SkWriteBuffer& buffer) const {
42     buffer.writeFlattenable(fOne.get());
43     buffer.writeFlattenable(fTwo.get());
44     buffer.write32(fOp);
45 }
46 
CreateProc(SkReadBuffer & buffer)47 sk_sp<SkFlattenable> SkOpPE::CreateProc(SkReadBuffer& buffer) {
48     auto one = buffer.readPathEffect();
49     auto two = buffer.readPathEffect();
50     SkPathOp op = buffer.read32LE(kReverseDifference_SkPathOp);
51     return buffer.isValid() ? SkMergePathEffect::Make(std::move(one), std::move(two), op) : nullptr;
52 }
53 
54 //////////////////////////////////////////////////////////////////////////////////////////////////
55 
MakeTranslate(SkScalar dx,SkScalar dy)56 sk_sp<SkPathEffect> SkMatrixPathEffect::MakeTranslate(SkScalar dx, SkScalar dy) {
57     if (!SkScalarsAreFinite(dx, dy)) {
58         return nullptr;
59     }
60     return sk_sp<SkPathEffect>(new SkMatrixPE(SkMatrix::MakeTrans(dx, dy)));
61 }
62 
Make(const SkMatrix & matrix)63 sk_sp<SkPathEffect> SkMatrixPathEffect::Make(const SkMatrix& matrix) {
64     if (!matrix.isFinite()) {
65         return nullptr;
66     }
67     return sk_sp<SkPathEffect>(new SkMatrixPE(matrix));
68 }
69 
SkMatrixPE(const SkMatrix & matrix)70 SkMatrixPE::SkMatrixPE(const SkMatrix& matrix) : fMatrix(matrix) {
71     SkASSERT(matrix.isFinite());
72 }
73 
onFilterPath(SkPath * dst,const SkPath & src,SkStrokeRec *,const SkRect *) const74 bool SkMatrixPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
75     src.transform(fMatrix, dst);
76     return true;
77 }
78 
flatten(SkWriteBuffer & buffer) const79 void SkMatrixPE::flatten(SkWriteBuffer& buffer) const {
80     buffer.writeMatrix(fMatrix);
81 }
82 
CreateProc(SkReadBuffer & buffer)83 sk_sp<SkFlattenable> SkMatrixPE::CreateProc(SkReadBuffer& buffer) {
84     SkMatrix mx;
85     buffer.readMatrix(&mx);
86     return buffer.isValid() ? SkMatrixPathEffect::Make(mx) : nullptr;
87 }
88 
89 //////////////////////////////////////////////////////////////////////////////////////////////////
90 
Make(SkScalar width,SkPaint::Join join,SkPaint::Cap cap,SkScalar miter)91 sk_sp<SkPathEffect> SkStrokePathEffect::Make(SkScalar width, SkPaint::Join join, SkPaint::Cap cap,
92                                              SkScalar miter) {
93     if (!SkScalarsAreFinite(width, miter) || width < 0 || miter < 0) {
94         return nullptr;
95     }
96     return sk_sp<SkPathEffect>(new SkStrokePE(width, join, cap, miter));
97 }
98 
SkStrokePE(SkScalar width,SkPaint::Join join,SkPaint::Cap cap,SkScalar miter)99 SkStrokePE::SkStrokePE(SkScalar width, SkPaint::Join join, SkPaint::Cap cap, SkScalar miter)
100     : fWidth(width), fMiter(miter), fJoin(join), fCap(cap) {}
101 
onFilterPath(SkPath * dst,const SkPath & src,SkStrokeRec *,const SkRect *) const102 bool SkStrokePE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*) const {
103     SkStrokeRec rec(SkStrokeRec::kFill_InitStyle);
104     rec.setStrokeStyle(fWidth);
105     rec.setStrokeParams(fCap, fJoin, fMiter);
106     return rec.applyToPath(dst, src);
107 }
108 
flatten(SkWriteBuffer & buffer) const109 void SkStrokePE::flatten(SkWriteBuffer& buffer) const {
110     buffer.writeScalar(fWidth);
111     buffer.writeScalar(fMiter);
112     buffer.write32(fJoin);
113     buffer.write32(fCap);
114 }
115 
CreateProc(SkReadBuffer & buffer)116 sk_sp<SkFlattenable> SkStrokePE::CreateProc(SkReadBuffer& buffer) {
117     SkScalar width = buffer.readScalar();
118     SkScalar miter = buffer.readScalar();
119     SkPaint::Join join = buffer.read32LE(SkPaint::kLast_Join);
120     SkPaint::Cap cap = buffer.read32LE(SkPaint::kLast_Cap);
121     return buffer.isValid() ? SkStrokePathEffect::Make(width, join, cap, miter) : nullptr;
122 }
123 
124 
125