/*
 * Copyright 2006 The Android Open Source Project
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */


#include "include/core/SkPath.h"
#include "include/core/SkRegion.h"
#include "include/core/SkStrokeRec.h"
#include "include/effects/Sk2DPathEffect.h"
#include "src/core/SkReadBuffer.h"
#include "src/core/SkWriteBuffer.h"

Sk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
    // Calling invert will set the type mask on both matrices, making them thread safe.
    fMatrixIsInvertible = fMatrix.invert(&fInverse);
}

bool Sk2DPathEffect::onFilterPath(SkPath* dst, const SkPath& src,
                                  SkStrokeRec*, const SkRect*) const {
    if (!fMatrixIsInvertible) {
        return false;
    }

    SkPath  tmp;
    SkIRect ir;

    src.transform(fInverse, &tmp);
    tmp.getBounds().round(&ir);
    if (!ir.isEmpty()) {
        this->begin(ir, dst);

        SkRegion rgn;
        rgn.setPath(tmp, SkRegion(ir));
        SkRegion::Iterator iter(rgn);
        for (; !iter.done(); iter.next()) {
            const SkIRect& rect = iter.rect();
            for (int y = rect.fTop; y < rect.fBottom; ++y) {
                this->nextSpan(rect.fLeft, y, rect.width(), dst);
            }
        }

        this->end(dst);
    }
    return true;
}

void Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) const {
    if (!fMatrixIsInvertible) {
        return;
    }

    const SkMatrix& mat = this->getMatrix();
    SkPoint src, dst;

    src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
    do {
        mat.mapPoints(&dst, &src, 1);
        this->next(dst, x++, y, path);
        src.fX += SK_Scalar1;
    } while (--count > 0);
}

void Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) const {}
void Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) const {}
void Sk2DPathEffect::end(SkPath* dst) const {}

///////////////////////////////////////////////////////////////////////////////

void Sk2DPathEffect::flatten(SkWriteBuffer& buffer) const {
    this->INHERITED::flatten(buffer);
    buffer.writeMatrix(fMatrix);
}

///////////////////////////////////////////////////////////////////////////////

bool SkLine2DPathEffect::onFilterPath(SkPath* dst, const SkPath& src,
                                      SkStrokeRec* rec, const SkRect* cullRect) const {
    if (this->INHERITED::onFilterPath(dst, src, rec, cullRect)) {
        rec->setStrokeStyle(fWidth);
        return true;
    }
    return false;
}

void SkLine2DPathEffect::nextSpan(int u, int v, int ucount, SkPath* dst) const {
    if (ucount > 1) {
        SkPoint    src[2], dstP[2];

        src[0].set(SkIntToScalar(u) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
        src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
        this->getMatrix().mapPoints(dstP, src, 2);

        dst->moveTo(dstP[0]);
        dst->lineTo(dstP[1]);
    }
}

sk_sp<SkFlattenable> SkLine2DPathEffect::CreateProc(SkReadBuffer& buffer) {
    SkMatrix matrix;
    buffer.readMatrix(&matrix);
    SkScalar width = buffer.readScalar();
    return SkLine2DPathEffect::Make(width, matrix);
}

void SkLine2DPathEffect::flatten(SkWriteBuffer &buffer) const {
    buffer.writeMatrix(this->getMatrix());
    buffer.writeScalar(fWidth);
}

///////////////////////////////////////////////////////////////////////////////

SkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
    : INHERITED(m), fPath(p) {
}

sk_sp<SkFlattenable> SkPath2DPathEffect::CreateProc(SkReadBuffer& buffer) {
    SkMatrix matrix;
    buffer.readMatrix(&matrix);
    SkPath path;
    buffer.readPath(&path);
    return SkPath2DPathEffect::Make(matrix, path);
}

void SkPath2DPathEffect::flatten(SkWriteBuffer& buffer) const {
    buffer.writeMatrix(this->getMatrix());
    buffer.writePath(fPath);
}

void SkPath2DPathEffect::next(const SkPoint& loc, int u, int v,
                              SkPath* dst) const {
    dst->addPath(fPath, loc.fX, loc.fY);
}
