Removed degenerate quads from zero radius Chrome-style round rects
https://codereview.appspot.com/6737059/ git-svn-id: http://skia.googlecode.com/svn/trunk@6053 2bbb7eff-a529-9590-31e7-b0007b416f81
This commit is contained in:
parent
c8707d4686
commit
158618ec62
@ -671,8 +671,10 @@ private:
|
||||
typedef SkBenchmark INHERITED;
|
||||
};
|
||||
|
||||
// Chrome creates its own round rects with each corner possibly being different
|
||||
// Note: PathTest::test_arb_round_rect_is_convex performs almost exactly
|
||||
// Chrome creates its own round rects with each corner possibly being different.
|
||||
// In its "zero radius" incarnation it creates degenerate round rects.
|
||||
// Note: PathTest::test_arb_round_rect_is_convex and
|
||||
// test_arb_zero_rad_round_rect_is_rect perform almost exactly
|
||||
// the same test (but with no drawing)
|
||||
class ArbRoundRectBench : public SkBenchmark {
|
||||
protected:
|
||||
@ -682,8 +684,12 @@ protected:
|
||||
N = SkBENCHLOOP(100)
|
||||
};
|
||||
public:
|
||||
ArbRoundRectBench(void* param) : INHERITED(param) {
|
||||
fName.printf("arbroundrect");
|
||||
ArbRoundRectBench(void* param, bool zeroRad) : INHERITED(param), fZeroRad(zeroRad) {
|
||||
if (zeroRad) {
|
||||
fName.printf("zeroradroundrect");
|
||||
} else {
|
||||
fName.printf("arbroundrect");
|
||||
}
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -728,6 +734,7 @@ protected:
|
||||
add_corner_arc(path, r, xCorner, yCorner, 0);
|
||||
add_corner_arc(path, r, xCorner, yCorner, 90);
|
||||
add_corner_arc(path, r, xCorner, yCorner, 180);
|
||||
path->close();
|
||||
|
||||
#ifdef SK_REDEFINE_ROOT2OVER2_TO_MAKE_ARCTOS_CONVEX
|
||||
SkASSERT(path->isConvex());
|
||||
@ -743,24 +750,32 @@ protected:
|
||||
paint.setColor(0xff000000 | rand.nextU());
|
||||
paint.setAntiAlias(true);
|
||||
|
||||
SkScalar radius = rand.nextUScalar1() * 30;
|
||||
if (radius < SK_Scalar1) {
|
||||
SkScalar size = rand.nextUScalar1() * 30;
|
||||
if (size < SK_Scalar1) {
|
||||
continue;
|
||||
}
|
||||
r.fLeft = rand.nextUScalar1() * 300;
|
||||
r.fTop = rand.nextUScalar1() * 300;
|
||||
r.fRight = r.fLeft + 2 * radius;
|
||||
r.fBottom = r.fTop + 2 * radius;
|
||||
r.fRight = r.fLeft + 2 * size;
|
||||
r.fBottom = r.fTop + 2 * size;
|
||||
|
||||
SkPath temp;
|
||||
|
||||
make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
|
||||
if (fZeroRad) {
|
||||
make_arb_round_rect(&temp, r, 0, 0);
|
||||
|
||||
SkASSERT(temp.isRect(NULL));
|
||||
} else {
|
||||
make_arb_round_rect(&temp, r, r.width() / 10, r.height() / 15);
|
||||
}
|
||||
|
||||
canvas->drawPath(temp, paint);
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
bool fZeroRad; // should 0 radius rounds rects be tested?
|
||||
|
||||
typedef SkBenchmark INHERITED;
|
||||
};
|
||||
|
||||
@ -863,5 +878,8 @@ static BenchRegistry gRegReverseTo(FactReverseTo);
|
||||
static SkBenchmark* CirclesTest(void* p) { return new CirclesBench(p); }
|
||||
static BenchRegistry gRegCirclesTest(CirclesTest);
|
||||
|
||||
static SkBenchmark* ArbRoundRectTest(void* p) { return new ArbRoundRectBench(p); }
|
||||
static SkBenchmark* ArbRoundRectTest(void* p) { return new ArbRoundRectBench(p, false); }
|
||||
static BenchRegistry gRegArbRoundRectTest(ArbRoundRectTest);
|
||||
|
||||
static SkBenchmark* ZeroRadRoundRectTest(void* p) { return new ArbRoundRectBench(p, true); }
|
||||
static BenchRegistry gRegZeroRadRoundRectTest(ZeroRadRoundRectTest);
|
||||
|
@ -1030,6 +1030,15 @@ static int build_arc_points(const SkRect& oval, SkScalar startAngle,
|
||||
// bounding box (and break the circle special case).
|
||||
pts[0].set(oval.fRight, oval.centerY());
|
||||
return 1;
|
||||
} else if (0 == oval.width() && 0 == oval.height()) {
|
||||
// Chrome will sometimes create 0 radius round rects. Having degenerate
|
||||
// quad segments in the path prevents the path from being recognized as
|
||||
// a rect.
|
||||
// TODO: optimizing the case where only one of width or height is zero
|
||||
// should also be considered. This case, however, doesn't seem to be
|
||||
// as common as the single point case.
|
||||
pts[0].set(oval.fRight, oval.fTop);
|
||||
return 1;
|
||||
}
|
||||
|
||||
SkVector start, stop;
|
||||
|
@ -114,6 +114,7 @@ static void make_arb_round_rect(SkPath* path, const SkRect& r,
|
||||
add_corner_arc(path, r, xCorner, yCorner, 0);
|
||||
add_corner_arc(path, r, xCorner, yCorner, 90);
|
||||
add_corner_arc(path, r, xCorner, yCorner, 180);
|
||||
path->close();
|
||||
}
|
||||
|
||||
// Chrome creates its own round rects with each corner possibly being different.
|
||||
@ -126,14 +127,14 @@ static void test_arb_round_rect_is_convex(skiatest::Reporter* reporter) {
|
||||
|
||||
for (int i = 0; i < 5000; ++i) {
|
||||
|
||||
SkScalar radius = rand.nextUScalar1() * 30;
|
||||
if (radius < SK_Scalar1) {
|
||||
SkScalar size = rand.nextUScalar1() * 30;
|
||||
if (size < SK_Scalar1) {
|
||||
continue;
|
||||
}
|
||||
r.fLeft = rand.nextUScalar1() * 300;
|
||||
r.fTop = rand.nextUScalar1() * 300;
|
||||
r.fRight = r.fLeft + 2 * radius;
|
||||
r.fBottom = r.fTop + 2 * radius;
|
||||
r.fRight = r.fLeft + 2 * size;
|
||||
r.fBottom = r.fTop + 2 * size;
|
||||
|
||||
SkPath temp;
|
||||
|
||||
@ -145,6 +146,37 @@ static void test_arb_round_rect_is_convex(skiatest::Reporter* reporter) {
|
||||
}
|
||||
}
|
||||
|
||||
// Chrome will sometimes create a 0 radius round rect. The degenerate
|
||||
// quads prevent the path from being converted to a rect
|
||||
// Note: PathBench::ArbRoundRectBench performs almost exactly
|
||||
// the same test (but with drawing)
|
||||
static void test_arb_zero_rad_round_rect_is_rect(skiatest::Reporter* reporter) {
|
||||
SkRandom rand;
|
||||
SkRect r;
|
||||
|
||||
for (int i = 0; i < 5000; ++i) {
|
||||
|
||||
SkScalar size = rand.nextUScalar1() * 30;
|
||||
if (size < SK_Scalar1) {
|
||||
continue;
|
||||
}
|
||||
r.fLeft = rand.nextUScalar1() * 300;
|
||||
r.fTop = rand.nextUScalar1() * 300;
|
||||
r.fRight = r.fLeft + 2 * size;
|
||||
r.fBottom = r.fTop + 2 * size;
|
||||
|
||||
SkPath temp;
|
||||
|
||||
make_arb_round_rect(&temp, r, 0, 0);
|
||||
|
||||
#ifdef SK_REDEFINE_ROOT2OVER2_TO_MAKE_ARCTOS_CONVEX
|
||||
SkRect result;
|
||||
REPORTER_ASSERT(reporter, temp.isRect(&result));
|
||||
REPORTER_ASSERT(reporter, r == result);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static void test_rect_isfinite(skiatest::Reporter* reporter) {
|
||||
const SkScalar inf = SK_ScalarInfinity;
|
||||
const SkScalar nan = SK_ScalarNaN;
|
||||
@ -1685,6 +1717,7 @@ static void TestPath(skiatest::Reporter* reporter) {
|
||||
test_isfinite_after_transform(reporter);
|
||||
test_tricky_cubic(reporter);
|
||||
test_arb_round_rect_is_convex(reporter);
|
||||
test_arb_zero_rad_round_rect_is_rect(reporter);
|
||||
}
|
||||
|
||||
#include "TestClassDef.h"
|
||||
|
Loading…
Reference in New Issue
Block a user