Sk2DPathEffect.cpp revision 90bf427001fd4f6d9fcee88911deb015aeb4ab7c
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) {
3190bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    fMatrixIsInvertible = mat.invert(&fInverse);
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
3416edff2b1cbd80e36456138f8631711a585205bareed@google.combool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width) {
3590bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    if (!fMatrixIsInvertible) {
3690bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org        return false;
3790bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    }
3890bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Sk2DPathEffectBlitter   blitter(this, dst);
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath                  tmp;
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkIRect                 ir;
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    src.transform(fInverse, &tmp);
44d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    tmp.getBounds().round(&ir);
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!ir.isEmpty()) {
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->begin(ir, dst);
47045e62d715f5ee9b03deb5af3c750f8318096179reed@google.com        SkScan::FillPath(tmp, ir, &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) {
5490bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    if (!fMatrixIsInvertible) {
5590bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org        return;
5690bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    }
5790bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkMatrix& mat = this->getMatrix();
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint src, dst;
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        mat.mapPoints(&dst, &src, 1);
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->next(dst, x++, y, path);
658a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        src.fX += SK_Scalar1;
668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (--count > 0);
678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {}
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {}
718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Sk2DPathEffect::end(SkPath* dst) {}
728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7316edff2b1cbd80e36456138f8631711a585205bareed@google.com///////////////////////////////////////////////////////////////////////////////
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
7554924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comvoid Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
7654924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com    this->INHERITED::flatten(buffer);
771a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    char storage[SkMatrix::kMaxFlattenSize];
781a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    uint32_t size = fMatrix.flatten(storage);
791a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    buffer.write32(size);
801a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    buffer.write(storage, size);
818a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
8316edff2b1cbd80e36456138f8631711a585205bareed@google.comSk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) {
841a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    char storage[SkMatrix::kMaxFlattenSize];
851a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    uint32_t size = buffer.readS32();
861a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    SkASSERT(size <= sizeof(storage));
871a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    buffer.read(storage, size);
881a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    fMatrix.unflatten(storage);
8990bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    fMatrixIsInvertible = fMatrix.invert(&fInverse);
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
92e28b917669fc4677b2f1c0a08c4711b651cbf1a1reed@google.com///////////////////////////////////////////////////////////////////////////////
9318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com///////////////////////////////////////////////////////////////////////////////
9418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
9518dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comSkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
9618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com    : INHERITED(m), fPath(p) {
9718dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com}
9818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
9918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comSkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer)
10018dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com        : INHERITED(buffer) {
1012b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    buffer.readPath(&fPath);
10218dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com}
10318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
10454924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comvoid SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
10518dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com    this->INHERITED::flatten(buffer);
1062b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    buffer.writePath(fPath);
10718dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com}
10818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
10918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comvoid SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {
11018dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com    dst->addPath(fPath, loc.fX, loc.fY);
11118dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com}
1128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
113a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.com///////////////////////////////////////////////////////////////////////////////
1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
115a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.comSK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect)
116