Skip to content

Commit f7169f9

Browse files
authored
Merge pull request #5980 from radarhere/polygon
2 parents 5a35e87 + b894c8c commit f7169f9

File tree

3 files changed

+52
-7
lines changed

3 files changed

+52
-7
lines changed
Loading

Tests/test_imagedraw.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1440,3 +1440,15 @@ def test_continuous_horizontal_edges_polygon():
14401440
assert_image_equal_tofile(
14411441
img, expected, "continuous horizontal edges polygon failed"
14421442
)
1443+
1444+
1445+
def test_discontiguous_corners_polygon():
1446+
img, draw = create_base_image_draw((84, 68))
1447+
draw.polygon(((1, 21), (34, 4), (71, 1), (38, 18)), BLACK)
1448+
draw.polygon(((71, 44), (38, 27), (1, 24)), BLACK)
1449+
draw.polygon(
1450+
((38, 66), (5, 49), (77, 49), (47, 66), (82, 63), (82, 47), (1, 47), (1, 63)),
1451+
BLACK,
1452+
)
1453+
expected = os.path.join(IMAGES_PATH, "discontiguous_corners_polygon.png")
1454+
assert_image_similar_tofile(img, expected, 1)

src/libImaging/Draw.c

Lines changed: 40 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,8 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, hline_handler h
450450
int edge_count = 0;
451451
int ymin = im->ysize - 1;
452452
int ymax = 0;
453-
int i;
453+
int i, j, k;
454+
float adjacent_line_x, adjacent_line_x_other_edge;
454455

455456
if (n <= 0) {
456457
return 0;
@@ -493,16 +494,48 @@ polygon_generic(Imaging im, int n, Edge *e, int ink, int eofill, hline_handler h
493494
return -1;
494495
}
495496
for (; ymin <= ymax; ymin++) {
496-
int j = 0;
497+
j = 0;
497498
for (i = 0; i < edge_count; i++) {
498499
Edge *current = edge_table[i];
499500
if (ymin >= current->ymin && ymin <= current->ymax) {
500501
xx[j++] = (ymin - current->y0) * current->dx + current->x0;
501-
}
502-
/* Needed to draw consistent polygons */
503-
if (ymin == current->ymax && ymin < ymax) {
504-
xx[j] = xx[j - 1];
505-
j++;
502+
503+
if (ymin == current->ymax && ymin < ymax) {
504+
// Needed to draw consistent polygons
505+
xx[j] = xx[j - 1];
506+
j++;
507+
} else if (current->dx != 0 && roundf(xx[j-1]) == xx[j-1]) {
508+
// Connect discontiguous corners
509+
for (k = 0; k < i; k++) {
510+
Edge *other_edge = edge_table[k];
511+
if ((current->dx > 0 && other_edge->dx <= 0) ||
512+
(current->dx < 0 && other_edge->dx >= 0)) {
513+
continue;
514+
}
515+
// Check if the two edges join to make a corner
516+
if (xx[j-1] == (ymin - other_edge->y0) * other_edge->dx + other_edge->x0) {
517+
// Determine points from the edges on the next row
518+
// Or if this is the last row, check the previous row
519+
int offset = ymin == ymax ? -1 : 1;
520+
adjacent_line_x = (ymin + offset - current->y0) * current->dx + current->x0;
521+
adjacent_line_x_other_edge = (ymin + offset - other_edge->y0) * other_edge->dx + other_edge->x0;
522+
if (ymin == current->ymax) {
523+
if (current->dx > 0) {
524+
xx[k] = fmax(adjacent_line_x, adjacent_line_x_other_edge) + 1;
525+
} else {
526+
xx[k] = fmin(adjacent_line_x, adjacent_line_x_other_edge) - 1;
527+
}
528+
} else {
529+
if (current->dx > 0) {
530+
xx[k] = fmin(adjacent_line_x, adjacent_line_x_other_edge);
531+
} else {
532+
xx[k] = fmax(adjacent_line_x, adjacent_line_x_other_edge) + 1;
533+
}
534+
}
535+
break;
536+
}
537+
}
538+
}
506539
}
507540
}
508541
qsort(xx, j, sizeof(float), x_cmp);

0 commit comments

Comments
 (0)