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