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