blob: af0b640a4c5739084131cb713225223e9b0f831f [file] [log] [blame]
Florin Malita51b8c892018-01-07 08:54:24 -05001/*
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 "SkSGTrimEffect.h"
9
10#include "SkCanvas.h"
11#include "SkDashPathEffect.h"
12#include "SkPathMeasure.h"
13
14namespace sksg {
15
16TrimEffect::TrimEffect(sk_sp<GeometryNode> child)
17 : fChild(std::move(child)) {
18 fChild->addInvalReceiver(this);
19}
20
21TrimEffect::~TrimEffect() {
22 fChild->removeInvalReceiver(this);
23}
24
25// TODO
26// This is a quick hack to get something on the screen. What we really want here is to apply
27// the geometry transformation and cache the result on revalidation. Or an SkTrimPathEffect.
28void TrimEffect::onDraw(SkCanvas* canvas, const SkPaint& paint) const {
Florin Malita51b8c892018-01-07 08:54:24 -050029 SkASSERT(!paint.getPathEffect());
30
31 const auto path = fChild->asPath();
32 SkScalar pathLen = 0;
33 SkPathMeasure measure(path, false);
34 do {
35 pathLen += measure.getLength();
36 } while (measure.nextContour());
37
38 const auto start = SkScalarPin(fStart , 0, 1) * pathLen,
39 end = SkScalarPin(fEnd , 0, 1) * pathLen,
40 offset = SkScalarPin(fOffset, 0, 1) * pathLen,
41 len = SkTMax<SkScalar>(end - start, 0);
42
43 const SkScalar dashes[4] = { 0, start, len, pathLen - end };
44 SkPaint dashedPaint(paint);
45 dashedPaint.setPathEffect(SkDashPathEffect::Make(dashes, 4, -offset));
46
47 canvas->drawPath(path, dashedPaint);
48}
49
50SkPath TrimEffect::onAsPath() const {
51 return fChild->asPath();
52}
53
54SkRect TrimEffect::onRevalidate(InvalidationController* ic, const SkMatrix& ctm) {
55 SkASSERT(this->hasInval());
56 return fChild->revalidate(ic, ctm);
57}
58
59} // namespace sksg