11cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
21cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger/*
31cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Copyright 2006 The Android Open Source Project
41cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger *
51cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * Use of this source code is governed by a BSD-style license that can be
61cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger * found in the LICENSE file.
71cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger */
81cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
90910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
100910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "Sk2DPathEffect.h"
110910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkBlitter.h"
120910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkPath.h"
130910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project#include "SkScan.h"
140910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
150910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectclass Sk2DPathEffectBlitter : public SkBlitter {
160910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectpublic:
170910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk2DPathEffectBlitter(Sk2DPathEffect* pe, SkPath* dst)
181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        : fPE(pe), fDst(dst) {}
191cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
201cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    virtual void blitH(int x, int y, int count) {
210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        fPE->nextSpan(x, y, count, fDst);
220910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
230910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectprivate:
240910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk2DPathEffect* fPE;
250910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPath*         fDst;
260910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project};
270910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
281cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
290910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
301cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
310910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    mat.invert(&fInverse);
320910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
330910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
341cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergerbool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkScalar* width) {
350910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    Sk2DPathEffectBlitter   blitter(this, dst);
360910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPath                  tmp;
370910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkIRect                 ir;
380910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
390910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.transform(fInverse, &tmp);
400e747d6d0a794242bd214fa44a6a179baeadfdf9Mike Reed    tmp.getBounds().round(&ir);
410910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    if (!ir.isEmpty()) {
420910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->begin(ir, dst);
431cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        SkScan::FillPath(tmp, ir, &blitter);
440910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->end(dst);
450910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    }
460910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return true;
470910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
480910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
491cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) {
500910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    const SkMatrix& mat = this->getMatrix();
510910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    SkPoint src, dst;
520910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
530910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
540910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    do {
550910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        mat.mapPoints(&dst, &src, 1);
560910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        this->next(dst, x++, y, path);
570910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project        src.fX += SK_Scalar1;
580910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    } while (--count > 0);
590910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
600910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
610910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {}
620910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {}
630910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Projectvoid Sk2DPathEffect::end(SkPath* dst) {}
640910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
651cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
660910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
671cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
680b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    char storage[SkMatrix::kMaxFlattenSize];
690b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    uint32_t size = fMatrix.flatten(storage);
700b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    buffer.write32(size);
710b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    buffer.write(storage, size);
720910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
730910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
741cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) {
750b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    char storage[SkMatrix::kMaxFlattenSize];
760b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    uint32_t size = buffer.readS32();
770b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    SkASSERT(size <= sizeof(storage));
780b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    buffer.read(storage, size);
790b15698a8c76bb8abc1b555c1d91892669b4118fDerek Sollenberger    fMatrix.unflatten(storage);
800910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    fMatrix.invert(&fInverse);
810910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
820910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
831cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable::Factory Sk2DPathEffect::getFactory() {
840910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return CreateProc;
850910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
860910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
871cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable* Sk2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) {
880910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project    return SkNEW_ARGS(Sk2DPathEffect, (buffer));
890910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project}
900910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
911cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
921cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger///////////////////////////////////////////////////////////////////////////////
931cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
941cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
951cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    : INHERITED(m), fPath(p) {
961cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
971cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
981cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer)
991cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger        : INHERITED(buffer) {
1001cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fPath.unflatten(buffer);
1011cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1021cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1031cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable* SkPath2DPathEffect::CreateProc(SkFlattenableReadBuffer& buffer) {
1041cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return SkNEW_ARGS(SkPath2DPathEffect, (buffer));
1051cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1061cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1071cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
1081cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    this->INHERITED::flatten(buffer);
1091cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    fPath.flatten(buffer);
1101cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1111cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1121cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSkFlattenable::Factory SkPath2DPathEffect::getFactory() {
1131cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    return CreateProc;
1141cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1151cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger
1161cab2921ab279367f8206cdadc9259d12e603548Derek Sollenbergervoid SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {
1171cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger    dst->addPath(fPath, loc.fX, loc.fY);
1181cab2921ab279367f8206cdadc9259d12e603548Derek Sollenberger}
1190910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
1201cab2921ab279367f8206cdadc9259d12e603548Derek SollenbergerSK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect)
1210910916c0f7b951ee55c4b7c6358295b9bca0565The Android Open Source Project
122