Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkSGMerge.cpp
Go to the documentation of this file.
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
9
16#include "src/core/SkPathPriv.h"
17
18class SkMatrix;
19
20namespace sksg {
21
22Merge::Merge(std::vector<Rec>&& recs)
23 : fRecs(std::move(recs)) {
24 for (const auto& rec : fRecs) {
25 this->observeInval(rec.fGeo);
26 }
27}
28
29Merge::~Merge() {
30 for (const auto& rec : fRecs) {
31 this->unobserveInval(rec.fGeo);
32 }
33}
34
35void Merge::onClip(SkCanvas* canvas, bool antiAlias) const {
36 canvas->clipPath(fMerged, SkClipOp::kIntersect, antiAlias);
37}
38
39void Merge::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
40 canvas->drawPath(fMerged, paint);
41}
42
43bool Merge::onContains(const SkPoint& p) const {
44 return fMerged.contains(p.x(), p.y());
45}
46
47SkPath Merge::onAsPath() const {
48 return fMerged;
49}
50
52 switch (mode) {
53 case Merge::Mode::kUnion:
54 return kUnion_SkPathOp;
55 case Merge::Mode::kIntersect:
57 case Merge::Mode::kDifference:
59 case Merge::Mode::kReverseDifference:
61 case Merge::Mode::kXOR:
62 return kXOR_SkPathOp;
63 default:
64 break;
65 }
66
67 return kUnion_SkPathOp;
68}
69
70SkRect Merge::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
71 SkASSERT(this->hasInval());
72
73 SkOpBuilder builder;
74
75 fMerged.reset();
76 bool in_builder = false;
77
78 auto append = [&](const SkPath& path) {
79 if (in_builder) {
80 builder.resolve(&fMerged);
81 in_builder = false;
82 }
83
84 if (fMerged.isEmpty()) {
85 // First merge path determines the fill type.
86 fMerged = path;
87 } else {
88 fMerged.addPath(path);
89 }
90 };
91
92 for (const auto& rec : fRecs) {
93 rec.fGeo->revalidate(ic, ctm);
94
95 if (rec.fMode == Mode::kMerge) {
96 // Merge (append) is not supported by SkOpBuidler.
97 append(rec.fGeo->asPath());
98 continue;
99 }
100
101 if (!in_builder) {
102 builder.add(fMerged, kUnion_SkPathOp);
103 in_builder = true;
104 }
105
106 builder.add(rec.fGeo->asPath(), mode_to_op(rec.fMode));
107 }
108
109 if (in_builder) {
110 builder.resolve(&fMerged);
111 }
112
113 SkPathPriv::ShrinkToFit(&fMerged);
114
115 return fMerged.computeTightBounds();
116}
117
118} // namespace sksg
#define SkASSERT(cond)
Definition SkAssert.h:116
SkPathOp
Definition SkPathOps.h:22
@ kReverseDifference_SkPathOp
subtract the first path from the op path
Definition SkPathOps.h:27
@ kDifference_SkPathOp
subtract the op path from the first path
Definition SkPathOps.h:23
@ kIntersect_SkPathOp
intersect the two paths
Definition SkPathOps.h:24
@ kUnion_SkPathOp
union (inclusive-or) the two paths
Definition SkPathOps.h:25
@ kXOR_SkPathOp
exclusive-or the two paths
Definition SkPathOps.h:26
void clipPath(const SkPath &path, SkClipOp op, bool doAntiAlias)
void drawPath(const SkPath &path, const SkPaint &paint)
static void ShrinkToFit(SkPath *path)
Definition SkPathPriv.h:130
const Paint & paint
static void append(char **dst, size_t *count, const char *src, size_t n)
Definition editor.cpp:211
Definition Skottie.h:32
static SkPathOp mode_to_op(Merge::Mode mode)
Definition SkSGMerge.cpp:51
Definition ref_ptr.h:256