mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-27 10:26:19 +03:00
commit
c3ed8cc67e
BIN
Tests/images/imagedraw_arc_width_pieslice.png
Normal file
BIN
Tests/images/imagedraw_arc_width_pieslice.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 402 B |
BIN
Tests/images/imagedraw_ellipse_width_large.png
Normal file
BIN
Tests/images/imagedraw_ellipse_width_large.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.4 KiB |
|
@ -114,6 +114,19 @@ class TestImageDraw(PillowTestCase):
|
||||||
# Assert
|
# Assert
|
||||||
self.assert_image_similar(im, Image.open(expected), 1)
|
self.assert_image_similar(im, Image.open(expected), 1)
|
||||||
|
|
||||||
|
def test_arc_width_pieslice_large(self):
|
||||||
|
# Tests an arc with a large enough width that it is a pieslice
|
||||||
|
# Arrange
|
||||||
|
im = Image.new("RGB", (W, H))
|
||||||
|
draw = ImageDraw.Draw(im)
|
||||||
|
expected = "Tests/images/imagedraw_arc_width_pieslice.png"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
draw.arc(BBOX1, 10, 260, fill="yellow", width=100)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assert_image_similar(im, Image.open(expected), 1)
|
||||||
|
|
||||||
def test_arc_width_fill(self):
|
def test_arc_width_fill(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
|
@ -239,6 +252,18 @@ class TestImageDraw(PillowTestCase):
|
||||||
# Assert
|
# Assert
|
||||||
self.assert_image_similar(im, Image.open(expected), 1)
|
self.assert_image_similar(im, Image.open(expected), 1)
|
||||||
|
|
||||||
|
def test_ellipse_width_large(self):
|
||||||
|
# Arrange
|
||||||
|
im = Image.new("RGB", (500, 500))
|
||||||
|
draw = ImageDraw.Draw(im)
|
||||||
|
expected = "Tests/images/imagedraw_ellipse_width_large.png"
|
||||||
|
|
||||||
|
# Act
|
||||||
|
draw.ellipse((25, 25, 475, 475), outline="blue", width=75)
|
||||||
|
|
||||||
|
# Assert
|
||||||
|
self.assert_image_similar(im, Image.open(expected), 1)
|
||||||
|
|
||||||
def test_ellipse_width_fill(self):
|
def test_ellipse_width_fill(self):
|
||||||
# Arrange
|
# Arrange
|
||||||
im = Image.new("RGB", (W, H))
|
im = Image.new("RGB", (W, H))
|
||||||
|
|
|
@ -765,81 +765,39 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
int width, int mode, int op)
|
int width, int mode, int op)
|
||||||
{
|
{
|
||||||
float i;
|
float i;
|
||||||
int j;
|
int inner;
|
||||||
int n;
|
int n;
|
||||||
int cx, cy;
|
int maxEdgeCount;
|
||||||
int w, h;
|
int w, h;
|
||||||
int x = 0, y = 0;
|
int x, y;
|
||||||
int lx = 0, ly = 0;
|
int cx, cy;
|
||||||
int sx = 0, sy = 0;
|
int lx, ly;
|
||||||
|
int sx, sy;
|
||||||
|
int lx_inner, ly_inner;
|
||||||
|
int sx_inner, sy_inner;
|
||||||
DRAW* draw;
|
DRAW* draw;
|
||||||
INT32 ink;
|
INT32 ink;
|
||||||
|
Edge* e;
|
||||||
|
|
||||||
DRAWINIT();
|
DRAWINIT();
|
||||||
|
|
||||||
if (width == 0) {
|
|
||||||
width = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = 0; j < width; j++) {
|
|
||||||
|
|
||||||
w = x1 - x0;
|
|
||||||
h = y1 - y0;
|
|
||||||
if (w < 0 || h < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
cx = (x0 + x1) / 2;
|
|
||||||
cy = (y0 + y1) / 2;
|
|
||||||
|
|
||||||
while (end < start)
|
while (end < start)
|
||||||
end += 360;
|
end += 360;
|
||||||
|
|
||||||
if (end - start > 360) {
|
if (end - start > 360) {
|
||||||
/* no need to go in loops */
|
// no need to go in loops
|
||||||
end = start + 361;
|
end = start + 361;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mode != ARC && fill) {
|
w = x1 - x0;
|
||||||
|
h = y1 - y0;
|
||||||
|
if (w <= 0 || h <= 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
/* Build edge list */
|
cx = (x0 + x1) / 2;
|
||||||
/* malloc check UNDONE, FLOAT? */
|
cy = (y0 + y1) / 2;
|
||||||
Edge* e = calloc((end - start + 3), sizeof(Edge));
|
|
||||||
if (!e) {
|
|
||||||
ImagingError_MemoryError();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
n = 0;
|
|
||||||
|
|
||||||
for (i = start; i < end+1; i++) {
|
|
||||||
if (i > end) {
|
|
||||||
i = end;
|
|
||||||
}
|
|
||||||
ellipsePoint(cx, cy, w, h, i, &x, &y);
|
|
||||||
if (i != start)
|
|
||||||
add_edge(&e[n++], lx, ly, x, y);
|
|
||||||
else
|
|
||||||
sx = x, sy = y;
|
|
||||||
lx = x, ly = y;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (n > 0) {
|
|
||||||
/* close and draw polygon */
|
|
||||||
if (mode == PIESLICE) {
|
|
||||||
if (x != cx || y != cy) {
|
|
||||||
add_edge(&e[n++], x, y, cx, cy);
|
|
||||||
add_edge(&e[n++], cx, cy, sx, sy);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (x != sx || y != sy)
|
|
||||||
add_edge(&e[n++], x, y, sx, sy);
|
|
||||||
}
|
|
||||||
draw->polygon(im, n, e, ink, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(e);
|
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
|
if (!fill && width <= 1) {
|
||||||
for (i = start; i < end+1; i++) {
|
for (i = start; i < end+1; i++) {
|
||||||
if (i > end) {
|
if (i > end) {
|
||||||
i = end;
|
i = end;
|
||||||
|
@ -854,26 +812,103 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
|
||||||
|
|
||||||
if (i != start) {
|
if (i != start) {
|
||||||
if (mode == PIESLICE) {
|
if (mode == PIESLICE) {
|
||||||
if (j == 0 && (x != cx || y != cy)) {
|
if (x != cx || y != cy) {
|
||||||
if (width == 1) {
|
|
||||||
draw->line(im, x, y, cx, cy, ink);
|
draw->line(im, x, y, cx, cy, ink);
|
||||||
draw->line(im, cx, cy, sx, sy, ink);
|
draw->line(im, cx, cy, sx, sy, ink);
|
||||||
} else {
|
|
||||||
ImagingDrawWideLine(im, x, y, cx, cy, &ink, width, op);
|
|
||||||
ImagingDrawWideLine(im, cx, cy, sx, sy, &ink, width, op);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else if (mode == CHORD) {
|
} else if (mode == CHORD) {
|
||||||
if (x != sx || y != sy)
|
if (x != sx || y != sy)
|
||||||
draw->line(im, x, y, sx, sy, ink);
|
draw->line(im, x, y, sx, sy, ink);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
inner = (mode == ARC || !fill) ? 1 : 0;
|
||||||
|
|
||||||
|
// Build edge list
|
||||||
|
// malloc check UNDONE, FLOAT?
|
||||||
|
maxEdgeCount = end - start;
|
||||||
|
if (inner) {
|
||||||
|
maxEdgeCount *= 2;
|
||||||
}
|
}
|
||||||
x0++;
|
maxEdgeCount += 3;
|
||||||
y0++;
|
e = calloc(maxEdgeCount, sizeof(Edge));
|
||||||
x1--;
|
if (!e) {
|
||||||
y1--;
|
ImagingError_MemoryError();
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Outer circle
|
||||||
|
n = 0;
|
||||||
|
for (i = start; i < end+1; i++) {
|
||||||
|
if (i > end) {
|
||||||
|
i = end;
|
||||||
|
}
|
||||||
|
ellipsePoint(cx, cy, w, h, i, &x, &y);
|
||||||
|
if (i == start) {
|
||||||
|
sx = x, sy = y;
|
||||||
|
} else {
|
||||||
|
add_edge(&e[n++], lx, ly, x, y);
|
||||||
|
}
|
||||||
|
lx = x, ly = y;
|
||||||
|
}
|
||||||
|
if (n == 0)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (inner) {
|
||||||
|
// Inner circle
|
||||||
|
x0 += width - 1;
|
||||||
|
y0 += width - 1;
|
||||||
|
x1 -= width - 1;
|
||||||
|
y1 -= width - 1;
|
||||||
|
|
||||||
|
w = x1 - x0;
|
||||||
|
h = y1 - y0;
|
||||||
|
if (w <= 0 || h <= 0) {
|
||||||
|
// ARC with no gap in the middle is a PIESLICE
|
||||||
|
mode = PIESLICE;
|
||||||
|
inner = 0;
|
||||||
|
} else {
|
||||||
|
for (i = start; i < end+1; i++) {
|
||||||
|
if (i > end) {
|
||||||
|
i = end;
|
||||||
|
}
|
||||||
|
ellipsePoint(cx, cy, w, h, i, &x, &y);
|
||||||
|
if (i == start)
|
||||||
|
sx_inner = x, sy_inner = y;
|
||||||
|
else
|
||||||
|
add_edge(&e[n++], lx_inner, ly_inner, x, y);
|
||||||
|
lx_inner = x, ly_inner = y;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (end - start < 360) {
|
||||||
|
// Close polygon
|
||||||
|
if (mode == PIESLICE) {
|
||||||
|
if (x != cx || y != cy) {
|
||||||
|
add_edge(&e[n++], sx, sy, cx, cy);
|
||||||
|
add_edge(&e[n++], cx, cy, lx, ly);
|
||||||
|
if (inner) {
|
||||||
|
ImagingDrawWideLine(im, sx, sy, cx, cy, &ink, width, op);
|
||||||
|
ImagingDrawWideLine(im, cx, cy, lx, ly, &ink, width, op);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (mode == CHORD) {
|
||||||
|
add_edge(&e[n++], sx, sy, lx, ly);
|
||||||
|
if (inner) {
|
||||||
|
add_edge(&e[n++], sx_inner, sy_inner, lx_inner, ly_inner);
|
||||||
|
}
|
||||||
|
} else if (mode == ARC) {
|
||||||
|
add_edge(&e[n++], sx, sy, sx_inner, sy_inner);
|
||||||
|
add_edge(&e[n++], lx, ly, lx_inner, ly_inner);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
draw->polygon(im, n, e, ink, 0);
|
||||||
|
|
||||||
|
free(e);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user