Avoid using SkPathEffect::DashInfo in GrStrokeInfo

Avoid using SkPathEffect::DashInfo for storing the phase
in GrStrokeInfo. Instead, just use normal instance variables.

Fixes the copy constructor pointing the DashInfo interval pointer
to the wrong interval data.

Also fixes GrStrokeInfo::setDashInfo(const SkPathEffect::DashInfo&)
by updating the fDashType correctly.

Makes it simpler to write code such as the operator== in the future.

Review URL: https://codereview.chromium.org/1110093002
This commit is contained in:
kkinnunen 2015-05-05 08:00:10 -07:00 committed by Commit bot
parent 67383fcfc1
commit 261694c98a
3 changed files with 57 additions and 41 deletions

View File

@ -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;

View File

@ -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;
};

View File

@ -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);
}