| 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 | #ifndef SkStrokeRec_DEFINED | 
|---|
| 9 | #define SkStrokeRec_DEFINED | 
|---|
| 10 |  | 
|---|
| 11 | #include "include/core/SkPaint.h" | 
|---|
| 12 | #include "include/private/SkMacros.h" | 
|---|
| 13 |  | 
|---|
| 14 | class SkPath; | 
|---|
| 15 |  | 
|---|
| 16 | SK_BEGIN_REQUIRE_DENSE | 
|---|
| 17 | class SK_API SkStrokeRec { | 
|---|
| 18 | public: | 
|---|
| 19 | enum InitStyle { | 
|---|
| 20 | kHairline_InitStyle, | 
|---|
| 21 | kFill_InitStyle | 
|---|
| 22 | }; | 
|---|
| 23 | SkStrokeRec(InitStyle style); | 
|---|
| 24 | SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1); | 
|---|
| 25 | explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1); | 
|---|
| 26 |  | 
|---|
| 27 | enum Style { | 
|---|
| 28 | kHairline_Style, | 
|---|
| 29 | kFill_Style, | 
|---|
| 30 | kStroke_Style, | 
|---|
| 31 | kStrokeAndFill_Style | 
|---|
| 32 | }; | 
|---|
| 33 |  | 
|---|
| 34 | static constexpr int kStyleCount = kStrokeAndFill_Style + 1; | 
|---|
| 35 |  | 
|---|
| 36 | Style getStyle() const; | 
|---|
| 37 | SkScalar getWidth() const { return fWidth; } | 
|---|
| 38 | SkScalar getMiter() const { return fMiterLimit; } | 
|---|
| 39 | SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; } | 
|---|
| 40 | SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; } | 
|---|
| 41 |  | 
|---|
| 42 | bool isHairlineStyle() const { | 
|---|
| 43 | return kHairline_Style == this->getStyle(); | 
|---|
| 44 | } | 
|---|
| 45 |  | 
|---|
| 46 | bool isFillStyle() const { | 
|---|
| 47 | return kFill_Style == this->getStyle(); | 
|---|
| 48 | } | 
|---|
| 49 |  | 
|---|
| 50 | void setFillStyle(); | 
|---|
| 51 | void setHairlineStyle(); | 
|---|
| 52 | /** | 
|---|
| 53 | *  Specify the strokewidth, and optionally if you want stroke + fill. | 
|---|
| 54 | *  Note, if width==0, then this request is taken to mean: | 
|---|
| 55 | *      strokeAndFill==true -> new style will be Fill | 
|---|
| 56 | *      strokeAndFill==false -> new style will be Hairline | 
|---|
| 57 | */ | 
|---|
| 58 | void setStrokeStyle(SkScalar width, bool strokeAndFill = false); | 
|---|
| 59 |  | 
|---|
| 60 | void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) { | 
|---|
| 61 | fCap = cap; | 
|---|
| 62 | fJoin = join; | 
|---|
| 63 | fMiterLimit = miterLimit; | 
|---|
| 64 | } | 
|---|
| 65 |  | 
|---|
| 66 | SkScalar getResScale() const { | 
|---|
| 67 | return fResScale; | 
|---|
| 68 | } | 
|---|
| 69 |  | 
|---|
| 70 | void setResScale(SkScalar rs) { | 
|---|
| 71 | SkASSERT(rs > 0 && SkScalarIsFinite(rs)); | 
|---|
| 72 | fResScale = rs; | 
|---|
| 73 | } | 
|---|
| 74 |  | 
|---|
| 75 | /** | 
|---|
| 76 | *  Returns true if this specifes any thick stroking, i.e. applyToPath() | 
|---|
| 77 | *  will return true. | 
|---|
| 78 | */ | 
|---|
| 79 | bool needToApply() const { | 
|---|
| 80 | Style style = this->getStyle(); | 
|---|
| 81 | return (kStroke_Style == style) || (kStrokeAndFill_Style == style); | 
|---|
| 82 | } | 
|---|
| 83 |  | 
|---|
| 84 | /** | 
|---|
| 85 | *  Apply these stroke parameters to the src path, returning the result | 
|---|
| 86 | *  in dst. | 
|---|
| 87 | * | 
|---|
| 88 | *  If there was no change (i.e. style == hairline or fill) this returns | 
|---|
| 89 | *  false and dst is unchanged. Otherwise returns true and the result is | 
|---|
| 90 | *  stored in dst. | 
|---|
| 91 | * | 
|---|
| 92 | *  src and dst may be the same path. | 
|---|
| 93 | */ | 
|---|
| 94 | bool applyToPath(SkPath* dst, const SkPath& src) const; | 
|---|
| 95 |  | 
|---|
| 96 | /** | 
|---|
| 97 | *  Apply these stroke parameters to a paint. | 
|---|
| 98 | */ | 
|---|
| 99 | void applyToPaint(SkPaint* paint) const; | 
|---|
| 100 |  | 
|---|
| 101 | /** | 
|---|
| 102 | * Gives a conservative value for the outset that should applied to a | 
|---|
| 103 | * geometries bounds to account for any inflation due to applying this | 
|---|
| 104 | * strokeRec to the geometry. | 
|---|
| 105 | */ | 
|---|
| 106 | SkScalar getInflationRadius() const; | 
|---|
| 107 |  | 
|---|
| 108 | /** | 
|---|
| 109 | * Equivalent to: | 
|---|
| 110 | *   SkStrokeRec rec(paint, style); | 
|---|
| 111 | *   rec.getInflationRadius(); | 
|---|
| 112 | * This does not account for other effects on the paint (i.e. path | 
|---|
| 113 | * effect). | 
|---|
| 114 | */ | 
|---|
| 115 | static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style); | 
|---|
| 116 |  | 
|---|
| 117 | static SkScalar GetInflationRadius(SkPaint::Join, SkScalar miterLimit, SkPaint::Cap, | 
|---|
| 118 | SkScalar strokeWidth); | 
|---|
| 119 |  | 
|---|
| 120 | /** | 
|---|
| 121 | * Compare if two SkStrokeRecs have an equal effect on a path. | 
|---|
| 122 | * Equal SkStrokeRecs produce equal paths. Equality of produced | 
|---|
| 123 | * paths does not take the ResScale parameter into account. | 
|---|
| 124 | */ | 
|---|
| 125 | bool hasEqualEffect(const SkStrokeRec& other) const { | 
|---|
| 126 | if (!this->needToApply()) { | 
|---|
| 127 | return this->getStyle() == other.getStyle(); | 
|---|
| 128 | } | 
|---|
| 129 | return fWidth == other.fWidth && | 
|---|
| 130 | fMiterLimit == other.fMiterLimit && | 
|---|
| 131 | fCap == other.fCap && | 
|---|
| 132 | fJoin == other.fJoin && | 
|---|
| 133 | fStrokeAndFill == other.fStrokeAndFill; | 
|---|
| 134 | } | 
|---|
| 135 |  | 
|---|
| 136 | private: | 
|---|
| 137 | void init(const SkPaint&, SkPaint::Style, SkScalar resScale); | 
|---|
| 138 |  | 
|---|
| 139 | SkScalar        fResScale; | 
|---|
| 140 | SkScalar        fWidth; | 
|---|
| 141 | SkScalar        fMiterLimit; | 
|---|
| 142 | // The following three members are packed together into a single u32. | 
|---|
| 143 | // This is to avoid unnecessary padding and ensure binary equality for | 
|---|
| 144 | // hashing (because the padded areas might contain garbage values). | 
|---|
| 145 | // | 
|---|
| 146 | // fCap and fJoin are larger than needed to avoid having to initialize | 
|---|
| 147 | // any pad values | 
|---|
| 148 | uint32_t        fCap : 16;             // SkPaint::Cap | 
|---|
| 149 | uint32_t        fJoin : 15;            // SkPaint::Join | 
|---|
| 150 | uint32_t        fStrokeAndFill : 1;    // bool | 
|---|
| 151 | }; | 
|---|
| 152 | SK_END_REQUIRE_DENSE | 
|---|
| 153 |  | 
|---|
| 154 | #endif | 
|---|
| 155 |  | 
|---|