Remove fuzz samples.
We now have a real fuzzer, and these samples only run on local dev machine anyway, so their current utility is quite low since they don't demonstrate any specific behavior. Bug: skia:8259 Change-Id: If44a0eaa161b1d7688dd3de6431414a84b7bd6c6 Reviewed-on: https://skia-review.googlesource.com/c/194862 Reviewed-by: Kevin Lubick <kjlubick@google.com> Commit-Queue: Ben Wagner <bungeman@google.com>
This commit is contained in:
parent
2f103f0d04
commit
7465943b1e
@ -45,7 +45,6 @@ samples_sources = [
|
||||
"$_samplecode/SampleFilter2.cpp",
|
||||
"$_samplecode/SampleFilterQuality.cpp",
|
||||
"$_samplecode/SampleFlutterAnimate.cpp",
|
||||
"$_samplecode/SampleFuzz.cpp",
|
||||
"$_samplecode/SampleGlyphTransform.cpp",
|
||||
"$_samplecode/SampleGradients.cpp",
|
||||
"$_samplecode/SampleHairCurves.cpp",
|
||||
@ -68,7 +67,6 @@ samples_sources = [
|
||||
"$_samplecode/SamplePathText.cpp",
|
||||
"$_samplecode/SamplePathClip.cpp",
|
||||
"$_samplecode/SamplePathEffects.cpp",
|
||||
"$_samplecode/SamplePathFuzz.cpp",
|
||||
"$_samplecode/SamplePathOverstroke.cpp",
|
||||
"$_samplecode/SamplePdfFileViewer.cpp",
|
||||
"$_samplecode/SamplePoints.cpp",
|
||||
|
@ -1,390 +0,0 @@
|
||||
/*
|
||||
* Copyright 2011 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "Sample.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkMaskFilter.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkRandom.h"
|
||||
|
||||
static void set2x3(SkMatrix* m, float a, float b, float c, float d, float e, float f) {
|
||||
m->reset();
|
||||
m->set(0, a);
|
||||
m->set(1, b);
|
||||
m->set(2, c);
|
||||
m->set(3, d);
|
||||
m->set(4, e);
|
||||
m->set(5, f);
|
||||
}
|
||||
|
||||
static SkRandom gRand;
|
||||
static bool return_large;
|
||||
static bool return_undef;
|
||||
static bool quick;
|
||||
static bool scale_large;
|
||||
static int scval = 1;
|
||||
static float transval = 0;
|
||||
|
||||
static int R(float x) {
|
||||
return (int)floor(SkScalarToFloat(gRand.nextUScalar1()) * x);
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
#pragma warning ( push )
|
||||
// we are intentionally causing an overflow here
|
||||
// (warning C4756: overflow in constant arithmetic)
|
||||
#pragma warning ( disable : 4756 )
|
||||
#endif
|
||||
|
||||
static float huge() {
|
||||
double d = 1e100;
|
||||
float f = (float)d;
|
||||
return f;
|
||||
}
|
||||
|
||||
#if defined _WIN32
|
||||
#pragma warning ( pop )
|
||||
#endif
|
||||
|
||||
static float make_number() {
|
||||
float v = 0;
|
||||
int sel;
|
||||
|
||||
if (return_large == true && R(3) == 1) {
|
||||
sel = R(6);
|
||||
} else {
|
||||
sel = R(4);
|
||||
}
|
||||
|
||||
if (return_undef == false && sel == 0) {
|
||||
sel = 1;
|
||||
}
|
||||
|
||||
if (R(2) == 1) {
|
||||
v = (float)R(100);
|
||||
} else {
|
||||
|
||||
switch (sel) {
|
||||
case 0: break;
|
||||
case 1: v = 0; break;
|
||||
case 2: v = 0.000001f; break;
|
||||
case 3: v = 10000; break;
|
||||
case 4: v = 2000000000; break;
|
||||
case 5: v = huge(); break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
if (R(4) == 1) {
|
||||
v = -v;
|
||||
}
|
||||
|
||||
return v;
|
||||
}
|
||||
|
||||
static SkColor make_color() {
|
||||
if (R(2) == 1) return 0xFFC0F0A0; else return 0xFF000090;
|
||||
}
|
||||
|
||||
|
||||
static SkColor make_fill() {
|
||||
#if 0
|
||||
int sel;
|
||||
|
||||
if (quick == true) sel = 0; else sel = R(6);
|
||||
|
||||
switch (sel) {
|
||||
|
||||
case 0:
|
||||
case 1:
|
||||
case 2:
|
||||
return make_color();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
var r = ctx.createLinearGradient(make_number(),make_number(),make_number(),make_number());
|
||||
for (i=0;i<4;i++)
|
||||
r.addColorStop(make_number(),make_color());
|
||||
return r;
|
||||
break;
|
||||
|
||||
case 4:
|
||||
var r = ctx.createRadialGradient(make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
|
||||
for (i=0;i<4;i++)
|
||||
r.addColorStop(make_number(),make_color());
|
||||
return r;
|
||||
break;
|
||||
|
||||
case 5:
|
||||
var r = ctx.createPattern(imgObj,"repeat");
|
||||
if (R(6) == 0)
|
||||
r.addColorStop(make_number(),make_color());
|
||||
return r;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
return make_color();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static void do_fuzz(SkCanvas* canvas) {
|
||||
SkPath path;
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
for (int i=0;i<100;i++) {
|
||||
switch (R(33)) {
|
||||
|
||||
case 0:
|
||||
paint.setColor(make_fill());
|
||||
break;
|
||||
|
||||
case 1:
|
||||
paint.setAlpha(gRand.nextU() & 0xFF);
|
||||
break;
|
||||
|
||||
case 2: {
|
||||
SkBlendMode mode;
|
||||
switch (R(3)) {
|
||||
case 0: mode = SkBlendMode::kSrc; break;
|
||||
case 1: mode = SkBlendMode::kXor; break;
|
||||
case 2:
|
||||
default: // silence warning
|
||||
mode = SkBlendMode::kSrcOver; break;
|
||||
}
|
||||
paint.setBlendMode(mode);
|
||||
}
|
||||
break;
|
||||
|
||||
case 3:
|
||||
switch (R(2)) {
|
||||
case 0: paint.setStrokeCap(SkPaint::kRound_Cap); break;
|
||||
case 1: paint.setStrokeCap(SkPaint::kButt_Cap); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 4:
|
||||
switch (R(2)) {
|
||||
case 0: paint.setStrokeJoin(SkPaint::kRound_Join); break;
|
||||
case 1: paint.setStrokeJoin(SkPaint::kMiter_Join); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case 5:
|
||||
paint.setStrokeWidth(make_number());
|
||||
break;
|
||||
|
||||
case 6:
|
||||
paint.setStrokeMiter(make_number());
|
||||
break;
|
||||
|
||||
case 7:
|
||||
if (quick == true) break;
|
||||
paint.setMaskFilter(SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, make_number()));
|
||||
break;
|
||||
|
||||
case 8:
|
||||
if (quick == true) break;
|
||||
//ctx.shadowColor = make_fill();
|
||||
break;
|
||||
|
||||
case 9:
|
||||
if (quick == true) break;
|
||||
//ctx.shadowOffsetX = make_number();
|
||||
//ctx.shadowOffsetY = make_number();
|
||||
break;
|
||||
|
||||
case 10:
|
||||
canvas->restore();
|
||||
break;
|
||||
|
||||
case 11:
|
||||
canvas->rotate(make_number());
|
||||
break;
|
||||
|
||||
case 12:
|
||||
canvas->save();
|
||||
break;
|
||||
|
||||
case 13:
|
||||
canvas->scale(-1,-1);
|
||||
break;
|
||||
|
||||
case 14:
|
||||
|
||||
if (quick == true) break;
|
||||
|
||||
if (transval == 0) {
|
||||
transval = make_number();
|
||||
canvas->translate(transval,0);
|
||||
} else {
|
||||
canvas->translate(-transval,0);
|
||||
transval = 0;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case 15: {
|
||||
SkRect r;
|
||||
r.set(make_number(),make_number(),make_number(),make_number());
|
||||
SkPaint::Style s = paint.getStyle();
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
canvas->drawRect(r, paint);
|
||||
paint.setStyle(s);
|
||||
// clearrect
|
||||
} break;
|
||||
|
||||
case 16:
|
||||
if (quick == true) break;
|
||||
// ctx.drawImage(imgObj,make_number(),make_number(),make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
|
||||
break;
|
||||
|
||||
case 17: {
|
||||
SkRect r;
|
||||
r.set(make_number(),make_number(),make_number(),make_number());
|
||||
SkPaint::Style s = paint.getStyle();
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
canvas->drawRect(r, paint);
|
||||
paint.setStyle(s);
|
||||
} break;
|
||||
|
||||
case 18:
|
||||
path.reset();
|
||||
break;
|
||||
|
||||
case 19:
|
||||
// ctx.clip() is evil.
|
||||
break;
|
||||
|
||||
case 20:
|
||||
path.close();
|
||||
break;
|
||||
|
||||
case 21: {
|
||||
SkPaint::Style s = paint.getStyle();
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
canvas->drawPath(path, paint);
|
||||
paint.setStyle(s);
|
||||
} break;
|
||||
|
||||
case 22: {
|
||||
SkPaint::Style s = paint.getStyle();
|
||||
paint.setStyle(SkPaint::kFill_Style);
|
||||
canvas->drawPath(path, paint);
|
||||
paint.setStyle(s);
|
||||
} break;
|
||||
|
||||
case 23: {
|
||||
SkRect r;
|
||||
r.set(make_number(),make_number(),make_number(),make_number());
|
||||
SkPaint::Style s = paint.getStyle();
|
||||
paint.setStyle(SkPaint::kStroke_Style);
|
||||
canvas->drawRect(r, paint);
|
||||
paint.setStyle(s);
|
||||
} break;
|
||||
|
||||
case 24:
|
||||
if (quick == true) break;
|
||||
//ctx.arc(make_number(),make_number(),make_number(),make_number(),make_number(),true);
|
||||
break;
|
||||
|
||||
case 25:
|
||||
if (quick == true) break;
|
||||
//ctx.arcTo(make_number(),make_number(),make_number(),make_number(),make_number());
|
||||
break;
|
||||
|
||||
case 26:
|
||||
if (quick == true) break;
|
||||
//ctx.bezierCurveTo(make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
|
||||
break;
|
||||
|
||||
case 27:
|
||||
path.lineTo(make_number(),make_number());
|
||||
break;
|
||||
|
||||
case 28:
|
||||
path.moveTo(make_number(),make_number());
|
||||
break;
|
||||
|
||||
case 29:
|
||||
if (quick == true) break;
|
||||
path.quadTo(make_number(),make_number(),make_number(),make_number());
|
||||
break;
|
||||
|
||||
case 30: {
|
||||
if (quick == true) break;
|
||||
SkMatrix matrix;
|
||||
set2x3(&matrix, make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
|
||||
canvas->concat(matrix);
|
||||
} break;
|
||||
|
||||
case 31: {
|
||||
if (quick == true) break;
|
||||
SkMatrix matrix;
|
||||
set2x3(&matrix, make_number(),make_number(),make_number(),make_number(),make_number(),make_number());
|
||||
canvas->setMatrix(matrix);
|
||||
} break;
|
||||
|
||||
case 32:
|
||||
|
||||
if (scale_large == true) {
|
||||
|
||||
switch (scval) {
|
||||
case 0: canvas->scale(-1000000000,1);
|
||||
canvas->scale(-1000000000,1);
|
||||
scval = 1; break;
|
||||
case 1: canvas->scale(-.000000001f,1); scval = 2; break;
|
||||
case 2: canvas->scale(-.000000001f,1); scval = 0; break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
class FuzzView : public Sample {
|
||||
public:
|
||||
FuzzView() {
|
||||
this->setBGColor(0xFFDDDDDD);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual bool onQuery(Sample::Event* evt) {
|
||||
if (Sample::TitleQ(*evt)) {
|
||||
Sample::TitleR(evt, "Fuzzer");
|
||||
return true;
|
||||
}
|
||||
return this->INHERITED::onQuery(evt);
|
||||
}
|
||||
|
||||
void drawBG(SkCanvas* canvas) {
|
||||
canvas->drawColor(0xFFDDDDDD);
|
||||
}
|
||||
|
||||
virtual void onDrawContent(SkCanvas* canvas) {
|
||||
do_fuzz(canvas);
|
||||
}
|
||||
|
||||
private:
|
||||
typedef Sample INHERITED;
|
||||
};
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
DEF_SAMPLE( return new FuzzView(); )
|
@ -1,697 +0,0 @@
|
||||
/*
|
||||
* Copyright 2015 Google Inc.
|
||||
*
|
||||
* Use of this source code is governed by a BSD-style license that can be
|
||||
* found in the LICENSE file.
|
||||
*/
|
||||
|
||||
#include "Sample.h"
|
||||
#include "SkCanvas.h"
|
||||
#include "SkPaint.h"
|
||||
#include "SkPath.h"
|
||||
#include "SkMatrix.h"
|
||||
#include "SkColor.h"
|
||||
#include "SkTDArray.h"
|
||||
#include "SkRandom.h"
|
||||
#include "SkRRect.h"
|
||||
|
||||
enum RandomAddPath {
|
||||
kMoveToPath,
|
||||
kRMoveToPath,
|
||||
kLineToPath,
|
||||
kRLineToPath,
|
||||
kQuadToPath,
|
||||
kRQuadToPath,
|
||||
kConicToPath,
|
||||
kRConicToPath,
|
||||
kCubicToPath,
|
||||
kRCubicToPath,
|
||||
kArcToPath,
|
||||
kArcTo2Path,
|
||||
kClosePath,
|
||||
kAddArc,
|
||||
kAddRoundRect1,
|
||||
kAddRoundRect2,
|
||||
kAddRRect,
|
||||
kAddPoly,
|
||||
kAddPath1,
|
||||
kAddPath2,
|
||||
kAddPath3,
|
||||
kReverseAddPath,
|
||||
};
|
||||
|
||||
const int kRandomAddPath_Last = kReverseAddPath;
|
||||
|
||||
const char* gRandomAddPathNames[] = {
|
||||
"kMoveToPath",
|
||||
"kRMoveToPath",
|
||||
"kLineToPath",
|
||||
"kRLineToPath",
|
||||
"kQuadToPath",
|
||||
"kRQuadToPath",
|
||||
"kConicToPath",
|
||||
"kRConicToPath",
|
||||
"kCubicToPath",
|
||||
"kRCubicToPath",
|
||||
"kArcToPath",
|
||||
"kArcTo2Path",
|
||||
"kClosePath",
|
||||
"kAddArc",
|
||||
"kAddRoundRect1",
|
||||
"kAddRoundRect2",
|
||||
"kAddRRect",
|
||||
"kAddPoly",
|
||||
"kAddPath1",
|
||||
"kAddPath2",
|
||||
"kAddPath3",
|
||||
"kReverseAddPath",
|
||||
};
|
||||
|
||||
enum RandomSetRRect {
|
||||
kSetEmpty,
|
||||
kSetRect,
|
||||
kSetOval,
|
||||
kSetRectXY,
|
||||
kSetNinePatch,
|
||||
kSetRectRadii,
|
||||
};
|
||||
|
||||
const char* gRandomSetRRectNames[] = {
|
||||
"kSetEmpty",
|
||||
"kSetRect",
|
||||
"kSetOval",
|
||||
"kSetRectXY",
|
||||
"kSetNinePatch",
|
||||
"kSetRectRadii",
|
||||
};
|
||||
|
||||
int kRandomSetRRect_Last = kSetRectRadii;
|
||||
|
||||
enum RandomSetMatrix {
|
||||
kSetIdentity,
|
||||
kSetTranslate,
|
||||
kSetTranslateX,
|
||||
kSetTranslateY,
|
||||
kSetScale,
|
||||
kSetScaleTranslate,
|
||||
kSetScaleX,
|
||||
kSetScaleY,
|
||||
kSetSkew,
|
||||
kSetSkewTranslate,
|
||||
kSetSkewX,
|
||||
kSetSkewY,
|
||||
kSetRotate,
|
||||
kSetRotateTranslate,
|
||||
kSetPerspectiveX,
|
||||
kSetPerspectiveY,
|
||||
kSetAll,
|
||||
};
|
||||
|
||||
int kRandomSetMatrix_Last = kSetAll;
|
||||
|
||||
const char* gRandomSetMatrixNames[] = {
|
||||
"kSetIdentity",
|
||||
"kSetTranslate",
|
||||
"kSetTranslateX",
|
||||
"kSetTranslateY",
|
||||
"kSetScale",
|
||||
"kSetScaleTranslate",
|
||||
"kSetScaleX",
|
||||
"kSetScaleY",
|
||||
"kSetSkew",
|
||||
"kSetSkewTranslate",
|
||||
"kSetSkewX",
|
||||
"kSetSkewY",
|
||||
"kSetRotate",
|
||||
"kSetRotateTranslate",
|
||||
"kSetPerspectiveX",
|
||||
"kSetPerspectiveY",
|
||||
"kSetAll",
|
||||
};
|
||||
|
||||
class FuzzPath {
|
||||
public:
|
||||
FuzzPath()
|
||||
: fFloatMin(0)
|
||||
, fFloatMax(800)
|
||||
, fAddCount(0)
|
||||
, fPrintName(false)
|
||||
, fStrokeOnly(false)
|
||||
, fValidate(false)
|
||||
{
|
||||
fTab = " ";
|
||||
}
|
||||
void randomize() {
|
||||
fPathDepth = 0;
|
||||
fPathDepthLimit = fRand.nextRangeU(1, 2);
|
||||
fPathContourCount = fRand.nextRangeU(1, 4);
|
||||
fPathSegmentLimit = fRand.nextRangeU(1, 8);
|
||||
fClip = makePath();
|
||||
SkASSERT(!fPathDepth);
|
||||
fMatrix = makeMatrix();
|
||||
fPaint = makePaint();
|
||||
fPathDepthLimit = fRand.nextRangeU(1, 3);
|
||||
fPathContourCount = fRand.nextRangeU(1, 6);
|
||||
fPathSegmentLimit = fRand.nextRangeU(1, 16);
|
||||
fPath = makePath();
|
||||
SkASSERT(!fPathDepth);
|
||||
}
|
||||
|
||||
const SkPath& getClip() const {
|
||||
return fClip;
|
||||
}
|
||||
|
||||
const SkMatrix& getMatrix() const {
|
||||
return fMatrix;
|
||||
}
|
||||
|
||||
const SkPaint& getPaint() const {
|
||||
return fPaint;
|
||||
}
|
||||
|
||||
const SkPath& getPath() const {
|
||||
return fPath;
|
||||
}
|
||||
|
||||
void setSeed(int seed) {
|
||||
fRand.setSeed(seed);
|
||||
}
|
||||
|
||||
void setStrokeOnly() {
|
||||
fStrokeOnly = true;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
SkPath::AddPathMode makeAddPathMode() {
|
||||
return (SkPath::AddPathMode) fRand.nextRangeU(SkPath::kAppend_AddPathMode,
|
||||
SkPath::kExtend_AddPathMode);
|
||||
}
|
||||
|
||||
RandomAddPath makeAddPathType() {
|
||||
return (RandomAddPath) fRand.nextRangeU(0, kRandomAddPath_Last);
|
||||
}
|
||||
|
||||
SkScalar makeAngle() {
|
||||
SkScalar angle;
|
||||
angle = fRand.nextF();
|
||||
return angle;
|
||||
}
|
||||
|
||||
bool makeBool() {
|
||||
return fRand.nextBool();
|
||||
}
|
||||
|
||||
SkPath::Direction makeDirection() {
|
||||
return (SkPath::Direction) fRand.nextRangeU(SkPath::kCW_Direction, SkPath::kCCW_Direction);
|
||||
}
|
||||
|
||||
SkMatrix makeMatrix() {
|
||||
SkMatrix matrix;
|
||||
matrix.reset();
|
||||
RandomSetMatrix setMatrix = (RandomSetMatrix) fRand.nextRangeU(0, kRandomSetMatrix_Last);
|
||||
if (fPrintName) {
|
||||
SkDebugf("%.*s%s\n", fPathDepth * 3, fTab, gRandomSetMatrixNames[setMatrix]);
|
||||
}
|
||||
switch (setMatrix) {
|
||||
case kSetIdentity:
|
||||
break;
|
||||
case kSetTranslateX:
|
||||
matrix.setTranslateX(makeScalar());
|
||||
break;
|
||||
case kSetTranslateY:
|
||||
matrix.setTranslateY(makeScalar());
|
||||
break;
|
||||
case kSetTranslate:
|
||||
matrix.setTranslate(makeScalar(), makeScalar());
|
||||
break;
|
||||
case kSetScaleX:
|
||||
matrix.setScaleX(makeScalar());
|
||||
break;
|
||||
case kSetScaleY:
|
||||
matrix.setScaleY(makeScalar());
|
||||
break;
|
||||
case kSetScale:
|
||||
matrix.setScale(makeScalar(), makeScalar());
|
||||
break;
|
||||
case kSetScaleTranslate:
|
||||
matrix.setScale(makeScalar(), makeScalar(), makeScalar(), makeScalar());
|
||||
break;
|
||||
case kSetSkewX:
|
||||
matrix.setSkewX(makeScalar());
|
||||
break;
|
||||
case kSetSkewY:
|
||||
matrix.setSkewY(makeScalar());
|
||||
break;
|
||||
case kSetSkew:
|
||||
matrix.setSkew(makeScalar(), makeScalar());
|
||||
break;
|
||||
case kSetSkewTranslate:
|
||||
matrix.setSkew(makeScalar(), makeScalar(), makeScalar(), makeScalar());
|
||||
break;
|
||||
case kSetRotate:
|
||||
matrix.setRotate(makeScalar());
|
||||
break;
|
||||
case kSetRotateTranslate:
|
||||
matrix.setRotate(makeScalar(), makeScalar(), makeScalar());
|
||||
break;
|
||||
case kSetPerspectiveX:
|
||||
matrix.setPerspX(makeScalar());
|
||||
break;
|
||||
case kSetPerspectiveY:
|
||||
matrix.setPerspY(makeScalar());
|
||||
break;
|
||||
case kSetAll:
|
||||
matrix.setAll(makeScalar(), makeScalar(), makeScalar(),
|
||||
makeScalar(), makeScalar(), makeScalar(),
|
||||
makeScalar(), makeScalar(), makeScalar());
|
||||
break;
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
SkPaint makePaint() {
|
||||
SkPaint paint;
|
||||
bool antiAlias = fRand.nextBool();
|
||||
paint.setAntiAlias(antiAlias);
|
||||
SkPaint::Style style = fStrokeOnly ? SkPaint::kStroke_Style :
|
||||
(SkPaint::Style) fRand.nextRangeU(SkPaint::kFill_Style, SkPaint::kStrokeAndFill_Style);
|
||||
paint.setStyle(style);
|
||||
SkColor color = (SkColor) fRand.nextU();
|
||||
paint.setColor(color);
|
||||
SkScalar width = fRand.nextRangeF(0, 10);
|
||||
paint.setStrokeWidth(width);
|
||||
SkScalar miter = makeScalar();
|
||||
paint.setStrokeMiter(miter);
|
||||
SkPaint::Cap cap = (SkPaint::Cap) fRand.nextRangeU(SkPaint::kButt_Cap, SkPaint::kSquare_Cap);
|
||||
paint.setStrokeCap(cap);
|
||||
SkPaint::Join join = (SkPaint::Join) fRand.nextRangeU(SkPaint::kMiter_Join,
|
||||
SkPaint::kBevel_Join);
|
||||
paint.setStrokeJoin(join);
|
||||
return paint;
|
||||
}
|
||||
|
||||
SkPoint makePoint() {
|
||||
SkPoint result;
|
||||
makeScalarArray(2, &result.fX);
|
||||
return result;
|
||||
}
|
||||
|
||||
void makePointArray(size_t arrayCount, SkPoint* points) {
|
||||
for (size_t index = 0; index < arrayCount; ++index) {
|
||||
points[index] = makePoint();
|
||||
}
|
||||
}
|
||||
|
||||
void makePointArray(SkTDArray<SkPoint>* points) {
|
||||
size_t arrayCount = fRand.nextRangeU(1, 10);
|
||||
for (size_t index = 0; index < arrayCount; ++index) {
|
||||
*points->append() = makePoint();
|
||||
}
|
||||
}
|
||||
|
||||
SkRect makeRect() {
|
||||
SkRect result;
|
||||
makeScalarArray(4, &result.fLeft);
|
||||
return result;
|
||||
}
|
||||
|
||||
SkRRect makeRRect() {
|
||||
SkRRect rrect;
|
||||
RandomSetRRect rrectType = makeSetRRectType();
|
||||
if (fPrintName) {
|
||||
SkDebugf("%.*s%s\n", fPathDepth * 3, fTab, gRandomSetRRectNames[rrectType]);
|
||||
}
|
||||
switch (rrectType) {
|
||||
case kSetEmpty:
|
||||
rrect.setEmpty();
|
||||
break;
|
||||
case kSetRect: {
|
||||
SkRect rect = makeRect();
|
||||
rrect.setRect(rect);
|
||||
} break;
|
||||
case kSetOval: {
|
||||
SkRect oval = makeRect();
|
||||
rrect.setOval(oval);
|
||||
} break;
|
||||
case kSetRectXY: {
|
||||
SkRect rect = makeRect();
|
||||
SkScalar xRad = makeScalar();
|
||||
SkScalar yRad = makeScalar();
|
||||
rrect.setRectXY(rect, xRad, yRad);
|
||||
} break;
|
||||
case kSetNinePatch: {
|
||||
SkRect rect = makeRect();
|
||||
SkScalar leftRad = makeScalar();
|
||||
SkScalar topRad = makeScalar();
|
||||
SkScalar rightRad = makeScalar();
|
||||
SkScalar bottomRad = makeScalar();
|
||||
rrect.setNinePatch(rect, leftRad, topRad, rightRad, bottomRad);
|
||||
SkDebugf(""); // keep locals in scope
|
||||
} break;
|
||||
case kSetRectRadii: {
|
||||
SkRect rect = makeRect();
|
||||
SkVector radii[4];
|
||||
makeVectorArray(SK_ARRAY_COUNT(radii), radii);
|
||||
rrect.setRectRadii(rect, radii);
|
||||
} break;
|
||||
}
|
||||
return rrect;
|
||||
}
|
||||
|
||||
SkPath makePath() {
|
||||
SkPath path;
|
||||
for (uint32_t cIndex = 0; cIndex < fPathContourCount; ++cIndex) {
|
||||
uint32_t segments = makeSegmentCount();
|
||||
for (uint32_t sIndex = 0; sIndex < segments; ++sIndex) {
|
||||
RandomAddPath addPathType = makeAddPathType();
|
||||
++fAddCount;
|
||||
if (fPrintName) {
|
||||
SkDebugf("%.*s%s\n", fPathDepth * 3, fTab,
|
||||
gRandomAddPathNames[addPathType]);
|
||||
}
|
||||
switch (addPathType) {
|
||||
case kAddArc: {
|
||||
SkRect oval = makeRect();
|
||||
SkScalar startAngle = makeAngle();
|
||||
SkScalar sweepAngle = makeAngle();
|
||||
path.addArc(oval, startAngle, sweepAngle);
|
||||
validate(path);
|
||||
} break;
|
||||
case kAddRoundRect1: {
|
||||
SkRect rect = makeRect();
|
||||
SkScalar rx = makeScalar(), ry = makeScalar();
|
||||
SkPath::Direction dir = makeDirection();
|
||||
path.addRoundRect(rect, rx, ry, dir);
|
||||
validate(path);
|
||||
} break;
|
||||
case kAddRoundRect2: {
|
||||
SkRect rect = makeRect();
|
||||
SkScalar radii[8];
|
||||
makeScalarArray(SK_ARRAY_COUNT(radii), radii);
|
||||
SkPath::Direction dir = makeDirection();
|
||||
path.addRoundRect(rect, radii, dir);
|
||||
validate(path);
|
||||
} break;
|
||||
case kAddRRect: {
|
||||
SkRRect rrect = makeRRect();
|
||||
SkPath::Direction dir = makeDirection();
|
||||
path.addRRect(rrect, dir);
|
||||
validate(path);
|
||||
} break;
|
||||
case kAddPoly: {
|
||||
SkTDArray<SkPoint> points;
|
||||
makePointArray(&points);
|
||||
bool close = makeBool();
|
||||
path.addPoly(&points[0], points.count(), close);
|
||||
validate(path);
|
||||
} break;
|
||||
case kAddPath1:
|
||||
if (fPathDepth < fPathDepthLimit) {
|
||||
++fPathDepth;
|
||||
SkPath src = makePath();
|
||||
validate(src);
|
||||
SkScalar dx = makeScalar();
|
||||
SkScalar dy = makeScalar();
|
||||
SkPath::AddPathMode mode = makeAddPathMode();
|
||||
path.addPath(src, dx, dy, mode);
|
||||
--fPathDepth;
|
||||
validate(path);
|
||||
}
|
||||
break;
|
||||
case kAddPath2:
|
||||
if (fPathDepth < fPathDepthLimit) {
|
||||
++fPathDepth;
|
||||
SkPath src = makePath();
|
||||
validate(src);
|
||||
SkPath::AddPathMode mode = makeAddPathMode();
|
||||
path.addPath(src, mode);
|
||||
--fPathDepth;
|
||||
validate(path);
|
||||
}
|
||||
break;
|
||||
case kAddPath3:
|
||||
if (fPathDepth < fPathDepthLimit) {
|
||||
++fPathDepth;
|
||||
SkPath src = makePath();
|
||||
validate(src);
|
||||
SkMatrix matrix = makeMatrix();
|
||||
SkPath::AddPathMode mode = makeAddPathMode();
|
||||
path.addPath(src, matrix, mode);
|
||||
--fPathDepth;
|
||||
validate(path);
|
||||
}
|
||||
break;
|
||||
case kReverseAddPath:
|
||||
if (fPathDepth < fPathDepthLimit) {
|
||||
++fPathDepth;
|
||||
SkPath src = makePath();
|
||||
validate(src);
|
||||
path.reverseAddPath(src);
|
||||
--fPathDepth;
|
||||
validate(path);
|
||||
}
|
||||
break;
|
||||
case kMoveToPath: {
|
||||
SkScalar x = makeScalar();
|
||||
SkScalar y = makeScalar();
|
||||
path.moveTo(x, y);
|
||||
validate(path);
|
||||
} break;
|
||||
case kRMoveToPath: {
|
||||
SkScalar x = makeScalar();
|
||||
SkScalar y = makeScalar();
|
||||
path.rMoveTo(x, y);
|
||||
validate(path);
|
||||
} break;
|
||||
case kLineToPath: {
|
||||
SkScalar x = makeScalar();
|
||||
SkScalar y = makeScalar();
|
||||
path.lineTo(x, y);
|
||||
validate(path);
|
||||
} break;
|
||||
case kRLineToPath: {
|
||||
SkScalar x = makeScalar();
|
||||
SkScalar y = makeScalar();
|
||||
path.rLineTo(x, y);
|
||||
validate(path);
|
||||
} break;
|
||||
case kQuadToPath: {
|
||||
SkPoint pt[2];
|
||||
makePointArray(SK_ARRAY_COUNT(pt), pt);
|
||||
path.quadTo(pt[0], pt[1]);
|
||||
validate(path);
|
||||
} break;
|
||||
case kRQuadToPath: {
|
||||
SkPoint pt[2];
|
||||
makePointArray(SK_ARRAY_COUNT(pt), pt);
|
||||
path.rQuadTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY);
|
||||
validate(path);
|
||||
} break;
|
||||
case kConicToPath: {
|
||||
SkPoint pt[2];
|
||||
makePointArray(SK_ARRAY_COUNT(pt), pt);
|
||||
SkScalar weight = makeScalar();
|
||||
path.conicTo(pt[0], pt[1], weight);
|
||||
validate(path);
|
||||
} break;
|
||||
case kRConicToPath: {
|
||||
SkPoint pt[2];
|
||||
makePointArray(SK_ARRAY_COUNT(pt), pt);
|
||||
SkScalar weight = makeScalar();
|
||||
path.rConicTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY, weight);
|
||||
validate(path);
|
||||
} break;
|
||||
case kCubicToPath: {
|
||||
SkPoint pt[3];
|
||||
makePointArray(SK_ARRAY_COUNT(pt), pt);
|
||||
path.cubicTo(pt[0], pt[1], pt[2]);
|
||||
validate(path);
|
||||
} break;
|
||||
case kRCubicToPath: {
|
||||
SkPoint pt[3];
|
||||
makePointArray(SK_ARRAY_COUNT(pt), pt);
|
||||
path.rCubicTo(pt[0].fX, pt[0].fY, pt[1].fX, pt[1].fY, pt[2].fX, pt[2].fY);
|
||||
validate(path);
|
||||
} break;
|
||||
case kArcToPath: {
|
||||
SkPoint pt[2];
|
||||
makePointArray(SK_ARRAY_COUNT(pt), pt);
|
||||
SkScalar radius = makeScalar();
|
||||
path.arcTo(pt[0], pt[1], radius);
|
||||
validate(path);
|
||||
} break;
|
||||
case kArcTo2Path: {
|
||||
SkRect oval = makeRect();
|
||||
SkScalar startAngle = makeAngle();
|
||||
SkScalar sweepAngle = makeAngle();
|
||||
bool forceMoveTo = makeBool();
|
||||
path.arcTo(oval, startAngle, sweepAngle, forceMoveTo);
|
||||
validate(path);
|
||||
} break;
|
||||
case kClosePath:
|
||||
path.close();
|
||||
validate(path);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return path;
|
||||
}
|
||||
|
||||
uint32_t makeSegmentCount() {
|
||||
return fRand.nextRangeU(1, fPathSegmentLimit);
|
||||
}
|
||||
|
||||
RandomSetRRect makeSetRRectType() {
|
||||
return (RandomSetRRect) fRand.nextRangeU(0, kRandomSetRRect_Last);
|
||||
}
|
||||
|
||||
SkScalar makeScalar() {
|
||||
SkScalar scalar;
|
||||
scalar = fRand.nextRangeF(fFloatMin, fFloatMax);
|
||||
return scalar;
|
||||
}
|
||||
|
||||
void makeScalarArray(size_t arrayCount, SkScalar* array) {
|
||||
for (size_t index = 0; index < arrayCount; ++index) {
|
||||
array[index] = makeScalar();
|
||||
}
|
||||
}
|
||||
|
||||
void makeVectorArray(size_t arrayCount, SkVector* array) {
|
||||
for (size_t index = 0; index < arrayCount; ++index) {
|
||||
array[index] = makeVector();
|
||||
}
|
||||
}
|
||||
|
||||
SkVector makeVector() {
|
||||
SkVector result;
|
||||
makeScalarArray(2, &result.fX);
|
||||
return result;
|
||||
}
|
||||
|
||||
void validate(const SkPath& path) {
|
||||
if (fValidate) {
|
||||
// FIXME: this could probably assert on path.isValid() instead
|
||||
SkDEBUGCODE(path.validateRef());
|
||||
}
|
||||
}
|
||||
|
||||
SkRandom fRand;
|
||||
SkMatrix fMatrix;
|
||||
SkPath fClip;
|
||||
SkPaint fPaint;
|
||||
SkPath fPath;
|
||||
SkScalar fFloatMin;
|
||||
SkScalar fFloatMax;
|
||||
uint32_t fPathContourCount;
|
||||
int fPathDepth;
|
||||
int fPathDepthLimit;
|
||||
uint32_t fPathSegmentLimit;
|
||||
int fAddCount;
|
||||
bool fPrintName;
|
||||
bool fStrokeOnly;
|
||||
bool fValidate;
|
||||
const char* fTab;
|
||||
};
|
||||
|
||||
static bool contains_only_moveTo(const SkPath& path) {
|
||||
int verbCount = path.countVerbs();
|
||||
if (verbCount == 0) {
|
||||
return true;
|
||||
}
|
||||
SkTDArray<uint8_t> verbs;
|
||||
verbs.setCount(verbCount);
|
||||
SkDEBUGCODE(int getVerbResult = ) path.getVerbs(verbs.begin(), verbCount);
|
||||
SkASSERT(getVerbResult == verbCount);
|
||||
for (int index = 0; index < verbCount; ++index) {
|
||||
if (verbs[index] != SkPath::kMove_Verb) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#include "SkGraphics.h"
|
||||
#include "SkSurface.h"
|
||||
#include "SkTaskGroup.h"
|
||||
#include "SkTDArray.h"
|
||||
|
||||
static void path_fuzz_stroker(SkBitmap* bitmap, int seed) {
|
||||
SkTaskGroup().batch(100, [&](int i) {
|
||||
int localSeed = seed + i;
|
||||
|
||||
FuzzPath fuzzPath;
|
||||
fuzzPath.setStrokeOnly();
|
||||
fuzzPath.setSeed(localSeed);
|
||||
fuzzPath.randomize();
|
||||
const SkPath& path = fuzzPath.getPath();
|
||||
const SkPaint& paint = fuzzPath.getPaint();
|
||||
const SkImageInfo& info = bitmap->info();
|
||||
std::unique_ptr<SkCanvas> canvas(
|
||||
SkCanvas::MakeRasterDirect(info, bitmap->getPixels(), bitmap->rowBytes()));
|
||||
int w = info.width() / 4;
|
||||
int h = info.height() / 4;
|
||||
int x = localSeed / 4 % 4;
|
||||
int y = localSeed % 4;
|
||||
SkRect clipBounds = SkRect::MakeXYWH(SkIntToScalar(x) * w, SkIntToScalar(y) * h,
|
||||
SkIntToScalar(w), SkIntToScalar(h));
|
||||
canvas->save();
|
||||
canvas->clipRect(clipBounds);
|
||||
canvas->translate(SkIntToScalar(x) * w, SkIntToScalar(y) * h);
|
||||
canvas->drawPath(path, paint);
|
||||
canvas->restore();
|
||||
});
|
||||
}
|
||||
|
||||
class PathFuzzView : public Sample {
|
||||
public:
|
||||
PathFuzzView()
|
||||
: fOneDraw(false)
|
||||
{
|
||||
}
|
||||
protected:
|
||||
bool onQuery(Sample::Event* evt) override {
|
||||
if (Sample::TitleQ(*evt)) {
|
||||
Sample::TitleR(evt, "PathFuzzer");
|
||||
return true;
|
||||
}
|
||||
return this->INHERITED::onQuery(evt);
|
||||
}
|
||||
|
||||
void onOnceBeforeDraw() override {
|
||||
fIndex = 0;
|
||||
SkImageInfo info(SkImageInfo::MakeN32Premul(SkScalarRoundToInt(width()),
|
||||
SkScalarRoundToInt(height())));
|
||||
offscreen.allocPixels(info);
|
||||
path_fuzz_stroker(&offscreen, fIndex);
|
||||
}
|
||||
|
||||
void onDrawContent(SkCanvas* canvas) override {
|
||||
if (fOneDraw) {
|
||||
fuzzPath.randomize();
|
||||
const SkPath& path = fuzzPath.getPath();
|
||||
const SkPaint& paint = fuzzPath.getPaint();
|
||||
const SkPath& clip = fuzzPath.getClip();
|
||||
const SkMatrix& matrix = fuzzPath.getMatrix();
|
||||
if (!contains_only_moveTo(clip)) {
|
||||
canvas->clipPath(clip);
|
||||
}
|
||||
canvas->setMatrix(matrix);
|
||||
canvas->drawPath(path, paint);
|
||||
} else {
|
||||
path_fuzz_stroker(&offscreen, fIndex += 100);
|
||||
canvas->drawBitmap(offscreen, 0, 0);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
int fIndex;
|
||||
SkBitmap offscreen;
|
||||
FuzzPath fuzzPath;
|
||||
bool fOneDraw;
|
||||
typedef Sample INHERITED;
|
||||
};
|
||||
|
||||
DEF_SAMPLE( return new PathFuzzView(); )
|
Loading…
Reference in New Issue
Block a user