xref: /aosp_15_r20/external/skia/src/utils/SkClipStackUtils.cpp (revision c8dee2aa9b3f27cf6c858bd81872bdeb2c07ed17)
1*c8dee2aaSAndroid Build Coastguard Worker /*
2*c8dee2aaSAndroid Build Coastguard Worker * Copyright 2019 Google Inc.
3*c8dee2aaSAndroid Build Coastguard Worker *
4*c8dee2aaSAndroid Build Coastguard Worker * Use of this source code is governed by a BSD-style license that can be
5*c8dee2aaSAndroid Build Coastguard Worker * found in the LICENSE file.
6*c8dee2aaSAndroid Build Coastguard Worker */
7*c8dee2aaSAndroid Build Coastguard Worker 
8*c8dee2aaSAndroid Build Coastguard Worker #include "src/utils/SkClipStackUtils.h"
9*c8dee2aaSAndroid Build Coastguard Worker 
10*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPath.h"
11*c8dee2aaSAndroid Build Coastguard Worker #include "include/core/SkPathTypes.h"
12*c8dee2aaSAndroid Build Coastguard Worker #include "include/pathops/SkPathOps.h"
13*c8dee2aaSAndroid Build Coastguard Worker #include "src/core/SkClipStack.h"
14*c8dee2aaSAndroid Build Coastguard Worker 
15*c8dee2aaSAndroid Build Coastguard Worker enum class SkClipOp;
16*c8dee2aaSAndroid Build Coastguard Worker 
SkClipStack_AsPath(const SkClipStack & cs,SkPath * path)17*c8dee2aaSAndroid Build Coastguard Worker void SkClipStack_AsPath(const SkClipStack& cs, SkPath* path) {
18*c8dee2aaSAndroid Build Coastguard Worker     path->reset();
19*c8dee2aaSAndroid Build Coastguard Worker     path->setFillType(SkPathFillType::kInverseEvenOdd);
20*c8dee2aaSAndroid Build Coastguard Worker 
21*c8dee2aaSAndroid Build Coastguard Worker     SkClipStack::Iter iter(cs, SkClipStack::Iter::kBottom_IterStart);
22*c8dee2aaSAndroid Build Coastguard Worker     while (const SkClipStack::Element* element = iter.next()) {
23*c8dee2aaSAndroid Build Coastguard Worker         if (element->getDeviceSpaceType() == SkClipStack::Element::DeviceSpaceType::kShader) {
24*c8dee2aaSAndroid Build Coastguard Worker             // TODO: Handle DeviceSpaceType::kShader somehow; it can't be turned into an SkPath
25*c8dee2aaSAndroid Build Coastguard Worker             // but perhaps the pdf backend can apply shaders in another way.
26*c8dee2aaSAndroid Build Coastguard Worker             continue;
27*c8dee2aaSAndroid Build Coastguard Worker         }
28*c8dee2aaSAndroid Build Coastguard Worker         SkPath operand;
29*c8dee2aaSAndroid Build Coastguard Worker         if (element->getDeviceSpaceType() != SkClipStack::Element::DeviceSpaceType::kEmpty) {
30*c8dee2aaSAndroid Build Coastguard Worker             element->asDeviceSpacePath(&operand);
31*c8dee2aaSAndroid Build Coastguard Worker         }
32*c8dee2aaSAndroid Build Coastguard Worker 
33*c8dee2aaSAndroid Build Coastguard Worker         SkClipOp elementOp = element->getOp();
34*c8dee2aaSAndroid Build Coastguard Worker         if (element->isReplaceOp()) {
35*c8dee2aaSAndroid Build Coastguard Worker             *path = operand;
36*c8dee2aaSAndroid Build Coastguard Worker             // TODO: Once expanding clip ops are removed, we can switch the iterator to be top
37*c8dee2aaSAndroid Build Coastguard Worker             // to bottom, which allows us to break here on encountering a replace op.
38*c8dee2aaSAndroid Build Coastguard Worker         } else {
39*c8dee2aaSAndroid Build Coastguard Worker             Op(*path, operand, (SkPathOp)elementOp, path);
40*c8dee2aaSAndroid Build Coastguard Worker         }
41*c8dee2aaSAndroid Build Coastguard Worker     }
42*c8dee2aaSAndroid Build Coastguard Worker }
43