Home | History | Annotate | Download | only in core
      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 "SkPaint.h"
     12 
     13 class SkPath;
     14 
     15 class SkStrokeRec {
     16 public:
     17     enum InitStyle {
     18         kHairline_InitStyle,
     19         kFill_InitStyle
     20     };
     21     SkStrokeRec(InitStyle style);
     22 
     23     SkStrokeRec(const SkStrokeRec&);
     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     enum {
     34         kStyleCount = kStrokeAndFill_Style + 1
     35     };
     36 
     37     Style getStyle() const;
     38     SkScalar getWidth() const { return fWidth; }
     39     SkScalar getMiter() const { return fMiterLimit; }
     40     SkPaint::Cap getCap() const { return fCap; }
     41     SkPaint::Join getJoin() const { return fJoin; }
     42 
     43     bool isHairlineStyle() const {
     44         return kHairline_Style == this->getStyle();
     45     }
     46 
     47     bool isFillStyle() const {
     48         return kFill_Style == this->getStyle();
     49     }
     50 
     51     void setFillStyle();
     52     void setHairlineStyle();
     53     /**
     54      *  Specify the strokewidth, and optionally if you want stroke + fill.
     55      *  Note, if width==0, then this request is taken to mean:
     56      *      strokeAndFill==true -> new style will be Fill
     57      *      strokeAndFill==false -> new style will be Hairline
     58      */
     59     void setStrokeStyle(SkScalar width, bool strokeAndFill = false);
     60 
     61     void setStrokeParams(SkPaint::Cap cap, SkPaint::Join join, SkScalar miterLimit) {
     62         fCap = cap;
     63         fJoin = join;
     64         fMiterLimit = miterLimit;
     65     }
     66 
     67     void setResScale(SkScalar rs) {
     68         SkASSERT(rs > 0 && SkScalarIsFinite(rs));
     69         fResScale = rs;
     70     }
     71 
     72     /**
     73      *  Returns true if this specifes any thick stroking, i.e. applyToPath()
     74      *  will return true.
     75      */
     76     bool needToApply() const {
     77         Style style = this->getStyle();
     78         return (kStroke_Style == style) || (kStrokeAndFill_Style == style);
     79     }
     80 
     81     /**
     82      *  Apply these stroke parameters to the src path, returning the result
     83      *  in dst.
     84      *
     85      *  If there was no change (i.e. style == hairline or fill) this returns
     86      *  false and dst is unchanged. Otherwise returns true and the result is
     87      *  stored in dst.
     88      *
     89      *  src and dst may be the same path.
     90      */
     91     bool applyToPath(SkPath* dst, const SkPath& src) const;
     92 
     93     /**
     94      *  Apply these stroke parameters to a paint.
     95      */
     96     void applyToPaint(SkPaint* paint) const;
     97 
     98     /**
     99      * Compare if two SkStrokeRecs have an equal effect on a path.
    100      * Equal SkStrokeRecs produce equal paths. Equality of produced
    101      * paths does not take the ResScale parameter into account.
    102      */
    103     bool hasEqualEffect(const SkStrokeRec& other) const {
    104         if (!this->needToApply()) {
    105             return this->getStyle() == other.getStyle();
    106         }
    107         return fWidth == other.fWidth &&
    108                fMiterLimit == other.fMiterLimit &&
    109                fCap == other.fCap &&
    110                fJoin == other.fJoin &&
    111                fStrokeAndFill == other.fStrokeAndFill;
    112     }
    113 
    114 private:
    115     void init(const SkPaint&, SkPaint::Style, SkScalar resScale);
    116 
    117     SkScalar        fResScale;
    118     SkScalar        fWidth;
    119     SkScalar        fMiterLimit;
    120     SkPaint::Cap    fCap;
    121     SkPaint::Join   fJoin;
    122     bool            fStrokeAndFill;
    123 };
    124 
    125 #endif
    126