1 /*
2 * Copyright 2012 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "SkStrokeRec.h"
9 #include "SkPaintDefaults.h"
10
11 // must be < 0, since ==0 means hairline, and >0 means normal stroke
12 #define kStrokeRec_FillStyleWidth (-SK_Scalar1)
13
SkStrokeRec(InitStyle s)14 SkStrokeRec::SkStrokeRec(InitStyle s) {
15 fWidth = (kFill_InitStyle == s) ? kStrokeRec_FillStyleWidth : 0;
16 fMiterLimit = SkPaintDefaults_MiterLimit;
17 fCap = SkPaint::kDefault_Cap;
18 fJoin = SkPaint::kDefault_Join;
19 fStrokeAndFill = false;
20 }
21
SkStrokeRec(const SkStrokeRec & src)22 SkStrokeRec::SkStrokeRec(const SkStrokeRec& src) {
23 memcpy(this, &src, sizeof(src));
24 }
25
SkStrokeRec(const SkPaint & paint)26 SkStrokeRec::SkStrokeRec(const SkPaint& paint) {
27 this->init(paint, paint.getStyle());
28 }
29
SkStrokeRec(const SkPaint & paint,SkPaint::Style styleOverride)30 SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkPaint::Style styleOverride) {
31 this->init(paint, styleOverride);
32 }
33
init(const SkPaint & paint,SkPaint::Style style)34 void SkStrokeRec::init(const SkPaint& paint, SkPaint::Style style) {
35 switch (style) {
36 case SkPaint::kFill_Style:
37 fWidth = kStrokeRec_FillStyleWidth;
38 fStrokeAndFill = false;
39 break;
40 case SkPaint::kStroke_Style:
41 fWidth = paint.getStrokeWidth();
42 fStrokeAndFill = false;
43 break;
44 case SkPaint::kStrokeAndFill_Style:
45 if (0 == paint.getStrokeWidth()) {
46 // hairline+fill == fill
47 fWidth = kStrokeRec_FillStyleWidth;
48 fStrokeAndFill = false;
49 } else {
50 fWidth = paint.getStrokeWidth();
51 fStrokeAndFill = true;
52 }
53 break;
54 default:
55 SkDEBUGFAIL("unknown paint style");
56 // fall back on just fill
57 fWidth = kStrokeRec_FillStyleWidth;
58 fStrokeAndFill = false;
59 break;
60 }
61
62 // copy these from the paint, regardless of our "style"
63 fMiterLimit = paint.getStrokeMiter();
64 fCap = paint.getStrokeCap();
65 fJoin = paint.getStrokeJoin();
66 }
67
getStyle() const68 SkStrokeRec::Style SkStrokeRec::getStyle() const {
69 if (fWidth < 0) {
70 return kFill_Style;
71 } else if (0 == fWidth) {
72 return kHairline_Style;
73 } else {
74 return fStrokeAndFill ? kStrokeAndFill_Style : kStroke_Style;
75 }
76 }
77
setFillStyle()78 void SkStrokeRec::setFillStyle() {
79 fWidth = kStrokeRec_FillStyleWidth;
80 fStrokeAndFill = false;
81 }
82
setHairlineStyle()83 void SkStrokeRec::setHairlineStyle() {
84 fWidth = 0;
85 fStrokeAndFill = false;
86 }
87
setStrokeStyle(SkScalar width,bool strokeAndFill)88 void SkStrokeRec::setStrokeStyle(SkScalar width, bool strokeAndFill) {
89 if (strokeAndFill && (0 == width)) {
90 // hairline+fill == fill
91 this->setFillStyle();
92 } else {
93 fWidth = width;
94 fStrokeAndFill = strokeAndFill;
95 }
96 }
97
98 #include "SkStroke.h"
99
applyToPath(SkPath * dst,const SkPath & src) const100 bool SkStrokeRec::applyToPath(SkPath* dst, const SkPath& src) const {
101 if (fWidth <= 0) { // hairline or fill
102 return false;
103 }
104
105 SkStroke stroker;
106 stroker.setCap(fCap);
107 stroker.setJoin(fJoin);
108 stroker.setMiterLimit(fMiterLimit);
109 stroker.setWidth(fWidth);
110 stroker.setDoFill(fStrokeAndFill);
111 stroker.strokePath(src, dst);
112 return true;
113 }
114