1 2/* 3 * Copyright 2006 The Android Open Source Project 4 * 5 * Use of this source code is governed by a BSD-style license that can be 6 * found in the LICENSE file. 7 */ 8 9 10#include "SkPathEffect.h" 11#include "SkPath.h" 12#include "SkBuffer.h" 13 14/////////////////////////////////////////////////////////////////////////////// 15 16SkPairPathEffect::SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1) 17 : fPE0(pe0), fPE1(pe1) { 18 SkASSERT(pe0); 19 SkASSERT(pe1); 20 fPE0->ref(); 21 fPE1->ref(); 22} 23 24SkPairPathEffect::~SkPairPathEffect() { 25 SkSafeUnref(fPE0); 26 SkSafeUnref(fPE1); 27} 28 29/* 30 Format: [oe0-factory][pe1-factory][pe0-size][pe0-data][pe1-data] 31*/ 32void SkPairPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 33 buffer.writeFlattenable(fPE0); 34 buffer.writeFlattenable(fPE1); 35} 36 37SkPairPathEffect::SkPairPathEffect(SkFlattenableReadBuffer& buffer) { 38 fPE0 = (SkPathEffect*)buffer.readFlattenable(); 39 fPE1 = (SkPathEffect*)buffer.readFlattenable(); 40 // either of these may fail, so we have to check for nulls later on 41} 42 43/////////////////////////////////////////////////////////////////////////////// 44 45bool SkComposePathEffect::filterPath(SkPath* dst, const SkPath& src, 46 SkScalar* width) { 47 // we may have failed to unflatten these, so we have to check 48 if (!fPE0 || !fPE1) { 49 return false; 50 } 51 52 SkPath tmp; 53 const SkPath* ptr = &src; 54 55 if (fPE1->filterPath(&tmp, src, width)) { 56 ptr = &tmp; 57 } 58 return fPE0->filterPath(dst, *ptr, width); 59} 60 61/////////////////////////////////////////////////////////////////////////////// 62 63bool SkSumPathEffect::filterPath(SkPath* dst, const SkPath& src, 64 SkScalar* width) { 65 // use bit-or so that we always call both, even if the first one succeeds 66 return fPE0->filterPath(dst, src, width) | fPE1->filterPath(dst, src, width); 67} 68 69/////////////////////////////////////////////////////////////////////////////// 70 71#include "SkStroke.h" 72 73SkStrokePathEffect::SkStrokePathEffect(const SkPaint& paint) 74 : fWidth(paint.getStrokeWidth()), fMiter(paint.getStrokeMiter()), 75 fStyle(SkToU8(paint.getStyle())), fJoin(SkToU8(paint.getStrokeJoin())), 76 fCap(SkToU8(paint.getStrokeCap())) { 77} 78 79SkStrokePathEffect::SkStrokePathEffect(SkScalar width, SkPaint::Style style, 80 SkPaint::Join join, SkPaint::Cap cap, SkScalar miter) 81 : fWidth(width), fMiter(miter), fStyle(SkToU8(style)), 82 fJoin(SkToU8(join)), fCap(SkToU8(cap)) { 83 if (miter < 0) { // signal they want the default 84 fMiter = SkIntToScalar(4); 85 } 86} 87 88bool SkStrokePathEffect::filterPath(SkPath* dst, const SkPath& src, 89 SkScalar* width) { 90 if (fWidth < 0 || fStyle == SkPaint::kFill_Style) { 91 return false; 92 } 93 94 if (fStyle == SkPaint::kStroke_Style && fWidth == 0) { // hairline 95 *width = 0; 96 return true; 97 } 98 99 SkStroke stroke; 100 101 stroke.setWidth(fWidth); 102 stroke.setMiterLimit(fMiter); 103 stroke.setJoin((SkPaint::Join)fJoin); 104 stroke.setCap((SkPaint::Cap)fCap); 105 stroke.setDoFill(fStyle == SkPaint::kStrokeAndFill_Style); 106 107 stroke.strokePath(src, dst); 108 return true; 109} 110 111SkFlattenable::Factory SkStrokePathEffect::getFactory() { 112 return CreateProc; 113} 114 115SkFlattenable* SkStrokePathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 116 return SkNEW_ARGS(SkStrokePathEffect, (buffer)); 117} 118 119void SkStrokePathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 120 buffer.writeScalar(fWidth); 121 buffer.writeScalar(fMiter); 122 buffer.write8(fStyle); 123 buffer.write8(fJoin); 124 buffer.write8(fCap); 125} 126 127SkStrokePathEffect::SkStrokePathEffect(SkFlattenableReadBuffer& buffer) { 128 fWidth = buffer.readScalar(); 129 fMiter = buffer.readScalar(); 130 fStyle = buffer.readU8(); 131 fJoin = buffer.readU8(); 132 fCap = buffer.readU8(); 133} 134 135/////////////////////////////////////////////////////////////////////////////// 136 137SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkPathEffect) 138 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkComposePathEffect) 139 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkStrokePathEffect) 140 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkSumPathEffect) 141SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 142 143