Flutter Engine
The Flutter Engine
Loading...
Searching...
No Matches
SkTrimPathEffect.cpp
Go to the documentation of this file.
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
9
11#include "include/core/SkPath.h"
22
23#include <cstddef>
24#include <cstdint>
25
26class SkMatrix;
27class SkStrokeRec;
28struct SkRect;
29
30namespace {
31
32// Returns the number of contours iterated to satisfy the request.
33static size_t add_segments(const SkPath& src, SkScalar start, SkScalar stop, SkPath* dst,
34 bool requires_moveto = true) {
35 SkASSERT(start < stop);
36
37 SkPathMeasure measure(src, false);
38
39 SkScalar current_segment_offset = 0;
40 size_t contour_count = 1;
41
42 do {
43 const auto next_offset = current_segment_offset + measure.getLength();
44
45 if (start < next_offset) {
46 measure.getSegment(start - current_segment_offset,
47 stop - current_segment_offset,
48 dst, requires_moveto);
49
50 if (stop <= next_offset)
51 break;
52 }
53
54 contour_count++;
55 current_segment_offset = next_offset;
56 } while (measure.nextContour());
57
58 return contour_count;
59}
60
61} // namespace
62
64 : fStartT(startT), fStopT(stopT), fMode(mode) {}
65
66bool SkTrimPE::onFilterPath(SkPath* dst, const SkPath& src, SkStrokeRec*, const SkRect*,
67 const SkMatrix&) const {
68 if (fStartT >= fStopT) {
70 return true;
71 }
72
73 // First pass: compute the total len.
74 SkScalar len = 0;
75 SkPathMeasure meas(src, false);
76 do {
77 len += meas.getLength();
78 } while (meas.nextContour());
79
80 const auto arcStart = len * fStartT,
81 arcStop = len * fStopT;
82
83 // Second pass: actually add segments.
85 // Normal mode -> one span.
86 if (arcStart < arcStop) {
87 add_segments(src, arcStart, arcStop, dst);
88 }
89 } else {
90 // Inverted mode -> one logical span which wraps around at the end -> two actual spans.
91 // In order to preserve closed path continuity:
92 //
93 // 1) add the second/tail span first
94 //
95 // 2) skip the head span move-to for single-closed-contour paths
96
97 bool requires_moveto = true;
98 if (arcStop < len) {
99 // since we're adding the "tail" first, this is the total number of contours
100 const auto contour_count = add_segments(src, arcStop, len, dst);
101
102 // if the path consists of a single closed contour, we don't want to disconnect
103 // the two parts with a moveto.
104 if (contour_count == 1 && src.isLastContourClosed()) {
105 requires_moveto = false;
106 }
107 }
108 if (0 < arcStart) {
109 add_segments(src, 0, arcStart, dst, requires_moveto);
110 }
111 }
112
113 return true;
114}
115
117 buffer.writeScalar(fStartT);
118 buffer.writeScalar(fStopT);
119 buffer.writeUInt(static_cast<uint32_t>(fMode));
120}
121
122sk_sp<SkFlattenable> SkTrimPE::CreateProc(SkReadBuffer& buffer) {
123 const auto start = buffer.readScalar(),
124 stop = buffer.readScalar();
125 const auto mode = buffer.readUInt();
126
127 return SkTrimPathEffect::Make(start, stop,
129}
130
131//////////////////////////////////////////////////////////////////////////////////////////////////
132
134 if (!SkIsFinite(startT, stopT)) {
135 return nullptr;
136 }
137
138 if (startT <= 0 && stopT >= 1 && mode == Mode::kNormal) {
139 return nullptr;
140 }
141
142 startT = SkTPin(startT, 0.f, 1.f);
143 stopT = SkTPin(stopT, 0.f, 1.f);
144
145 if (startT >= stopT && mode == Mode::kInverted) {
146 return nullptr;
147 }
148
149 return sk_sp<SkPathEffect>(new SkTrimPE(startT, stopT, mode));
150}
#define SkASSERT(cond)
Definition SkAssert.h:116
static bool SkIsFinite(T x, Pack... values)
static constexpr const T & SkTPin(const T &x, const T &lo, const T &hi)
Definition SkTPin.h:19
SkScalar getLength()
bool onFilterPath(SkPath *dst, const SkPath &src, SkStrokeRec *, const SkRect *, const SkMatrix &) const override
void flatten(SkWriteBuffer &) const override
SkTrimPE(SkScalar startT, SkScalar stopT, SkTrimPathEffect::Mode)
static sk_sp< SkPathEffect > Make(SkScalar startT, SkScalar stopT, Mode=Mode::kNormal)
@ kNormal
Default priority level.
Definition embedder.h:260
float SkScalar
Definition extension.cpp:12
static const uint8_t buffer[]
SkBlendMode fMode
Definition xfermodes.cpp:52