| Index: src/gpu/GrStrokeInfo.h
 | 
| diff --git a/src/gpu/GrStrokeInfo.h b/src/gpu/GrStrokeInfo.h
 | 
| new file mode 100644
 | 
| index 0000000000000000000000000000000000000000..9cf7d8302f1388b0490e906945c3a2ea24909769
 | 
| --- /dev/null
 | 
| +++ b/src/gpu/GrStrokeInfo.h
 | 
| @@ -0,0 +1,191 @@
 | 
| +/*
 | 
| + * Copyright 2014 Google Inc.
 | 
| + *
 | 
| + * Use of this source code is governed by a BSD-style license that can be
 | 
| + * found in the LICENSE file.
 | 
| + */
 | 
| +
 | 
| +#ifndef GrStrokeInfo_DEFINED
 | 
| +#define GrStrokeInfo_DEFINED
 | 
| +
 | 
| +#include "SkPathEffect.h"
 | 
| +#include "SkStrokeRec.h"
 | 
| +#include "SkTemplates.h"
 | 
| +
 | 
| +class GrUniqueKey;
 | 
| +
 | 
| +/*
 | 
| + * GrStrokeInfo encapsulates all the pertinent infomation regarding the stroke. The SkStrokeRec
 | 
| + * which holds information on fill style, width, miter, cap, and join. It also holds information
 | 
| + * about the dash like intervals, count, and phase.
 | 
| + */
 | 
| +class GrStrokeInfo : public SkStrokeRec {
 | 
| +public:
 | 
| +    static const GrStrokeInfo& FillInfo() {
 | 
| +        static const GrStrokeInfo gFill(kFill_InitStyle);
 | 
| +        return gFill;
 | 
| +    }
 | 
| +
 | 
| +    GrStrokeInfo(SkStrokeRec::InitStyle style)
 | 
| +        : INHERITED(style)
 | 
| +        , fDashType(SkPathEffect::kNone_DashType) {
 | 
| +    }
 | 
| +
 | 
| +    GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true)
 | 
| +        : INHERITED(src) {
 | 
| +        if (includeDash && src.isDashed()) {
 | 
| +            fDashType = src.fDashType;
 | 
| +            fDashPhase = src.fDashPhase;
 | 
| +            fIntervals.reset(src.getDashCount());
 | 
| +            memcpy(fIntervals.get(), src.fIntervals.get(), fIntervals.count() * sizeof(SkScalar));
 | 
| +        } else {
 | 
| +            fDashType = SkPathEffect::kNone_DashType;
 | 
| +        }
 | 
| +    }
 | 
| +
 | 
| +    GrStrokeInfo(const SkPaint& paint, SkPaint::Style styleOverride)
 | 
| +        : INHERITED(paint, styleOverride)
 | 
| +        , fDashType(SkPathEffect::kNone_DashType) {
 | 
| +        this->init(paint);
 | 
| +    }
 | 
| +
 | 
| +    explicit GrStrokeInfo(const SkPaint& paint)
 | 
| +        : INHERITED(paint)
 | 
| +        , fDashType(SkPathEffect::kNone_DashType) {
 | 
| +        this->init(paint);
 | 
| +    }
 | 
| +
 | 
| +    GrStrokeInfo& operator=(const GrStrokeInfo& other) {
 | 
| +        if (other.isDashed()) {
 | 
| +            fDashType = other.fDashType;
 | 
| +            fDashPhase = other.fDashPhase;
 | 
| +            fIntervals.reset(other.getDashCount());
 | 
| +            memcpy(fIntervals.get(), other.fIntervals.get(), fIntervals.count() * sizeof(SkScalar));
 | 
| +        } else {
 | 
| +            this->removeDash();
 | 
| +        }
 | 
| +        this->INHERITED::operator=(other);
 | 
| +        return *this;
 | 
| +    }
 | 
| +
 | 
| +    bool hasEqualEffect(const GrStrokeInfo& other) const {
 | 
| +        if (this->isDashed() != other.isDashed()) {
 | 
| +            return false;
 | 
| +        }
 | 
| +        if (this->isDashed()) {
 | 
| +            if (fDashPhase != other.fDashPhase ||
 | 
| +                fIntervals.count() != other.fIntervals.count() ||
 | 
| +                memcmp(fIntervals.get(), other.fIntervals.get(),
 | 
| +                       fIntervals.count() * sizeof(SkScalar)) != 0) {
 | 
| +                return false;
 | 
| +            }
 | 
| +        }
 | 
| +        return this->INHERITED::hasEqualEffect(other);
 | 
| +    }
 | 
| +
 | 
| +    /*
 | 
| +     * This functions takes in a patheffect and updates the dashing information if the path effect
 | 
| +     * is a Dash type. Returns true if the path effect is a dashed effect and we are stroking,
 | 
| +     * otherwise it returns false.
 | 
| +     */
 | 
