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 Workervoid 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