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 769fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 778b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSk2DPathEffect::Sk2DPathEffect(SkReadBuffer& buffer) { 78d2700eec7eb2e26beb206b88a0f0b6f3c5f49118djsollen@google.com buffer.readMatrix(&fMatrix); 7990bf427001fd4f6d9fcee88911deb015aeb4ab7cmike@reedtribe.org fMatrixIsInvertible = fMatrix.invert(&fInverse); 808a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 819fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 828a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 83e28b917669fc4677b2f1c0a08c4711b651cbf1a1reed@google.com/////////////////////////////////////////////////////////////////////////////// 84d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com 85548a1f321011292359ef163f78c8a1d4871b3b7freed@google.combool SkLine2DPathEffect::filterPath(SkPath* dst, const SkPath& src, 864bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com SkStrokeRec* rec, const SkRect* cullRect) const { 874bbdeac58cc928dc66296bde3bd06e78070d96b7reed@google.com if (this->INHERITED::filterPath(dst, src, rec, cullRect)) { 88d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com rec->setStrokeStyle(fWidth); 89d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com return true; 90d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com } 91d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com return false; 92d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com} 93d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com 94548a1f321011292359ef163f78c8a1d4871b3b7freed@google.comvoid SkLine2DPathEffect::nextSpan(int u, int v, int ucount, SkPath* dst) const { 95d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com if (ucount > 1) { 96d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com SkPoint src[2], dstP[2]; 97d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com 98d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com src[0].set(SkIntToScalar(u) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf); 99d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com src[1].set(SkIntToScalar(u+ucount) + SK_ScalarHalf, SkIntToScalar(v) + SK_ScalarHalf); 100d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com this->getMatrix().mapPoints(dstP, src, 2); 101d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com 102d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com dst->moveTo(dstP[0]); 103d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com dst->lineTo(dstP[1]); 104d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com } 105d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com} 106d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com 1079fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 1088b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgSkLine2DPathEffect::SkLine2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { 109d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com fWidth = buffer.readScalar(); 110d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com} 1119fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 1129fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 1139fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkLine2DPathEffect::CreateProc(SkReadBuffer& buffer) { 1149fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkMatrix matrix; 1159fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.readMatrix(&matrix); 1169fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkScalar width = buffer.readScalar(); 1179fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkLine2DPathEffect::Create(width, matrix); 1189fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 119d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com 1208b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkLine2DPathEffect::flatten(SkWriteBuffer &buffer) const { 1219fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.writeMatrix(this->getMatrix()); 122d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com buffer.writeScalar(fWidth); 123d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com} 124d8a6cc814f1a0a8faaddad05ae765ad2f6b11aacscroggo@google.com 12518dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com/////////////////////////////////////////////////////////////////////////////// 12618dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 12718dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.comSkPath2DPathEffect::SkPath2DPathEffect(const SkMatrix& m, const SkPath& p) 12818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com : INHERITED(m), fPath(p) { 12918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 13018dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 1319fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#ifdef SK_SUPPORT_LEGACY_DEEPFLATTENING 1329fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkPath2DPathEffect::SkPath2DPathEffect(SkReadBuffer& buffer) : INHERITED(buffer) { 1332b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com buffer.readPath(&fPath); 13418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 1359fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed#endif 1369fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed 1379fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reedSkFlattenable* SkPath2DPathEffect::CreateProc(SkReadBuffer& buffer) { 1389fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkMatrix matrix; 1399fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.readMatrix(&matrix); 1409fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed SkPath path; 1419fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.readPath(&path); 1429fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed return SkPath2DPathEffect::Create(matrix, path); 1439fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed} 14418dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 1458b0e8ac5f582de80356019406e2975079bf0829dcommit-bot@chromium.orgvoid SkPath2DPathEffect::flatten(SkWriteBuffer& buffer) const { 1469fa60daad4d5f54c0dbe3dbcc7608a8f6d721187reed buffer.writeMatrix(this->getMatrix()); 1472b2ede3e713065e1bac461787b0aafb03eaf871fdjsollen@google.com buffer.writePath(fPath); 14818dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 14918dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com 150548a1f321011292359ef163f78c8a1d4871b3b7freed@google.comvoid SkPath2DPathEffect::next(const SkPoint& loc, int u, int v, 151548a1f321011292359ef163f78c8a1d4871b3b7freed@google.com SkPath* dst) const { 15218dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com dst->addPath(fPath, loc.fX, loc.fY); 15318dc47731f4b37d8896b51f1b92ab31abd78b5a0reed@google.com} 154