Home | History | Annotate | Download | only in gpu
      1 /*
      2  * Copyright 2014 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 GrStrokeInfo_DEFINED
      9 #define GrStrokeInfo_DEFINED
     10 
     11 #include "SkStrokeRec.h"
     12 #include "SkPathEffect.h"
     13 
     14 /*
     15  * GrStrokeInfo encapsulates all the pertinent infomation regarding the stroke. The SkStrokeRec
     16  * which holds information on fill style, width, miter, cap, and join. It also holds information
     17  * about the dash like intervals, count, and phase.
     18  */
     19 class GrStrokeInfo {
     20 public:
     21     GrStrokeInfo(SkStrokeRec::InitStyle style) :
     22         fStroke(style), fDashType(SkPathEffect::kNone_DashType) {}
     23 
     24     GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true) : fStroke(src.fStroke) {
     25         if (includeDash && src.isDashed()) {
     26             fDashType = src.fDashType;
     27             fDashPhase = src.fDashPhase;
     28             fIntervals.reset(src.getDashCount());
     29             memcpy(fIntervals.get(), src.fIntervals.get(), fIntervals.count() * sizeof(SkScalar));
     30         } else {
     31             fDashType = SkPathEffect::kNone_DashType;
     32         }
     33     }
     34 
     35     GrStrokeInfo(const SkPaint& paint, SkPaint::Style styleOverride) :
     36         fStroke(paint, styleOverride), fDashType(SkPathEffect::kNone_DashType) {
     37         this->init(paint);
     38     }
     39 
     40     explicit GrStrokeInfo(const SkPaint& paint) :
     41         fStroke(paint), fDashType(SkPathEffect::kNone_DashType) {
     42         this->init(paint);
     43     }
     44 
     45     GrStrokeInfo& operator=(const GrStrokeInfo& other) {
     46         if (other.isDashed()) {
     47             fDashType = other.fDashType;
     48             fDashPhase = other.fDashPhase;
     49             fIntervals.reset(other.getDashCount());
     50             memcpy(fIntervals.get(), other.fIntervals.get(), fIntervals.count() * sizeof(SkScalar));
     51         } else {
     52             this->removeDash();
     53         }
     54         fStroke = other.fStroke;
     55         return *this;
     56     }
     57 
     58     const SkStrokeRec& getStrokeRec() const { return fStroke; }
     59 
     60     SkStrokeRec* getStrokeRecPtr() { return &fStroke; }
     61 
     62     void setFillStyle() { fStroke.setFillStyle(); }
     63 
     64     /*
     65      * This functions takes in a patheffect and updates the dashing information if the path effect
     66      * is a Dash type. Returns true if the path effect is a dashed effect and we are stroking,
     67      * otherwise it returns false.
     68      */
     69     bool setDashInfo(const SkPathEffect* pe) {
     70         if (pe && !fStroke.isFillStyle()) {
     71             SkPathEffect::DashInfo dashInfo;
     72             fDashType = pe->asADash(&dashInfo);
     73             if (SkPathEffect::kDash_DashType == fDashType) {
     74                 fIntervals.reset(dashInfo.fCount);
     75                 dashInfo.fIntervals = fIntervals.get();
     76                 pe->asADash(&dashInfo);
     77                 fDashPhase = dashInfo.fPhase;
     78                 return true;
     79             }
     80         }
     81         return false;
     82     }
     83 
     84     /*
     85      * Like the above, but sets with an explicit SkPathEffect::DashInfo
     86      */
     87     bool setDashInfo(const SkPathEffect::DashInfo& info) {
     88         if (!fStroke.isFillStyle()) {
     89             SkASSERT(!fStroke.isFillStyle());
     90             fDashType = SkPathEffect::kDash_DashType;
     91             fDashPhase = info.fPhase;
     92             fIntervals.reset(info.fCount);
     93             for (int i = 0; i < fIntervals.count(); i++) {
     94                 fIntervals[i] = info.fIntervals[i];
     95             }
     96             return true;
     97         }
     98         return false;
     99     }
    100 
    101     bool isDashed() const {
    102         return (!fStroke.isFillStyle() && SkPathEffect::kDash_DashType == fDashType);
    103     }
    104 
    105     bool isFillStyle() const { return fStroke.isFillStyle(); }
    106 
    107     int32_t getDashCount() const {
    108         SkASSERT(this->isDashed());
    109         return fIntervals.count();
    110     }
    111 
    112     SkScalar getDashPhase() const {
    113         SkASSERT(this->isDashed());
    114         return fDashPhase;
    115     }
    116 
    117     const SkScalar* getDashIntervals() const {
    118         SkASSERT(this->isDashed());
    119         return fIntervals.get();
    120     }
    121 
    122     void removeDash() {
    123         fDashType = SkPathEffect::kNone_DashType;
    124     }
    125 
    126     /** Applies the dash to a path, if the stroke info has dashing.
    127      * @return true if the dashing was applied (dst and dstStrokeInfo will be modified).
    128      *         false if the stroke info did not have dashing. The dst and dstStrokeInfo
    129      *               will be unmodified. The stroking in the SkStrokeRec might still
    130      *               be applicable.
    131      */
    132     bool applyDash(SkPath* dst, GrStrokeInfo* dstStrokeInfo, const SkPath& src) const;
    133 
    134 private:
    135 
    136     void init(const SkPaint& paint) {
    137         const SkPathEffect* pe = paint.getPathEffect();
    138         this->setDashInfo(pe);
    139     }
    140 
    141     SkStrokeRec            fStroke;
    142     SkPathEffect::DashType fDashType;
    143     SkScalar               fDashPhase;
    144     SkAutoSTArray<2, SkScalar> fIntervals;
    145 };
    146 
    147 #endif
    148