diff --git a/src/gpu/GrStrokeInfo.cpp b/src/gpu/GrStrokeInfo.cpp index 30f4b8931e..be8e5603a1 100644 --- a/src/gpu/GrStrokeInfo.cpp +++ b/src/gpu/GrStrokeInfo.cpp @@ -11,7 +11,10 @@ bool GrStrokeInfo::applyDash(SkPath* dst, GrStrokeInfo* dstStrokeInfo, const SkPath& src) const { if (this->isDashed()) { - const SkPathEffect::DashInfo& info = this->getDashInfo(); + SkPathEffect::DashInfo info; + info.fIntervals = fIntervals.get(); + info.fCount = fIntervals.count(); + info.fPhase = fDashPhase; SkStrokeRec strokeRec = fStroke; if (SkDashPath::FilterDashPath(dst, src, &strokeRec, NULL, info)) { dstStrokeInfo->fStroke = strokeRec; diff --git a/src/gpu/GrStrokeInfo.h b/src/gpu/GrStrokeInfo.h index f008dc6a5d..e1349a7eec 100644 --- a/src/gpu/GrStrokeInfo.h +++ b/src/gpu/GrStrokeInfo.h @@ -12,10 +12,9 @@ #include "SkPathEffect.h" /* - * GrStrokeInfo encapsulates the data objects that hold all the pertinent infomation - * regarding the stroke. The two objects are SkStrokeRec which holds information on fill style, - * width, miter, cap, and join. The second object is DashInfo. This holds information about the - * dash like intervals, count, and phase. + * 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: @@ -23,11 +22,11 @@ public: fStroke(style), fDashType(SkPathEffect::kNone_DashType) {} GrStrokeInfo(const GrStrokeInfo& src, bool includeDash = true) : fStroke(src.fStroke) { - if (includeDash) { - fDashInfo = src.fDashInfo; + if (includeDash && src.isDashed()) { fDashType = src.fDashType; - fIntervals.reset(src.dashCount()); - memcpy(fIntervals.get(), src.fIntervals.get(), src.dashCount() * sizeof(SkScalar)); + fDashPhase = src.fDashPhase; + fIntervals.reset(src.getDashCount()); + memcpy(fIntervals.get(), src.fIntervals.get(), fIntervals.count() * sizeof(SkScalar)); } else { fDashType = SkPathEffect::kNone_DashType; } @@ -44,11 +43,15 @@ public: } 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(); + } fStroke = other.fStroke; - fDashInfo = other.fDashInfo; - fDashType = other.fDashType; - fIntervals.reset(other.dashCount()); - memcpy(fIntervals.get(), other.fIntervals.get(), other.dashCount() * sizeof(SkScalar)); return *this; } @@ -59,18 +62,19 @@ public: void setFillStyle() { fStroke.setFillStyle(); } /* - * This functions takes in a patheffect and fills in fDashInfo with the various 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 retruns false. + * 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 && !fStroke.isFillStyle()) { - fDashInfo.fIntervals = NULL; - fDashType = pe->asADash(&fDashInfo); + SkPathEffect::DashInfo dashInfo; + fDashType = pe->asADash(&dashInfo); if (SkPathEffect::kDash_DashType == fDashType) { - fIntervals.reset(fDashInfo.fCount); - fDashInfo.fIntervals = fIntervals.get(); - pe->asADash(&fDashInfo); + fIntervals.reset(dashInfo.fCount); + dashInfo.fIntervals = fIntervals.get(); + pe->asADash(&dashInfo); + fDashPhase = dashInfo.fPhase; return true; } } @@ -83,13 +87,12 @@ public: bool setDashInfo(const SkPathEffect::DashInfo& info) { if (!fStroke.isFillStyle()) { SkASSERT(!fStroke.isFillStyle()); - fDashInfo.fCount = info.fCount; - fDashInfo.fPhase = info.fPhase; + fDashType = SkPathEffect::kDash_DashType; + fDashPhase = info.fPhase; fIntervals.reset(info.fCount); - for (int i = 0; i < info.fCount; i++) { + for (int i = 0; i < fIntervals.count(); i++) { fIntervals[i] = info.fIntervals[i]; } - fDashInfo.fIntervals = fIntervals.get(); return true; } return false; @@ -101,18 +104,27 @@ public: bool isFillStyle() const { return fStroke.isFillStyle(); } - int32_t dashCount() const { - return fDashInfo.fCount; + 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; } - - const SkPathEffect::DashInfo& getDashInfo() const { return fDashInfo; } /** Applies the dash to a path, if the stroke info has dashing. - * @return true if the dash ingwas applied (dst and dstStrokeInfo will be modified). + * @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. @@ -128,7 +140,7 @@ private: SkStrokeRec fStroke; SkPathEffect::DashType fDashType; - SkPathEffect::DashInfo fDashInfo; + SkScalar fDashPhase; SkAutoSTArray<2, SkScalar> fIntervals; }; diff --git a/src/gpu/effects/GrDashingEffect.cpp b/src/gpu/effects/GrDashingEffect.cpp index 7250245e7e..869454049a 100644 --- a/src/gpu/effects/GrDashingEffect.cpp +++ b/src/gpu/effects/GrDashingEffect.cpp @@ -43,18 +43,18 @@ bool GrDashingEffect::CanDrawDashLine(const SkPoint pts[2], const GrStrokeInfo& return false; } - if (!strokeInfo.isDashed() || 2 != strokeInfo.dashCount()) { + if (!strokeInfo.isDashed() || 2 != strokeInfo.getDashCount()) { return false; } - const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); - if (0 == info.fIntervals[0] && 0 == info.fIntervals[1]) { + const SkScalar* intervals = strokeInfo.getDashIntervals(); + if (0 == intervals[0] && 0 == intervals[1]) { return false; } SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); // Current we do don't handle Round or Square cap dashes - if (SkPaint::kRound_Cap == cap && info.fIntervals[0] != 0.f) { + if (SkPaint::kRound_Cap == cap && intervals[0] != 0.f) { return false; } @@ -682,7 +682,8 @@ private: static GrBatch* create_batch(GrColor color, const SkMatrix& viewMatrix, const SkPoint pts[2], bool useAA, const GrStrokeInfo& strokeInfo, bool msaaRT) { - const SkPathEffect::DashInfo& info = strokeInfo.getDashInfo(); + const SkScalar* intervals = strokeInfo.getDashIntervals(); + SkScalar phase = strokeInfo.getDashPhase(); SkPaint::Cap cap = strokeInfo.getStrokeRec().getCap(); @@ -690,7 +691,7 @@ static GrBatch* create_batch(GrColor color, const SkMatrix& viewMatrix, const Sk geometry.fSrcStrokeWidth = strokeInfo.getStrokeRec().getWidth(); // the phase should be normalized to be [0, sum of all intervals) - SkASSERT(info.fPhase >= 0 && info.fPhase < info.fIntervals[0] + info.fIntervals[1]); + SkASSERT(phase >= 0 && phase < intervals[0] + intervals[1]); // Rotate the src pts so they are aligned horizontally with pts[0].fX < pts[1].fX if (pts[0].fY != pts[1].fY || pts[0].fX > pts[1].fX) { @@ -709,7 +710,7 @@ static GrBatch* create_batch(GrColor color, const SkMatrix& viewMatrix, const Sk calc_dash_scaling(&geometry.fParallelScale, &geometry.fPerpendicularScale, viewMatrix, geometry.fPtsRot); - SkScalar offInterval = info.fIntervals[1] * geometry.fParallelScale; + SkScalar offInterval = intervals[1] * geometry.fParallelScale; SkScalar strokeWidth = geometry.fSrcStrokeWidth * geometry.fPerpendicularScale; if (SkPaint::kSquare_Cap == cap && 0 != geometry.fSrcStrokeWidth) { @@ -725,9 +726,9 @@ static GrBatch* create_batch(GrColor color, const SkMatrix& viewMatrix, const Sk geometry.fColor = color; geometry.fViewMatrix = viewMatrix; - geometry.fPhase = info.fPhase; - geometry.fIntervals[0] = info.fIntervals[0]; - geometry.fIntervals[1] = info.fIntervals[1]; + geometry.fPhase = phase; + geometry.fIntervals[0] = intervals[0]; + geometry.fIntervals[1] = intervals[1]; return DashBatch::Create(geometry, cap, aaMode, fullDash); }