re-chop if we fail on a big-bad-cubic
BUG=629455 GOLD_TRYBOT_URL= https://gold.skia.org/search?issue=2159223005 Review-Url: https://codereview.chromium.org/2159223005
This commit is contained in:
parent
1f790aaeef
commit
158fabb071
@ -263,9 +263,25 @@ static void chop_cubic_in_Y(SkPoint pts[4], const SkRect& clip) {
|
||||
if (pts[0].fY < clip.fTop) {
|
||||
SkPoint tmp[7];
|
||||
chop_mono_cubic_at_y(pts, clip.fTop, tmp);
|
||||
|
||||
/*
|
||||
* For a large range in the points, we can do a poor job of chopping, such that the t
|
||||
* we computed resulted in the lower cubic still being partly above the clip.
|
||||
*
|
||||
* If just the first or first 2 Y values are above the fTop, we can just smash them
|
||||
* down. If the first 3 Ys are above fTop, we can't smash all 3, as that can really
|
||||
* distort the cubic. In this case, we take the first output (tmp[3..6] and treat it as
|
||||
* a guess, and re-chop against fTop. Then we fall through to checking if we need to
|
||||
* smash the first 1 or 2 Y values.
|
||||
*/
|
||||
if (tmp[3].fY < clip.fTop && tmp[4].fY < clip.fTop && tmp[5].fY < clip.fTop) {
|
||||
SkPoint tmp2[4];
|
||||
memcpy(tmp2, &tmp[3].fX, 4 * sizeof(SkPoint));
|
||||
chop_mono_cubic_at_y(tmp2, clip.fTop, tmp);
|
||||
}
|
||||
|
||||
// tmp[3, 4].fY should all be to the below clip.fTop.
|
||||
// Since we can't trust the numerics of
|
||||
// the chopper, we force those conditions now
|
||||
// Since we can't trust the numerics of the chopper, we force those conditions now
|
||||
tmp[3].fY = clip.fTop;
|
||||
clamp_ge(tmp[4].fY, clip.fTop);
|
||||
|
||||
|
@ -4129,6 +4129,21 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
static void test_crbug_629455(skiatest::Reporter* reporter) {
|
||||
SkPath path;
|
||||
path.moveTo(0, 0);
|
||||
path.cubicTo(SkBits2Float(0xcdcdcd00), SkBits2Float(0xcdcdcdcd),
|
||||
SkBits2Float(0xcdcdcdcd), SkBits2Float(0xcdcdcdcd),
|
||||
SkBits2Float(0x423fcdcd), SkBits2Float(0x40ed9341));
|
||||
// AKA: cubicTo(-4.31596e+08f, -4.31602e+08f, -4.31602e+08f, -4.31602e+08f, 47.951f, 7.42423f);
|
||||
path.lineTo(0, 0);
|
||||
|
||||
auto surface = SkSurface::MakeRasterN32Premul(100, 100);
|
||||
SkPaint paint;
|
||||
paint.setAntiAlias(true);
|
||||
surface->getCanvas()->drawPath(path, paint);
|
||||
}
|
||||
|
||||
static void test_interp(skiatest::Reporter* reporter) {
|
||||
SkPath p1, p2, out;
|
||||
REPORTER_ASSERT(reporter, p1.isInterpolatable(p2));
|
||||
@ -4177,6 +4192,7 @@ DEF_TEST(PathContains, reporter) {
|
||||
}
|
||||
|
||||
DEF_TEST(Paths, reporter) {
|
||||
test_crbug_629455(reporter);
|
||||
test_fuzz_crbug_627414(reporter);
|
||||
test_path_crbug364224();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user