SkPathEffect.cpp revision 54924243c1b65b3ee6d8fa064b50a9b1bb2a19a5
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 "SkPathEffect.h" 118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkPath.h" 128a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkBuffer.h" 138a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 14feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com/////////////////////////////////////////////////////////////////////////////// 158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkPairPathEffect::SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1) 17feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com : fPE0(pe0), fPE1(pe1) { 188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pe0); 198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkASSERT(pe1); 208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPE0->ref(); 218a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPE1->ref(); 228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 24feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comSkPairPathEffect::~SkPairPathEffect() { 256bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com SkSafeUnref(fPE0); 266bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com SkSafeUnref(fPE1); 278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 298a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com/* 308a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com Format: [oe0-factory][pe1-factory][pe0-size][pe0-data][pe1-data] 318a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com*/ 3254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comvoid SkPairPathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { 3354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com this->INHERITED::flatten(buffer); 348a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeFlattenable(fPE0); 358a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeFlattenable(fPE1); 368a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 378a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 38feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comSkPairPathEffect::SkPairPathEffect(SkFlattenableReadBuffer& buffer) { 398a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPE0 = (SkPathEffect*)buffer.readFlattenable(); 408a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fPE1 = (SkPathEffect*)buffer.readFlattenable(); 416bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // either of these may fail, so we have to check for nulls later on 428a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 438a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 44feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com/////////////////////////////////////////////////////////////////////////////// 458a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 46feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.combool SkComposePathEffect::filterPath(SkPath* dst, const SkPath& src, 47feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com SkScalar* width) { 486bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com // we may have failed to unflatten these, so we have to check 496bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com if (!fPE0 || !fPE1) { 506bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com return false; 516bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com } 526bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com 538a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkPath tmp; 548a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com const SkPath* ptr = &src; 558a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 56feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com if (fPE1->filterPath(&tmp, src, width)) { 578a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com ptr = &tmp; 58feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com } 598a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fPE0->filterPath(dst, *ptr, width); 608a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 618a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 62feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com/////////////////////////////////////////////////////////////////////////////// 638a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 64feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.combool SkSumPathEffect::filterPath(SkPath* dst, const SkPath& src, 65feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com SkScalar* width) { 668a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com // use bit-or so that we always call both, even if the first one succeeds 678a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return fPE0->filterPath(dst, src, width) | fPE1->filterPath(dst, src, width); 688a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 698a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 70feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com/////////////////////////////////////////////////////////////////////////////// 718a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 728a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com#include "SkStroke.h" 738a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 748a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.comSkStrokePathEffect::SkStrokePathEffect(const SkPaint& paint) 758a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com : fWidth(paint.getStrokeWidth()), fMiter(paint.getStrokeMiter()), 76feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com fStyle(SkToU8(paint.getStyle())), fJoin(SkToU8(paint.getStrokeJoin())), 77feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com fCap(SkToU8(paint.getStrokeCap())) { 788a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 798a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 80feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comSkStrokePathEffect::SkStrokePathEffect(SkScalar width, SkPaint::Style style, 81feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com SkPaint::Join join, SkPaint::Cap cap, SkScalar miter) 82feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com : fWidth(width), fMiter(miter), fStyle(SkToU8(style)), 83feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com fJoin(SkToU8(join)), fCap(SkToU8(cap)) { 84feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com if (miter < 0) { // signal they want the default 85aefdd062717dd6182e0f87d727c807af4314d445reed@google.com fMiter = SkIntToScalar(4); 86feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com } 878a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 888a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 89feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.combool SkStrokePathEffect::filterPath(SkPath* dst, const SkPath& src, 90feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com SkScalar* width) { 91feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com if (fWidth < 0 || fStyle == SkPaint::kFill_Style) { 928a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return false; 93feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com } 948a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 95feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.com if (fStyle == SkPaint::kStroke_Style && fWidth == 0) { // hairline 968a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com *width = 0; 978a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 988a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com } 998a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1008a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com SkStroke stroke; 1018a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1028a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stroke.setWidth(fWidth); 1038a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stroke.setMiterLimit(fMiter); 1048a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stroke.setJoin((SkPaint::Join)fJoin); 1058a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stroke.setCap((SkPaint::Cap)fCap); 1068a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stroke.setDoFill(fStyle == SkPaint::kStrokeAndFill_Style); 1078a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1088a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com stroke.strokePath(src, dst); 1098a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com return true; 1108a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1118a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 11254924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.comvoid SkStrokePathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { 11354924243c1b65b3ee6d8fa064b50a9b1bb2a19a5djsollen@google.com this->INHERITED::flatten(buffer); 1148a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeScalar(fWidth); 1158a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.writeScalar(fMiter); 1168a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.write8(fStyle); 1178a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.write8(fJoin); 1188a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com buffer.write8(fCap); 1198a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1208a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 121feb8cc870df055099c6fcdfebdd6c1486bd91b27reed@google.comSkStrokePathEffect::SkStrokePathEffect(SkFlattenableReadBuffer& buffer) { 1228a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fWidth = buffer.readScalar(); 1238a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fMiter = buffer.readScalar(); 1248a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fStyle = buffer.readU8(); 1258a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fJoin = buffer.readU8(); 1268a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com fCap = buffer.readU8(); 1278a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com} 1288a1c16ff38322f0210116fa7293eb8817c7e477ereed@android.com 1296bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com/////////////////////////////////////////////////////////////////////////////// 1306bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com 131a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.comSK_DEFINE_FLATTENABLE_REGISTRAR(SkComposePathEffect) 132a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.comSK_DEFINE_FLATTENABLE_REGISTRAR(SkStrokePathEffect) 133a2ca41e3afdd8fad5e0e924dec029f33918e0a67djsollen@google.comSK_DEFINE_FLATTENABLE_REGISTRAR(SkSumPathEffect) 1346bac947cd5bc460dd9166ada6310d678fd2e39f8reed@google.com 135