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 16 SkPairPathEffect::SkPairPathEffect(SkPathEffect* pe0, SkPathEffect* pe1) 17 : fPE0(pe0), fPE1(pe1) { 18 SkASSERT(pe0); 19 SkASSERT(pe1); 20 fPE0->ref(); 21 fPE1->ref(); 22 } 23 24 SkPairPathEffect::~SkPairPathEffect() { 25 SkSafeUnref(fPE0); 26 SkSafeUnref(fPE1); 27 } 28 29 /* 30 Format: [oe0-factory][pe1-factory][pe0-size][pe0-data][pe1-data] 31 */ 32 void SkPairPathEffect::flatten(SkFlattenableWriteBuffer& buffer) { 33 buffer.writeFlattenable(fPE0); 34 buffer.writeFlattenable(fPE1); 35 } 36 37 SkPairPathEffect::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 45 bool 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 63 bool 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 73 SkStrokePathEffect::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 79 SkStrokePathEffect::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 88 bool 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 111 SkFlattenable::Factory SkStrokePathEffect::getFactory() { 112 return CreateProc; 113 } 114 115 SkFlattenable* SkStrokePathEffect::CreateProc(SkFlattenableReadBuffer& buffer) { 116 return SkNEW_ARGS(SkStrokePathEffect, (buffer)); 117 } 118 119 void 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 127 SkStrokePathEffect::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 137 SK_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) 141 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 142 143