SkPathEffect.cpp revision 54924243c1b65b3ee6d8fa064b50a9b1bb2a19a5
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) const { 33 this->INHERITED::flatten(buffer); 34 buffer.writeFlattenable(fPE0); 35 buffer.writeFlattenable(fPE1); 36} 37 38SkPairPathEffect::SkPairPathEffect(SkFlattenableReadBuffer& buffer) { 39 fPE0 = (SkPathEffect*)buffer.readFlattenable(); 40 fPE1 = (SkPathEffect*)buffer.readFlattenable(); 41 // either of these may fail, so we have to check for nulls later on 42} 43 44/////////////////////////////////////////////////////////////////////////////// 45 46bool SkComposePathEffect::filterPath(SkPath* dst, const SkPath& src, 47 SkScalar* width) { 48 // we may have failed to unflatten these, so we have to check 49 if (!fPE0 || !fPE1) { 50 return false; 51 } 52 53 SkPath tmp; 54 const SkPath* ptr = &src; 55 56 if (fPE1->filterPath(&tmp, src, width)) { 57 ptr = &tmp; 58 } 59 return fPE0->filterPath(dst, *ptr, width); 60} 61 62/////////////////////////////////////////////////////////////////////////////// 63 64bool SkSumPathEffect::filterPath(SkPath* dst, const SkPath& src, 65 SkScalar* width) { 66 // use bit-or so that we always call both, even if the first one succeeds 67 return fPE0->filterPath(dst, src, width) | fPE1->filterPath(dst, src, width); 68} 69 70/////////////////////////////////////////////////////////////////////////////// 71 72#include "SkStroke.h" 73 74SkStrokePathEffect::SkStrokePathEffect(const SkPaint& paint) 75 : fWidth(paint.getStrokeWidth()), fMiter(paint.getStrokeMiter()), 76 fStyle(SkToU8(paint.getStyle())), fJoin(SkToU8(paint.getStrokeJoin())), 77 fCap(SkToU8(paint.getStrokeCap())) { 78} 79 80SkStrokePathEffect::SkStrokePathEffect(SkScalar width, SkPaint::Style style, 81 SkPaint::Join join, SkPaint::Cap cap, SkScalar miter) 82 : fWidth(width), fMiter(miter), fStyle(SkToU8(style)), 83 fJoin(SkToU8(join)), fCap(SkToU8(cap)) { 84 if (miter < 0) { // signal they want the default 85 fMiter = SkIntToScalar(4); 86 } 87} 88 89bool SkStrokePathEffect::filterPath(SkPath* dst, const SkPath& src, 90 SkScalar* width) { 91 if (fWidth < 0 || fStyle == SkPaint::kFill_Style) { 92 return false; 93 } 94 95 if (fStyle == SkPaint::kStroke_Style && fWidth == 0) { // hairline 96 *width = 0; 97 return true; 98 } 99 100 SkStroke stroke; 101 102 stroke.setWidth(fWidth); 103 stroke.setMiterLimit(fMiter); 104 stroke.setJoin((SkPaint::Join)fJoin); 105 stroke.setCap((SkPaint::Cap)fCap); 106 stroke.setDoFill(fStyle == SkPaint::kStrokeAndFill_Style); 107 108 stroke.strokePath(src, dst); 109 return true; 110} 111 112void SkStrokePathEffect::flatten(SkFlattenableWriteBuffer& buffer) const { 113 this->INHERITED::flatten(buffer); 114 buffer.writeScalar(fWidth); 115 buffer.writeScalar(fMiter); 116 buffer.write8(fStyle); 117 buffer.write8(fJoin); 118 buffer.write8(fCap); 119} 120 121SkStrokePathEffect::SkStrokePathEffect(SkFlattenableReadBuffer& buffer) { 122 fWidth = buffer.readScalar(); 123 fMiter = buffer.readScalar(); 124 fStyle = buffer.readU8(); 125 fJoin = buffer.readU8(); 126 fCap = buffer.readU8(); 127} 128 129/////////////////////////////////////////////////////////////////////////////// 130 131SK_DEFINE_FLATTENABLE_REGISTRAR(SkComposePathEffect) 132SK_DEFINE_FLATTENABLE_REGISTRAR(SkStrokePathEffect) 133SK_DEFINE_FLATTENABLE_REGISTRAR(SkSumPathEffect) 134 135