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 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 22 SkStrokeRec::SkStrokeRec(const SkStrokeRec& src) { 23 memcpy(this, &src, sizeof(src)); 24 } 25 26 SkStrokeRec::SkStrokeRec(const SkPaint& paint) { 27 this->init(paint, paint.getStyle()); 28 } 29 30 SkStrokeRec::SkStrokeRec(const SkPaint& paint, SkPaint::Style styleOverride) { 31 this->init(paint, styleOverride); 32 } 33 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 68 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 78 void SkStrokeRec::setFillStyle() { 79 fWidth = kStrokeRec_FillStyleWidth; 80 fStrokeAndFill = false; 81 } 82 83 void SkStrokeRec::setHairlineStyle() { 84 fWidth = 0; 85 fStrokeAndFill = false; 86 } 87 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 100 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