Sk2DPathEffect.cpp revision 6db9375b4f695c68a4e56e38bcd70f983440c2d5
15d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
25d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)/*
35d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Copyright 2006 The Android Open Source Project
45d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) *
55d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * Use of this source code is governed by a BSD-style license that can be
65d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) * found in the LICENSE file.
75d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) */
85d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
95d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
105d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "Sk2DPathEffect.h"
115d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)#include "SkFlattenableBuffers.h"
12effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch#include "SkPath.h"
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)#include "SkRegion.h"
145d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
155d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
165d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fMatrixIsInvertible = mat.invert(&fInverse);
1703b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles)}
185d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
195d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)bool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src, SkStrokeRec*) {
205d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!fMatrixIsInvertible) {
211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci        return false;
225d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    }
235d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
24effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SkPath  tmp;
25effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    SkIRect ir;
265d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
275d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    src.transform(fInverse, &tmp);
285d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    tmp.getBounds().round(&ir);
295d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    if (!ir.isEmpty()) {
305d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        this->begin(ir, dst);
315d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
325d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        SkRegion rgn;
335d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        rgn.setPath(tmp, SkRegion(ir));
34cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        SkRegion::Iterator iter(rgn);
35cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        for (; !iter.done(); iter.next()) {
36cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            const SkIRect& rect = iter.rect();
37cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            for (int y = rect.fTop; y < rect.fBottom; ++y) {
38cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)                this->nextSpan(rect.fLeft, y, rect.width(), dst);
39cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)            }
40cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        }
41cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
42cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this->end(dst);
43cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
44cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    return true;
45cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
46cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
47cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) {
4846d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)    if (!fMatrixIsInvertible) {
4946d4c2bc3267f3f028f39e7e311b0f89aba2e4fdTorne (Richard Coles)        return;
50cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    }
51cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
52cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    const SkMatrix& mat = this->getMatrix();
53cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    SkPoint src, dst;
54cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
55cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
56cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    do {
57cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        mat.mapPoints(&dst, &src, 1);
58cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        this->next(dst, x++, y, path);
59cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        src.fX += SK_Scalar1;
60cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    } while (--count > 0);
61cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)}
62cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
63cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) {}
64cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {}
65cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Sk2DPathEffect::end(SkPath* dst) {}
66cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
67cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
68cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)
69cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)void Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
70cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)    this->INHERITED::flatten(buffer);
71effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    buffer.writeMatrix(fMatrix);
72effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
73effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
745d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)Sk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) {
755d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    buffer.readMatrix(&fMatrix);
765d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    fMatrixIsInvertible = fMatrix.invert(&fInverse);
775d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
785d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
795d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
80effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch///////////////////////////////////////////////////////////////////////////////
815d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
825d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
83effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    : INHERITED(m), fPath(p) {
845d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
865d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer)
875d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)        : INHERITED(buffer) {
885d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    buffer.readPath(&fPath);
895d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)}
905d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
91effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
92effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    this->INHERITED::flatten(buffer);
93effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    buffer.writePath(fPath);
94effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
95effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
96effb81e5f8246d0db0270817048dc992db66e9fbBen Murdochvoid SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) {
97effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    dst->addPath(fPath, loc.fX, loc.fY);
98effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch}
99effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
1005d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)///////////////////////////////////////////////////////////////////////////////
1015d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)
1025d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)SK_DEFINE_FLATTENABLE_REGISTRAR(SkPath2DPathEffect)
1035d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)