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