| /* |
| * Copyright 2012 Google Inc. |
| * |
| * Use of this source code is governed by a BSD-style license that can be |
| * found in the LICENSE file. |
| */ |
| |
| #ifndef SkStrokeRec_DEFINED |
| #define SkStrokeRec_DEFINED |
| |
| #include "include/core/SkPaint.h" |
| #include "include/private/SkMacros.h" |
| |
| class SkPath; |
| |
| SK_BEGIN_REQUIRE_DENSE |
| class SK_API SkStrokeRec { |
| public: |
| enum InitStyle { |
| kHairline_InitStyle, |
| kFill_InitStyle |
| }; |
| SkStrokeRec(InitStyle style); |
| SkStrokeRec(const SkPaint&, SkPaint::Style, SkScalar resScale = 1); |
| explicit SkStrokeRec(const SkPaint&, SkScalar resScale = 1); |
| |
| enum Style { |
| kHairline_Style, |
| kFill_Style, |
| kStroke_Style, |
| kStrokeAndFill_Style |
| }; |
| |
| static constexpr int kStyleCount = kStrokeAndFill_Style + 1; |
| |
| Style getStyle() const; |
| SkScalar getWidth() const { return fWidth; } |
| SkScalar getMiter() const { return fMiterLimit; } |
| SkPaint::Cap getCap() const { return (SkPaint::Cap)fCap; } |
| SkPaint::Join getJoin() const { return (SkPaint::Join)fJoin; } |
| |
| bool isHairlineStyle() const { |
| return kHairline_Style == this->getStyle(); |
| } |
| |
| bool isFillStyle() const { |
| return kFill_Style == this->getStyle(); |
| } |
| |
| void setFillStyle(); |
| void setHairlineStyle(); |
| /** |
| * Specify the strokewidth, and optionally if you want stroke + fill. |
| * Note, if width==0, then this request is taken to mean: |
| * strokeAndFill==true -> new style will be Fill |
| * strokeAndFill==false -> new style will be Hairline |
| */ |
| void setStrokeStyle(SkScalar width, bool strokeAndFill = false); |
| |
| void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) { |
| fCap = cap; |
| fJoin = join; |
| fMiterLimit = miterLimit; |
| } |
| |
| SkScalar getResScale() const { |
| return fResScale; |
| } |
| |
| void setResScale(SkScalar rs) { |
| SkASSERT(rs > 0 && SkScalarIsFinite(rs)); |
| fResScale = rs; |
| } |
| |
| /** |
| * Returns true if this specifes any thick stroking, i.e. applyToPath() |
| * will return true. |
| */ |
| bool needToApply() const { |
| Style style = this->getStyle(); |
| return (kStroke_Style == style) || (kStrokeAndFill_Style == style); |
| } |
| |
| /** |
| * Apply these stroke parameters to the src path, returning the result |
| * in dst. |
| * |
| * If there was no change (i.e. style == hairline or fill) this returns |
| * false and dst is unchanged. Otherwise returns true and the result is |
| * stored in dst. |
| * |
| * src and dst may be the same path. |
| */ |
| bool applyToPath(SkPath* dst, const SkPath& src) const; |
| |
| /** |
| * Apply these stroke parameters to a paint. |
| */ |
| void applyToPaint(SkPaint* paint) const; |
| |
| /** |
| * Gives a conservative value for the outset that should applied to a |
| * geometries bounds to account for any inflation due to applying this |
| * strokeRec to the geometry. |
| */ |
| SkScalar getInflationRadius() const; |
| |
| /** |
| * Equivalent to: |
| * SkStrokeRec rec(paint, style); |
| * rec.getInflationRadius(); |
| * This does not account for other effects on the paint (i.e. path |
| * effect). |
| */ |
| static SkScalar GetInflationRadius(const SkPaint&, SkPaint::Style); |
| |
| static SkScalar GetInflationRadius(SkPaint::Join, SkScalar miterLimit, SkPaint::Cap, |
| SkScalar strokeWidth); |
| |
| /** |
| * Compare if two SkStrokeRecs have an equal effect on a path. |
| * Equal SkStrokeRecs produce equal paths. Equality of produced |
| * paths does not take the ResScale parameter into account. |
| */ |
| bool hasEqualEffect(const SkStrokeRec& other) const { |
| if (!this->needToApply()) { |
| return this->getStyle() == other.getStyle(); |
| } |
| return fWidth == other.fWidth && |
| (fJoin != SkPaint::kMiter_Join || fMiterLimit == other.fMiterLimit) && |
| fCap == other.fCap && |
| fJoin == other.fJoin && |
| fStrokeAndFill == other.fStrokeAndFill; |
| } |
| |
| private: |
| void init(const SkPaint&, SkPaint::Style, SkScalar resScale); |
| |
| SkScalar fResScale; |
| SkScalar fWidth; |
| SkScalar fMiterLimit; |
| // The following three members are packed together into a single u32. |
| // This is to avoid unnecessary padding and ensure binary equality for |
| // hashing (because the padded areas might contain garbage values). |
| // |
| // fCap and fJoin are larger than needed to avoid having to initialize |
| // any pad values |
| uint32_t fCap : 16; // SkPaint::Cap |
| uint32_t fJoin : 15; // SkPaint::Join |
| uint32_t fStrokeAndFill : 1; // bool |
| }; |
| SK_END_REQUIRE_DENSE |
| |
| #endif |