/* * Copyright 2006 The Android Open Source Project * * Use of this source code is governed by a BSD-style license that can be * found in the LICENSE file. */ #include "Sk2DPathEffect.h" #include "SkBlitter.h" #include "SkFlattenableBuffers.h" #include "SkPath.h" #include "SkScan.h" class Sk2DPathEffectBlitter : public SkBlitter { public: Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst) : fPE(pe), fDst(dst) {} virtual void blitH(int x, int y, int count) { fPE->nextSpan(x, y, count, fDst); } private: Sk2DPathEffect* fPE; SkPath* fDst; }; /////////////////////////////////////////////////////////////////////////////// Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) { fMatrixIsInvertible = mat.invert(&fInverse); } bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*) { if (!fMatrixIsInvertible) { return false; } Sk2DPathEffectBlitter blitter(this, dst); SkPath tmp; SkIRect ir; src.transform(fInverse, &tmp); tmp.getBounds().round(&ir); if (!ir.isEmpty()) { this->begin(ir, dst); SkScan::FillPath(tmp, ir, &blitter); this->end(dst); } return true; } void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) { if (!fMatrixIsInvertible) { return; } const SkMatrix& mat = this->getMatrix(); SkPoint src, dst; src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf); do { mat.mapPoints(&dst, &src, 1); this->next(dst, x++, y, path); src.fX += SK_Scalar1; } while (--count > 0); } void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {} void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {} void Sk2DPathEffect::end(SkPath* dst) {} /////////////////////////////////////////////////////////////////////////////// void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); buffer.writeMatrix(fMatrix); } Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) { buffer.readMatrix(&fMatrix); fMatrixIsInvertible = fMatrix.invert(&fInverse); } /////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////// SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) : INHERITED(m), fPath(p) { } SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) { buffer.readPath(&fPath); } void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { this->INHERITED::flatten(buffer); buffer.writePath(fPath); } void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) { dst->addPath(fPath, loc.fX, loc.fY); } /////////////////////////////////////////////////////////////////////////////// SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect)