• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
SkPairPathEffect(SkPathEffect * pe0,SkPathEffect * pe1)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 
~SkPairPathEffect()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 */
flatten(SkFlattenableWriteBuffer & buffer)32 void SkPairPathEffect::flatten(SkFlattenableWriteBuffer& buffer) {
33     buffer.writeFlattenable(fPE0);
34     buffer.writeFlattenable(fPE1);
35 }
36 
SkPairPathEffect(SkFlattenableReadBuffer & buffer)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 
filterPath(SkPath * dst,const SkPath & src,SkScalar * width)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 
filterPath(SkPath * dst,const SkPath & src,SkScalar * width)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 
SkStrokePathEffect(const SkPaint & paint)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 
SkStrokePathEffect(SkScalar width,SkPaint::Style style,SkPaint::Join join,SkPaint::Cap cap,SkScalar miter)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 
filterPath(SkPath * dst,const SkPath & src,SkScalar * width)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 
getFactory()111 SkFlattenable::Factory SkStrokePathEffect::getFactory() {
112     return CreateProc;
113 }
114 
CreateProc(SkFlattenableReadBuffer & buffer)115 SkFlattenable* SkStrokePathEffect::CreateProc(SkFlattenableReadBuffer& buffer) {
116     return SkNEW_ARGS(SkStrokePathEffect, (buffer));
117 }
118 
flatten(SkFlattenableWriteBuffer & buffer)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 
SkStrokePathEffect(SkFlattenableReadBuffer & buffer)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