Sk2DPathEffect.cpp revision ec3ed6a5ebf6f2c406d7bcf94b6bc34fcaeb976e
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)
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        : fPE(pe), fDst(dst)
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {}
208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    virtual void blitH(int x, int y, int count)
218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    {
228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        fPE->nextSpan(x, y, count, fDst);
238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comprivate:
258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Sk2DPathEffect* fPE;
268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath*         fDst;
278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com};
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////////
308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat)
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
338a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    mat.invert(&fInverse);
348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.combool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width)
378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
388a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    Sk2DPathEffectBlitter   blitter(this, dst);
398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPath                  tmp;
408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkIRect                 ir;
418a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    src.transform(fInverse, &tmp);
43d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    tmp.getBounds().round(&ir);
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!ir.isEmpty()) {
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // need to pass a clip to fillpath, required for inverse filltypes,
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        // even though those do not make sense for this patheffect
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkRegion clip(ir);
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
498a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->begin(ir, dst);
508a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        SkScan::FillPath(tmp, clip, &blitter);
518a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->end(dst);
528a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return true;
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path)
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
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
738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com////////////////////////////////////////////////////////////////////////////////
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comvoid Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer)
768a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
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
838a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer)
848a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
851a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    char storage[SkMatrix::kMaxFlattenSize];
861a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    uint32_t size = buffer.readS32();
871a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    SkASSERT(size <= sizeof(storage));
881a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    buffer.read(storage, size);
891a39493b328d945a000a0690659beb18aa932d3dsenorblanco@chromium.org    fMatrix.unflatten(storage);
908a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    fMatrix.invert(&fInverse);
918a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
938a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable::Factory Sk2DPathEffect::getFactory()
948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
958a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return CreateProc;
968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer)
998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com{
1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return SkNEW_ARGS(Sk2DPathEffect, (buffer));
1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
105