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 |