GrTessellator (AA): fix "Canvas Arcs" coverage artifact.
When sanitizing contours, if the first and last vertices coincide, continue with the previous vertex, not the next vertex, since we may otherwise exit prematurely. Also, round the last vertex before entering the loop, just in case it coincides with the first. Add a test case to exercise the above, and another one which exercises the intruding-vertex workaround. BUG=691593 Change-Id: Ic28a9308a21164d185edef0ee6fbc29b40742149 Reviewed-on: https://skia-review.googlesource.com/8364 Reviewed-by: Brian Salomon <bsalomon@google.com> Commit-Queue: Stephen White <senorblanco@chromium.org>
This commit is contained in:
parent
1e06d3d7b9
commit
5926f2da75
@ -62,6 +62,40 @@ void test_fake_bowtie(SkCanvas* canvas, const SkPaint& paint) {
|
|||||||
canvas->restore();
|
canvas->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Bowtie with a smaller right hand lobe. The outer vertex of the left hand
|
||||||
|
// lobe intrudes into the interior of the right hand lobe.
|
||||||
|
void test_intruding_vertex(SkCanvas* canvas, const SkPaint& paint) {
|
||||||
|
SkPath path;
|
||||||
|
canvas->save();
|
||||||
|
canvas->translate(400, 0);
|
||||||
|
path.setIsVolatile(true);
|
||||||
|
path.moveTo(20, 20);
|
||||||
|
path.lineTo(50, 50);
|
||||||
|
path.lineTo(68, 20);
|
||||||
|
path.lineTo(68, 80);
|
||||||
|
path.lineTo(50, 50);
|
||||||
|
path.lineTo(20, 80);
|
||||||
|
canvas->drawPath(path, paint);
|
||||||
|
canvas->restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
// A shape with an edge that becomes inverted on AA stroking and that also contains
|
||||||
|
// a repeated start/end vertex.
|
||||||
|
void test_inversion_repeat_vertex(SkCanvas* canvas, const SkPaint& paint) {
|
||||||
|
SkPath path;
|
||||||
|
canvas->save();
|
||||||
|
canvas->translate(400, 100);
|
||||||
|
path.setIsVolatile(true);
|
||||||
|
path.moveTo(80, 50);
|
||||||
|
path.lineTo(40, 80);
|
||||||
|
path.lineTo(60, 20);
|
||||||
|
path.lineTo(20, 20);
|
||||||
|
path.lineTo(39.99f, 80);
|
||||||
|
path.lineTo(80, 50);
|
||||||
|
canvas->drawPath(path, paint);
|
||||||
|
canvas->restore();
|
||||||
|
}
|
||||||
|
|
||||||
// Fish test (intersection/concave)
|
// Fish test (intersection/concave)
|
||||||
void test_fish(SkCanvas* canvas, const SkPaint& paint) {
|
void test_fish(SkCanvas* canvas, const SkPaint& paint) {
|
||||||
SkPath path;
|
SkPath path;
|
||||||
@ -360,7 +394,7 @@ void test_coincident_edges_4(SkCanvas* canvas, const SkPaint& paint) {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
DEF_SIMPLE_GM(concavepaths, canvas, 400, 600) {
|
DEF_SIMPLE_GM(concavepaths, canvas, 500, 600) {
|
||||||
SkPaint paint;
|
SkPaint paint;
|
||||||
|
|
||||||
paint.setAntiAlias(true);
|
paint.setAntiAlias(true);
|
||||||
@ -370,10 +404,12 @@ DEF_SIMPLE_GM(concavepaths, canvas, 400, 600) {
|
|||||||
test_reverse_concave(canvas, paint);
|
test_reverse_concave(canvas, paint);
|
||||||
test_bowtie(canvas, paint);
|
test_bowtie(canvas, paint);
|
||||||
test_fake_bowtie(canvas, paint);
|
test_fake_bowtie(canvas, paint);
|
||||||
|
test_intruding_vertex(canvas, paint);
|
||||||
test_fish(canvas, paint);
|
test_fish(canvas, paint);
|
||||||
test_fast_forward(canvas, paint);
|
test_fast_forward(canvas, paint);
|
||||||
test_hole(canvas, paint);
|
test_hole(canvas, paint);
|
||||||
test_star(canvas, paint);
|
test_star(canvas, paint);
|
||||||
|
test_inversion_repeat_vertex(canvas, paint);
|
||||||
test_stairstep(canvas, paint);
|
test_stairstep(canvas, paint);
|
||||||
test_stairstep2(canvas, paint);
|
test_stairstep2(canvas, paint);
|
||||||
test_overlapping(canvas, paint);
|
test_overlapping(canvas, paint);
|
||||||
|
@ -1149,6 +1149,9 @@ Vertex* check_for_intersection(Edge* edge, Edge* other, EdgeList* activeEdges, C
|
|||||||
void sanitize_contours(Vertex** contours, int contourCnt, bool approximate) {
|
void sanitize_contours(Vertex** contours, int contourCnt, bool approximate) {
|
||||||
for (int i = 0; i < contourCnt; ++i) {
|
for (int i = 0; i < contourCnt; ++i) {
|
||||||
SkASSERT(contours[i]);
|
SkASSERT(contours[i]);
|
||||||
|
if (approximate) {
|
||||||
|
round(&contours[i]->fPrev->fPoint);
|
||||||
|
}
|
||||||
for (Vertex* v = contours[i];;) {
|
for (Vertex* v = contours[i];;) {
|
||||||
if (approximate) {
|
if (approximate) {
|
||||||
round(&v->fPoint);
|
round(&v->fPoint);
|
||||||
@ -1162,7 +1165,7 @@ void sanitize_contours(Vertex** contours, int contourCnt, bool approximate) {
|
|||||||
v->fPrev->fNext = v->fNext;
|
v->fPrev->fNext = v->fNext;
|
||||||
v->fNext->fPrev = v->fPrev;
|
v->fNext->fPrev = v->fPrev;
|
||||||
if (contours[i] == v) {
|
if (contours[i] == v) {
|
||||||
contours[i] = v->fNext;
|
contours[i] = v->fPrev;
|
||||||
}
|
}
|
||||||
v = v->fPrev;
|
v = v->fPrev;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user