Coverage Report

Created: 2021-08-22 09:07

/src/skia/src/core/SkClipStackDevice.cpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
 * Copyright 2017 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 "src/core/SkClipStackDevice.h"
9
#include "src/core/SkDraw.h"
10
#include "src/core/SkRasterClip.h"
11
12
160k
SkIRect SkClipStackDevice::onDevClipBounds() const {
13
160k
    SkIRect r = fClipStack.bounds(this->imageInfo().bounds()).roundOut();
14
160k
    if (!r.isEmpty()) {
15
160k
        SkASSERT(this->imageInfo().bounds().contains(r));
16
160k
    }
17
160k
    return r;
18
160k
}
19
20
///////////////////////////////////////////////////////////////////////////////////////////////////
21
22
106k
void SkClipStackDevice::onSave() {
23
106k
    fClipStack.save();
24
106k
}
25
26
106k
void SkClipStackDevice::onRestore() {
27
106k
    fClipStack.restore();
28
106k
}
29
30
41.2k
void SkClipStackDevice::onClipRect(const SkRect& rect, SkClipOp op, bool aa) {
31
41.2k
    fClipStack.clipRect(rect, this->localToDevice(), op, aa);
32
41.2k
}
33
34
10.4k
void SkClipStackDevice::onClipRRect(const SkRRect& rrect, SkClipOp op, bool aa) {
35
10.4k
    fClipStack.clipRRect(rrect, this->localToDevice(), op, aa);
36
10.4k
}
37
38
5.35k
void SkClipStackDevice::onClipPath(const SkPath& path, SkClipOp op, bool aa) {
39
5.35k
    fClipStack.clipPath(path, this->localToDevice(), op, aa);
40
5.35k
}
41
42
0
void SkClipStackDevice::onClipShader(sk_sp<SkShader> shader) {
43
0
    fClipStack.clipShader(std::move(shader));
44
0
}
45
46
2.28k
void SkClipStackDevice::onClipRegion(const SkRegion& rgn, SkClipOp op) {
47
2.28k
    SkIPoint origin = this->getOrigin();
48
2.28k
    SkRegion tmp;
49
2.28k
    SkPath path;
50
2.28k
    rgn.getBoundaryPath(&path);
51
2.28k
    path.transform(SkMatrix::Translate(-origin));
52
2.28k
    fClipStack.clipPath(path, SkMatrix::I(), op, false);
53
2.28k
}
54
55
0
void SkClipStackDevice::onReplaceClip(const SkIRect& rect) {
56
0
    SkRect deviceRect = SkMatrixPriv::MapRect(this->globalToDevice(), SkRect::Make(rect));
57
0
    fClipStack.replaceClip(deviceRect, /*doAA=*/false);
58
0
}
59
60
0
bool SkClipStackDevice::onClipIsAA() const {
61
0
    SkClipStack::B2TIter        iter(fClipStack);
62
0
    const SkClipStack::Element* element;
63
64
0
    while ((element = iter.next()) != nullptr) {
65
0
        if (element->isAA()) {
66
0
            return true;
67
0
        }
68
0
    }
69
0
    return false;
70
0
}
71
72
0
bool SkClipStackDevice::onClipIsWideOpen() const {
73
0
    return fClipStack.quickContains(SkRect::MakeIWH(this->width(), this->height()));
74
0
}
75
76
0
void SkClipStackDevice::onAsRgnClip(SkRegion* rgn) const {
77
0
    SkClipStack::BoundsType boundType;
78
0
    bool isIntersectionOfRects;
79
0
    SkRect bounds;
80
0
    fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
81
0
    if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
82
0
        rgn->setRect(bounds.round());
83
0
    } else {
84
0
        SkRegion boundsRgn({0, 0, this->width(), this->height()});
85
0
        SkPath tmpPath;
86
87
0
        *rgn = boundsRgn;
88
0
        SkClipStack::B2TIter iter(fClipStack);
89
0
        while (auto elem = iter.next()) {
90
0
            tmpPath.rewind();
91
0
            elem->asDeviceSpacePath(&tmpPath);
92
0
            SkRegion tmpRgn;
93
0
            tmpRgn.setPath(tmpPath, boundsRgn);
94
0
            if (elem->isReplaceOp()) {
95
                // All replace elements are rectangles
96
                // TODO: SkClipStack can be simplified to be I,D,R ops now, which means element
97
                // iteration can be from top of the stack to the most recent replace element.
98
                // When that's done, this loop will be simplifiable.
99
0
                rgn->setRect(elem->getDeviceSpaceRect().round());
100
0
            } else {
101
0
                rgn->op(tmpRgn, static_cast<SkRegion::Op>(elem->getOp()));
102
0
            }
103
0
        }
104
0
    }
105
0
}
106
107
263k
SkBaseDevice::ClipType SkClipStackDevice::onGetClipType() const {
108
263k
    if (fClipStack.isWideOpen()) {
109
125k
        return ClipType::kRect;
110
125k
    }
111
138k
    if (fClipStack.isEmpty(SkIRect::MakeWH(this->width(), this->height()))) {
112
102k
        return ClipType::kEmpty;
113
35.8k
    } else {
114
35.8k
        SkClipStack::BoundsType boundType;
115
35.8k
        bool isIntersectionOfRects;
116
35.8k
        SkRect bounds;
117
35.8k
        fClipStack.getBounds(&bounds, &boundType, &isIntersectionOfRects);
118
35.8k
        if (isIntersectionOfRects && SkClipStack::kNormal_BoundsType == boundType) {
119
2.04k
            return ClipType::kRect;
120
33.8k
        } else {
121
33.8k
            return ClipType::kComplex;
122
33.8k
        }
123
35.8k
    }
124
138k
}