Sk2DPathEffect.cpp revision a2ca41e3afdd8fad5e0e924dec029f33918e0a67
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
22a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)/*
32a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Copyright 2006 The Android Open Source Project
42a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) *
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci * found in the LICENSE file.
73551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) */
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "Sk2DPathEffect.h"
111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "SkBlitter.h"
121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "SkPath.h"
131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "SkScan.h"
141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci
151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciclass Sk2DPathEffectBlitter : public SkBlitter {
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)public:
172a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst)
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        : fPE(pe), fDst(dst) {}
192a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
2003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    virtual void blitH(int x, int y, int count) {
212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        fPE->nextSpan(x, y, count, fDst);
22a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    }
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)private:
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Sk2DPathEffect* fPE;
255d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    SkPath*         fDst;
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)};
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
282a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
292a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    mat.invert(&fInverse);
322a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
342a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width) {
352a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    Sk2DPathEffectBlitter   blitter(this, dst);
362a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkPath                  tmp;
372a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkIRect                 ir;
385d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
395d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    src.transform(fInverse, &tmp);
405d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tmp.getBounds().round(&ir);
415d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!ir.isEmpty()) {
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        this->begin(ir, dst);
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        SkScan::FillPath(tmp, ir, &blitter);
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)        this->end(dst);
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    }
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return true;
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) {
505d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    const SkMatrix& mat = this->getMatrix();
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    SkPoint src, dst;
525d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
535d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    do {
5503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)        mat.mapPoints(&dst, &src, 1);
56eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch        this->next(dst, x++, y, path);
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        src.fX += SK_Scalar1;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    } while (--count > 0);
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {}
622a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {}
632a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Sk2DPathEffect::end(SkPath* dst) {}
645d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
665d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    char storage[SkMatrix::kMaxFlattenSize];
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32_t size = fMatrix.flatten(storage);
70a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    buffer.write32(size);
715d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    buffer.write(storage, size);
722a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
732a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
742a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) {
7503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    char storage[SkMatrix::kMaxFlattenSize];
762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    uint32_t size = buffer.readS32();
772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    SkASSERT(size <= sizeof(storage));
7803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    buffer.read(storage, size);
792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fMatrix.unflatten(storage);
802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    fMatrix.invert(&fInverse);
812a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
822a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
832a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkFlattenable::Factory Sk2DPathEffect::getFactory() {
842a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CreateProc;
852a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
862a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) {
882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return SkNEW_ARGS(Sk2DPathEffect, (buffer));
89a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)}
90a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
912a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
922a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
935d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
9403b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
9503b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    : INHERITED(m), fPath(p) {
9603b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
97d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)
98d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer)
99d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)        : INHERITED(buffer) {
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fPath.unflatten(buffer);
10103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
10203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
10303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)SkFlattenable* SkPath2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) {
104d0247b1b59f9c528cb6df88b4f2b9afaf80d181eTorne (Richard Coles)    return SkNEW_ARGS(SkPath2DPathEffect, (buffer));
1055d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
1062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
10703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)void SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
10803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    this->INHERITED::flatten(buffer);
10903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    fPath.flatten(buffer);
11003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
11103b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)SkFlattenable::Factory SkPath2DPathEffect::getFactory() {
1132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    return CreateProc;
1142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}
1152a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
1165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {
11703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)    dst->addPath(fPath, loc.fX, loc.fY);
11803b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
11903b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)
1205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1212a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)
12203b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect)
12303b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)