Sk2DPathEffect.cpp revision 16edff2b1cbd80e36456138f8631711a585205ba
1ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 2ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com/* 3ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Copyright 2006 The Android Open Source Project 4ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * 5ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * Use of this source code is governed by a BSD-style license that can be 6ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com * found in the LICENSE file. 7ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com */ 8ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976eepoger@google.com 98a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "Sk2DPathEffect.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBlitter.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkScan.h" 148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comclass Sk2DPathEffectBlitter : public SkBlitter { 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.compublic: 178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst) 1816edff2b1cbd80e36456138f8631711a585205bareed@google.com : fPE(pe), fDst(dst) {} 1916edff2b1cbd80e36456138f8631711a585205bareed@google.com 2016edff2b1cbd80e36456138f8631711a585205bareed@google.com virtual void blitH(int x, int y, int count) { 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPE->nextSpan(x, y, count, fDst); 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate: 248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Sk2DPathEffect* fPE; 258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath* fDst; 268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}; 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 2816edff2b1cbd80e36456138f8631711a585205bareed@google.com/////////////////////////////////////////////////////////////////////////////// 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3016edff2b1cbd80e36456138f8631711a585205bareed@google.comSk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) { 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mat.invert(&fInverse); 328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 3416edff2b1cbd80e36456138f8631711a585205bareed@google.combool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width) { 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Sk2DPathEffectBlitter blitter(this, dst); 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath tmp; 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkIRect ir; 388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com src.transform(fInverse, &tmp); 40d252db03d9650013b545ef9781fe993c07f8f314reed@android.com tmp.getBounds().round(&ir); 418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com if (!ir.isEmpty()) { 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // need to pass a clip to fillpath, required for inverse filltypes, 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // even though those do not make sense for this patheffect 448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkRegion clip(ir); 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->begin(ir, dst); 478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkScan::FillPath(tmp, clip, &blitter); 488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->end(dst); 498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 5316edff2b1cbd80e36456138f8631711a585205bareed@google.comvoid Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) { 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkMatrix& mat = this->getMatrix(); 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPoint src, dst; 568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf); 588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com do { 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com mat.mapPoints(&dst, &src, 1); 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com this->next(dst, x++, y, path); 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com src.fX += SK_Scalar1; 628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } while (--count > 0); 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {} 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {} 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Sk2DPathEffect::end(SkPath* dst) {} 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 6916edff2b1cbd80e36456138f8631711a585205bareed@google.com/////////////////////////////////////////////////////////////////////////////// 708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7116edff2b1cbd80e36456138f8631711a585205bareed@google.comvoid Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 721a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org char storage[SkMatrix::kMaxFlattenSize]; 731a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org uint32_t size = fMatrix.flatten(storage); 741a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org buffer.write32(size); 751a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org buffer.write(storage, size); 768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 778a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 7816edff2b1cbd80e36456138f8631711a585205bareed@google.comSk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) { 791a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org char storage[SkMatrix::kMaxFlattenSize]; 801a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org uint32_t size = buffer.readS32(); 811a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org SkASSERT(size <= sizeof(storage)); 821a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org buffer.read(storage, size); 831a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org fMatrix.unflatten(storage); 848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMatrix.invert(&fInverse); 858a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 868a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 8716edff2b1cbd80e36456138f8631711a585205bareed@google.comSkFlattenable::Factory Sk2DPathEffect::getFactory() { 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return CreateProc; 898a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 9116edff2b1cbd80e36456138f8631711a585205bareed@google.comSkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return SkNEW_ARGS(Sk2DPathEffect, (buffer)); 938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 95e28b917669fc4677b2f1c0a08c4711b651cbf1a1reed@google.com/////////////////////////////////////////////////////////////////////////////// 9618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com/////////////////////////////////////////////////////////////////////////////// 9718dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 9818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comSkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) 9918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com : INHERITED(m), fPath(p) { 10018dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 10118dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 10218dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comSkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer) 10318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com : INHERITED(buffer) { 10418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com fPath.unflatten(buffer); 10518dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 10618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 10718dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comSkFlattenable* SkPath2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 10818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com return SkNEW_ARGS(SkPath2DPathEffect, (buffer)); 10918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 11018dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 11118dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comvoid SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 11218dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com this->INHERITED::flatten(buffer); 11318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com fPath.flatten(buffer); 11418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 11518dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 11618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comSkFlattenable::Factory SkPath2DPathEffect::getFactory() { 11718dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com return CreateProc; 11818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 11918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 12018dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comvoid SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) { 12118dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com dst->addPath(fPath, loc.fX, loc.fY); 12218dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 12418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comstatic SkFlattenable::Registrar gReg("SkPath2DPathEffect", 12518dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com SkPath2DPathEffect::CreateProc); 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 127