180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru/*
380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Copyright 2006 The Android Open Source Project
480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru *
580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * Use of this source code is governed by a BSD-style license that can be
680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru * found in the LICENSE file.
780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru */
880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "Sk2DPathEffect.h"
1180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkFlattenableBuffers.h"
1280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkPath.h"
1380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru#include "SkRegion.h"
1480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
1580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
1680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMatrixIsInvertible = mat.invert(&fInverse);
1780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
1880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
19363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src,
20d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                                SkStrokeRec*, const SkRect*) const {
2180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!fMatrixIsInvertible) {
2280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return false;
2380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
2480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPath  tmp;
2680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkIRect ir;
2780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
2880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    src.transform(fInverse, &tmp);
2980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    tmp.getBounds().round(&ir);
3080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!ir.isEmpty()) {
3180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->begin(ir, dst);
3280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
3380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkRegion rgn;
3480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        rgn.setPath(tmp, SkRegion(ir));
3580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkRegion::Iterator iter(rgn);
3680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        for (; !iter.done(); iter.next()) {
3780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            const SkIRect& rect = iter.rect();
3880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            for (int y = rect.fTop; y < rect.fBottom; ++y) {
3980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru                this->nextSpan(rect.fLeft, y, rect.width(), dst);
4080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru            }
4180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        }
4280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
4380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->end(dst);
4480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
4580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return true;
4680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
4780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
48363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) const {
4980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (!fMatrixIsInvertible) {
5080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return;
5180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
5280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    const SkMatrix& mat = this->getMatrix();
5480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    SkPoint src, dst;
5580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
5680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
5780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    do {
5880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        mat.mapPoints(&dst, &src, 1);
5980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->next(dst, x++, y, path);
6080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        src.fX += SK_Scalar1;
6180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    } while (--count > 0);
6280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
6380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
64363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) const {}
65363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) const {}
66363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid Sk2DPathEffect::end(SkPath* dst) const {}
6780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
6880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
6980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid Sk2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
7180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->INHERITED::flatten(buffer);
7280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.writeMatrix(fMatrix);
7380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
7580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSk2DPathEffect::Sk2DPathEffect(SkFlattenableReadBuffer& buffer) {
7680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.readMatrix(&fMatrix);
7780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fMatrixIsInvertible = fMatrix.invert(&fInverse);
7880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
7980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
8080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
8180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
82363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergerbool SkLine2DPathEffect::filterPath(SkPath* dst, const SkPath& src,
83d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger                            SkStrokeRec* rec, const SkRect* cullRect) const {
84d686ac77c2c485c4a3302eda9c1de597a6f8c568Derek Sollenberger    if (this->INHERITED::filterPath(dst, src, rec, cullRect)) {
8580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        rec->setStrokeStyle(fWidth);
8680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        return true;
8780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
8880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    return false;
8980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
9080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
91363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkLine2DPathEffect::nextSpan(int u, int v, int ucount, SkPath* dst) const {
9280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    if (ucount > 1) {
9380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        SkPoint    src[2], dstP[2];
9480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        src[0].set(SkIntToScalar(u) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
9680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
9780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        this->getMatrix().mapPoints(dstP, src, 2);
9880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
9980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dst->moveTo(dstP[0]);
10080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        dst->lineTo(dstP[1]);
10180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    }
10280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkLine2DPathEffect::SkLine2DPathEffect(SkFlattenableReadBuffer& buffer) : INHERITED(buffer) {
10580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    fWidth = buffer.readScalar();
10680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
10780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
10880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkLine2DPathEffect::flatten(SkFlattenableWriteBuffer &buffer) const {
10980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->INHERITED::flatten(buffer);
11080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.writeScalar(fWidth);
11180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru///////////////////////////////////////////////////////////////////////////////
11480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
11680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    : INHERITED(m), fPath(p) {
11780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
11880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
11980bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste QueruSkPath2DPathEffect::SkPath2DPathEffect(SkFlattenableReadBuffer& buffer)
12080bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru        : INHERITED(buffer) {
12180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.readPath(&fPath);
12280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12380bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
12480bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queruvoid SkPath2DPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const {
12580bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    this->INHERITED::flatten(buffer);
12680bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    buffer.writePath(fPath);
12780bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
12880bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru
129363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenbergervoid SkPath2DPathEffect::next(const SkPoint& loc, int u, int v,
130363e546ed626b6dbbc42f5db87b3594bc0b5944bDerek Sollenberger                              SkPath* dst) const {
13180bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru    dst->addPath(fPath, loc.fX, loc.fY);
13280bacfeb4bda06541e8695bd502229727bccfeaJean-Baptiste Queru}
133