| +    bool setDashInfo(const SkPathEffect* pe) {
 | 
| +        if (pe && !this->isFillStyle()) {
 | 
| +            SkPathEffect::DashInfo dashInfo;
 | 
| +            fDashType = pe->asADash(&dashInfo);
 | 
| +            if (SkPathEffect::kDash_DashType == fDashType) {
 | 
| +                fIntervals.reset(dashInfo.fCount);
 | 
| +                dashInfo.fIntervals = fIntervals.get();
 | 
| +                pe->asADash(&dashInfo);
 | 
| +                fDashPhase = dashInfo.fPhase;
 | 
| +                return true;
 | 
| +            }
 | 
| +        }
 | 
| +        return false;
 | 
| +    }
 | 
| +
 | 
| +    /*
 | 
| +     * Like the above, but sets with an explicit SkPathEffect::DashInfo
 | 
| +     */
 | 
| +    bool setDashInfo(const SkPathEffect::DashInfo& info) {
 | 
| +        if (!this->isFillStyle()) {
 | 
| +            fDashType = SkPathEffect::kDash_DashType;
 | 
| +            fDashPhase = info.fPhase;
 | 
| +            fIntervals.reset(info.fCount);
 | 
| +            for (int i = 0; i < fIntervals.count(); i++) {
 | 
| +                fIntervals[i] = info.fIntervals[i];
 | 
| +            }
 | 
| +            return true;
 | 
| +        }
 | 
| +        return false;
 | 
| +    }
 | 
| +
 | 
| +    bool isDashed() const {
 | 
| +        return (!this->isFillStyle() && SkPathEffect::kDash_DashType == fDashType);
 | 
| +    }
 | 
| +
 | 
| +    int32_t getDashCount() const {
 | 
| +        SkASSERT(this->isDashed());
 | 
| +        return fIntervals.count();
 | 
| +    }
 | 
| +
 | 
| +    SkScalar getDashPhase() const {
 | 
| +        SkASSERT(this->isDashed());
 | 
| +        return fDashPhase;
 | 
| +    }
 | 
| +
 | 
| +    const SkScalar* getDashIntervals() const {
 | 
| +        SkASSERT(this->isDashed());
 | 
| +        return fIntervals.get();
 | 
| +    }
 | 
| +
 | 
| +    void removeDash() {
 | 
| +        fDashType = SkPathEffect::kNone_DashType;
 | 
| +    }
 | 
| +
 | 
| +    /** Applies the dash to a path, if the stroke info has dashing.
 | 
| +     * @return true if the dashing was applied (dst and dstStrokeInfo will be modified).
 | 
| +     *         false if the stroke info did not have dashing. The dst and dstStrokeInfo
 | 
| +     *               will be unmodified. The stroking in the SkStrokeRec might still
 | 
| +     *               be applicable.
 | 
| +     */
 | 
| +    bool applyDashToPath(SkPath* dst, GrStrokeInfo* dstStrokeInfo, const SkPath& src) const;
 | 
| +
 | 
| +    /**
 | 
| +     * Computes the length of the data that will be written by asUniqueKeyFragment() function.
 | 
| +     */
 | 
| +    int computeUniqueKeyFragmentData32Cnt() const {
 | 
| +        const int kSkScalarData32Cnt = sizeof(SkScalar) / sizeof(uint32_t);
 | 
| +        // SkStrokeRec data: 32 bits for style+join+cap and 2 scalars for miter and width.
 | 
| +        int strokeKeyData32Cnt = 1 + 2 * kSkScalarData32Cnt;
 | 
| +
 | 
| +        if (this->isDashed()) {
 | 
| +            // One scalar for dash phase and one for each dash value.
 | 
| +            strokeKeyData32Cnt += (1 + this->getDashCount()) * kSkScalarData32Cnt;
 | 
| +        }
 | 
| +        return strokeKeyData32Cnt;
 | 
| +    }
 | 
| +
 | 
| +    /**
 | 
| +     * Writes the object contents as uint32_t data, to be used with GrUniqueKey.
 | 
| +     * Note: the data written does not encode the length, so care must be taken to ensure
 | 
| +     * that the full unique key data is encoded properly. For example, GrStrokeInfo
 | 
| +     * fragment can be placed last in the sequence, at fixed index.
 | 
| +     */
 | 
| +    void asUniqueKeyFragment(uint32_t*) const;
 | 
| +
 | 
| +private:
 | 
| +    // Prevent accidental usage, should use GrStrokeInfo::hasEqualEffect.
 | 
| +    bool hasEqualEffect(const SkStrokeRec& other) const;
 | 
| +
 | 
| +    void init(const SkPaint& paint) {
 | 
| +        const SkPathEffect* pe = paint.getPathEffect();
 | 
| +        this->setDashInfo(pe);
 | 
| +    }
 | 
| +
 | 
| +    SkPathEffect::DashType fDashType;
 | 
| +    SkScalar               fDashPhase;
 | 
| +    SkAutoSTArray<2, SkScalar> fIntervals;
 | 
| +    typedef SkStrokeRec INHERITED;
 | 
| +};
 | 
| +
 | 
| +#endif
 | 
| 
 |