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
14SkStrokeRec::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
22SkStrokeRec::SkStrokeRec(const SkStrokeRec& src) {
23    memcpy(this, &src, sizeof(src));
24}
25
26SkStrokeRec::SkStrokeRec(const SkPaint& paint) {
27    switch (paint.getStyle()) {
28        case SkPaint::kFill_Style:
29            fWidth = kStrokeRec_FillStyleWidth;
30            fStrokeAndFill = false;
31            break;
32        case SkPaint::kStroke_Style:
33            fWidth = paint.getStrokeWidth();
34            fStrokeAndFill = false;
35            break;
36        case SkPaint::kStrokeAndFill_Style:
37            if (0 == paint.getStrokeWidth()) {
38                // hairline+fill == fill
39                fWidth = kStrokeRec_FillStyleWidth;
40                fStrokeAndFill = false;
41            } else {
42                fWidth = paint.getStrokeWidth();
43                fStrokeAndFill = true;
44            }
45            break;
46        default:
47            SkASSERT(!"unknown paint style");
48            // fall back on just fill
49            fWidth = kStrokeRec_FillStyleWidth;
50            fStrokeAndFill = false;
51            break;
52    }
53
54    // copy these from the paint, regardless of our "style"
55    fMiterLimit = paint.getStrokeMiter();
56    fCap        = paint.getStrokeCap();
57    fJoin       = paint.getStrokeJoin();
58}
59
60SkStrokeRec::Style SkStrokeRec::getStyle() const {
61    if (fWidth < 0) {
62        return kFill_Style;
63    } else if (0 == fWidth) {
64        return kHairline_Style;
65    } else {
66        return fStrokeAndFill ? kStrokeAndFill_Style : kStroke_Style;
67    }
68}
69
70void SkStrokeRec::setFillStyle() {
71    fWidth = kStrokeRec_FillStyleWidth;
72    fStrokeAndFill = false;
73}
74
75void SkStrokeRec::setHairlineStyle() {
76    fWidth = 0;
77    fStrokeAndFill = false;
78}
79
80void SkStrokeRec::setStrokeStyle(SkScalar width, bool strokeAndFill) {
81    if (strokeAndFill && (0 == width)) {
82        // hairline+fill == fill
83        this->setFillStyle();
84    } else {
85        fWidth = width;
86        fStrokeAndFill = strokeAndFill;
87    }
88}
89
90#include "SkStroke.h"
91
92bool SkStrokeRec::applyToPath(SkPath* dst, const SkPath& src) const {
93    if (fWidth <= 0) {  // hairline or fill
94        return false;
95    }
96
97    SkStroke stroker;
98    stroker.setCap(fCap);
99    stroker.setJoin(fJoin);
100    stroker.setMiterLimit(fMiterLimit);
101    stroker.setWidth(fWidth);
102    stroker.setDoFill(fStrokeAndFill);
103    stroker.strokePath(src, dst);
104    return true;
105}
106