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"
118b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkReadBuffer.h"
128b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.org#include "SkWriteBuffer.h"
138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h"
146db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com#include "SkRegion.h"
158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
1616edff2b1cbd80e36456138f8631711a585205bareed@google.comSk2DPathEffect::Sk2DPathEffect(const SkMatrix& mat) : fMatrix(mat) {
1790bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    fMatrixIsInvertible = mat.invert(&fInverse);
188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
20548a1f321011292359ef163f78c8a1d4871b3b7freed@google.combool Sk2DPathEffect::filterPath(SkPath* dst, const SkPath& src,
214bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com                                SkStrokeRec*, const SkRect*) const {
2290bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    if (!fMatrixIsInvertible) {
2390bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org        return false;
2490bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    }
2590bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org
266db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com    SkPath  tmp;
276db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com    SkIRect ir;
288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    src.transform(fInverse, &tmp);
30d252db03d9650013b545ef9781fe993c07f8f314reed@android.com    tmp.getBounds().round(&ir);
318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    if (!ir.isEmpty()) {
328a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->begin(ir, dst);
336db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com
346db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com        SkRegion rgn;
356db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com        rgn.setPath(tmp, SkRegion(ir));
366db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com        SkRegion::Iterator iter(rgn);
376db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com        for (; !iter.done(); iter.next()) {
386db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com            const SkIRect& rect = iter.rect();
396db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com            for (int y = rect.fTop; y < rect.fBottom; ++y) {
406db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com                this->nextSpan(rect.fLeft, y, rect.width(), dst);
416db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com            }
426db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com        }
436db9375b4f695c68a4e56e38bcd70f983440c2d5reed@google.com
448a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->end(dst);
458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    }
468a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    return true;
478a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
488a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
49548a1f321011292359ef163f78c8a1d4871b3b7freed@google.comvoid Sk2DPathEffect::nextSpan(int x, int y, int count, SkPath* path) const {
5090bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    if (!fMatrixIsInvertible) {
5190bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org        return;
5290bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    }
5390bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org
548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    const SkMatrix& mat = this->getMatrix();
558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    SkPoint src, dst;
568a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    src.set(SkIntToScalar(x) + SK_ScalarHalf, SkIntToScalar(y) + SK_ScalarHalf);
588a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    do {
598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        mat.mapPoints(&dst, &src, 1);
608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        this->next(dst, x++, y, path);
618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com        src.fX += SK_Scalar1;
628a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com    } while (--count > 0);
638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
648a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
65548a1f321011292359ef163f78c8a1d4871b3b7freed@google.comvoid Sk2DPathEffect::begin(const SkIRect& uvBounds, SkPath* dst) const {}
66548a1f321011292359ef163f78c8a1d4871b3b7freed@google.comvoid Sk2DPathEffect::next(const SkPoint& loc, int u, int v, SkPath* dst) const {}
67548a1f321011292359ef163f78c8a1d4871b3b7freed@google.comvoid Sk2DPathEffect::end(SkPath* dst) const {}
688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
6916edff2b1cbd80e36456138f8631711a585205bareed@google.com///////////////////////////////////////////////////////////////////////////////
708a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
718b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid Sk2DPathEffect::flatten(SkWriteBuffer& buffer) const {
7254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com    this->INHERITED::flatten(buffer);
73d2700eec7eb2e26beb206b88a0f0b6f3c5f49118djsollen@google.com    buffer.writeMatrix(fMatrix);
748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
768b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSk2DPathEffect::Sk2DPathEffect(SkReadBuffer& buffer) {
77d2700eec7eb2e26beb206b88a0f0b6f3c5f49118djsollen@google.com    buffer.readMatrix(&fMatrix);
7890bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org    fMatrixIsInvertible = fMatrix.invert(&fInverse);
798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com}
808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com
81e28b917669fc4677b2f1c0a08c4711b651cbf1a1reed@google.com///////////////////////////////////////////////////////////////////////////////
82d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
83548a1f321011292359ef163f78c8a1d4871b3b7freed@google.combool SkLine2DPathEffect::filterPath(SkPath* dst, const SkPath& src,
844bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com                            SkStrokeRec* rec, const SkRect* cullRect) const {
854bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com    if (this->INHERITED::filterPath(dst, src, rec, cullRect)) {
86d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com        rec->setStrokeStyle(fWidth);
87d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com        return true;
88d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com    }
89d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com    return false;
90d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com}
91d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
92548a1f321011292359ef163f78c8a1d4871b3b7freed@google.comvoid SkLine2DPathEffect::nextSpan(int u, int v, int ucount, SkPath* dst) const {
93d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com    if (ucount > 1) {
94d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com        SkPoint    src[2], dstP[2];
95d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
96d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com        src[0].set(SkIntToScalar(u) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
97d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com        src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf);
98d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com        this->getMatrix().mapPoints(dstP, src, 2);
99d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
100d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com        dst->moveTo(dstP[0]);
101d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com        dst->lineTo(dstP[1]);
102d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com    }
103d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com}
104d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
1058b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkLine2DPathEffect::SkLine2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) {
106d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com    fWidth = buffer.readScalar();
107d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com}
108d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
1098b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkLine2DPathEffect::flatten(SkWriteBuffer &buffer) const {
110d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com    this->INHERITED::flatten(buffer);
111d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com    buffer.writeScalar(fWidth);
112d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com}
113d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com
11418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com///////////////////////////////////////////////////////////////////////////////
11518dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
11618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comSkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p)
11718dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com    : INHERITED(m), fPath(p) {
11818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com}
11918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
1208b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkPath2DPathEffect::SkPath2DPathEffect(SkReadBuffer& buffer)
12118dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com        : INHERITED(buffer) {
1222b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    buffer.readPath(&fPath);
12318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com}
12418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
1258b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPath2DPathEffect::flatten(SkWriteBuffer& buffer) const {
12618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com    this->INHERITED::flatten(buffer);
1272b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com    buffer.writePath(fPath);
12818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com}
12918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com
130548a1f321011292359ef163f78c8a1d4871b3b7freed@google.comvoid SkPath2DPathEffect::next(const SkPoint& loc, int u, int v,
131548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com                              SkPath* dst) const {
13218dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com    dst->addPath(fPath, loc.fX, loc.fY);
13318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com}
134