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