Randomize seed for SkDiscretePathEffect::filterPath()
Fix for https://code.google.com/p/skia/issues/detail?id=2581. Randomizes the seed in SkDiscretePathEffect::filterPath(). Prior to this we were using the path length as a seed. Now, if we have two different paths with identical contents and we apply an SkDiscretePathEffect to each, we obtain two different random paths. Previously, we would obtain two overlapping paths (identical path contents leading to the same seed). BUG=skia: R=reed@google.com, scroggo@google.com Author: rs.prinja@samsung.com Review URL: https://codereview.chromium.org/311803002
This commit is contained in:
parent
bfefc7c95f
commit
39e58adb99
@ -19,9 +19,21 @@ public:
|
||||
/** Break the path into segments of segLength length, and randomly move the endpoints
|
||||
away from the original path by a maximum of deviation.
|
||||
Note: works on filled or framed paths
|
||||
|
||||
@param seedAssist This is a caller-supplied seedAssist that modifies
|
||||
the seed value that is used to randomize the path
|
||||
segments' endpoints. If not supplied it defaults to 0,
|
||||
in which case filtering a path multiple times will
|
||||
result in the same set of segments (this is useful for
|
||||
testing). If a caller does not want this behaviour
|
||||
they can pass in a different seedAssist to get a
|
||||
different set of path segments.
|
||||
*/
|
||||
static SkDiscretePathEffect* Create(SkScalar segLength, SkScalar deviation) {
|
||||
return SkNEW_ARGS(SkDiscretePathEffect, (segLength, deviation));
|
||||
static SkDiscretePathEffect* Create(SkScalar segLength,
|
||||
SkScalar deviation,
|
||||
uint32_t seedAssist=0) {
|
||||
return SkNEW_ARGS(SkDiscretePathEffect,
|
||||
(segLength, deviation, seedAssist));
|
||||
}
|
||||
|
||||
virtual bool filterPath(SkPath* dst, const SkPath& src,
|
||||
@ -30,13 +42,18 @@ public:
|
||||
SK_DECLARE_PUBLIC_FLATTENABLE_DESERIALIZATION_PROCS(SkDiscretePathEffect)
|
||||
|
||||
protected:
|
||||
SkDiscretePathEffect(SkScalar segLength, SkScalar deviation);
|
||||
SkDiscretePathEffect(SkScalar segLength,
|
||||
SkScalar deviation,
|
||||
uint32_t seedAssist);
|
||||
explicit SkDiscretePathEffect(SkReadBuffer&);
|
||||
virtual void flatten(SkWriteBuffer&) const SK_OVERRIDE;
|
||||
|
||||
private:
|
||||
SkScalar fSegLength, fPerterb;
|
||||
|
||||
/* Caller-supplied 32 bit seed assist */
|
||||
uint32_t fSeedAssist;
|
||||
|
||||
typedef SkPathEffect INHERITED;
|
||||
};
|
||||
|
||||
|
@ -20,9 +20,10 @@ static void Perterb(SkPoint* p, const SkVector& tangent, SkScalar scale) {
|
||||
*p += normal;
|
||||
}
|
||||
|
||||
|
||||
SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength, SkScalar deviation)
|
||||
: fSegLength(segLength), fPerterb(deviation)
|
||||
SkDiscretePathEffect::SkDiscretePathEffect(SkScalar segLength,
|
||||
SkScalar deviation,
|
||||
uint32_t seedAssist)
|
||||
: fSegLength(segLength), fPerterb(deviation), fSeedAssist(seedAssist)
|
||||
{
|
||||
}
|
||||
|
||||
@ -31,7 +32,10 @@ bool SkDiscretePathEffect::filterPath(SkPath* dst, const SkPath& src,
|
||||
bool doFill = rec->isFillStyle();
|
||||
|
||||
SkPathMeasure meas(src, doFill);
|
||||
uint32_t seed = SkScalarRoundToInt(meas.getLength());
|
||||
|
||||
/* Caller may supply their own seed assist, which by default is 0 */
|
||||
uint32_t seed = fSeedAssist ^ SkScalarRoundToInt(meas.getLength());
|
||||
|
||||
SkLCGRandom rand(seed ^ ((seed << 16) | (seed >> 16)));
|
||||
SkScalar scale = fPerterb;
|
||||
SkPoint p;
|
||||
@ -75,9 +79,11 @@ void SkDiscretePathEffect::flatten(SkWriteBuffer& buffer) const {
|
||||
this->INHERITED::flatten(buffer);
|
||||
buffer.writeScalar(fSegLength);
|
||||
buffer.writeScalar(fPerterb);
|
||||
buffer.writeUInt(fSeedAssist);
|
||||
}
|
||||
|
||||
SkDiscretePathEffect::SkDiscretePathEffect(SkReadBuffer& buffer) {
|
||||
fSegLength = buffer.readScalar();
|
||||
fPerterb = buffer.readScalar();
|
||||
fSeedAssist = buffer.readUInt();
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user