/* libs/graphics/effects/Sk2DPathEffect.cpp ** ** Copyright 2006, The Android Open Source Project ** ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** ** http://www.apache.org/licenses/LICENSE-2.0 ** ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. */ #include "Sk2DPathEffect.h" #include "SkBlitter.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) { mat.invert(&fInverse); } bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width) { Sk2DPathEffectBlitter blitter(this, dst); SkPath tmp; SkIRect ir; src.transform(fInverse, &tmp); tmp.getBounds().round(&ir); if (!ir.isEmpty()) { // need to pass a clip to fillpath, required for inverse filltypes, // even though those do not make sense for this patheffect SkRegion clip(ir); this->begin(ir, dst); SkScan::FillPath(tmp, clip, &blitter); this->end(dst); } return true; } void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) { 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) { char storage[SkMatrix::kMaxFlattenSize]; uint32_t size = fMatrix.flatten(storage); buffer.write32(size); buffer.write(storage, size); } Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) { char storage[SkMatrix::kMaxFlattenSize]; uint32_t size = buffer.readS32(); SkASSERT(size <= sizeof(storage)); buffer.read(storage, size); fMatrix.unflatten(storage); fMatrix.invert(&fInverse); } SkFlattenable::Factory Sk2DPathEffect::getFactory() { return CreateProc; } SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { return SkNEW_ARGS(Sk2DPathEffect, (buffer)); }