Merge pull request #3094 from hugovk/add-width-to-shapes

Add line width parameter to rectangle and ellipse-based shapes
This commit is contained in:
Andrew Murray 2018-09-29 23:21:03 +10:00 committed by GitHub
commit 1e305380ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
16 changed files with 278 additions and 116 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 439 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 488 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 507 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 452 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 477 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 496 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 523 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 228 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 239 B

View File

@ -102,6 +102,30 @@ class TestImageDraw(PillowTestCase):
self.assert_image_similar( self.assert_image_similar(
im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1) im, Image.open("Tests/images/imagedraw_arc_no_loops.png"), 1)
def test_arc_width(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_arc_width.png"
# Act
draw.arc(BBOX1, 10, 260, width=5)
# Assert
self.assert_image_similar(im, Image.open(expected), 1)
def test_arc_width_fill(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_arc_width_fill.png"
# Act
draw.arc(BBOX1, 10, 260, fill="yellow", width=5)
# Assert
self.assert_image_similar(im, Image.open(expected), 1)
def test_bitmap(self): def test_bitmap(self):
# Arrange # Arrange
small = Image.open("Tests/images/pil123rgba.png").resize((50, 50)) small = Image.open("Tests/images/pil123rgba.png").resize((50, 50))
@ -137,6 +161,30 @@ class TestImageDraw(PillowTestCase):
self.helper_chord(mode, BBOX2, 0, 180) self.helper_chord(mode, BBOX2, 0, 180)
self.helper_chord(mode, BBOX2, 0.5, 180.4) self.helper_chord(mode, BBOX2, 0.5, 180.4)
def test_chord_width(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_chord_width.png"
# Act
draw.chord(BBOX1, 10, 260, outline="yellow", width=5)
# Assert
self.assert_image_similar(im, Image.open(expected), 1)
def test_chord_width_fill(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_chord_width_fill.png"
# Act
draw.chord(BBOX1, 10, 260, fill="red", outline="yellow", width=5)
# Assert
self.assert_image_similar(im, Image.open(expected), 1)
def helper_ellipse(self, mode, bbox): def helper_ellipse(self, mode, bbox):
# Arrange # Arrange
im = Image.new(mode, (W, H)) im = Image.new(mode, (W, H))
@ -179,6 +227,30 @@ class TestImageDraw(PillowTestCase):
draw.ellipse(bbox, fill="green", outline="blue") draw.ellipse(bbox, fill="green", outline="blue")
self.assert_image_equal(im, im.transpose(Image.FLIP_LEFT_RIGHT)) self.assert_image_equal(im, im.transpose(Image.FLIP_LEFT_RIGHT))
def test_ellipse_width(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_ellipse_width.png"
# Act
draw.ellipse(BBOX1, outline="blue", width=5)
# Assert
self.assert_image_similar(im, Image.open(expected), 1)
def test_ellipse_width_fill(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_ellipse_width_fill.png"
# Act
draw.ellipse(BBOX1, fill="green", outline="blue", width=5)
# Assert
self.assert_image_similar(im, Image.open(expected), 1)
def helper_line(self, points): def helper_line(self, points):
# Arrange # Arrange
im = Image.new("RGB", (W, H)) im = Image.new("RGB", (W, H))
@ -259,6 +331,30 @@ class TestImageDraw(PillowTestCase):
self.helper_pieslice(BBOX2, -90, 45) self.helper_pieslice(BBOX2, -90, 45)
self.helper_pieslice(BBOX2, -90.5, 45.4) self.helper_pieslice(BBOX2, -90.5, 45.4)
def test_pieslice_width(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_pieslice_width.png"
# Act
draw.pieslice(BBOX1, 10, 260, outline="blue", width=5)
# Assert
self.assert_image_similar(im, Image.open(expected), 1)
def test_pieslice_width_fill(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_pieslice_width_fill.png"
# Act
draw.pieslice(BBOX1, 10, 260, fill="white", outline="blue", width=5)
# Assert
self.assert_image_similar(im, Image.open(expected), 1)
def helper_point(self, points): def helper_point(self, points):
# Arrange # Arrange
im = Image.new("RGB", (W, H)) im = Image.new("RGB", (W, H))
@ -343,6 +439,30 @@ 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_rectangle_width(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_rectangle_width.png"
# Act
draw.rectangle(BBOX1, outline="green", width=5)
# Assert
self.assert_image_equal(im, Image.open(expected))
def test_rectangle_width_fill(self):
# Arrange
im = Image.new("RGB", (W, H))
draw = ImageDraw.Draw(im)
expected = "Tests/images/imagedraw_rectangle_width_fill.png"
# Act
draw.rectangle(BBOX1, fill="blue", outline="green", width=5)
# Assert
self.assert_image_equal(im, Image.open(expected))
def test_floodfill(self): def test_floodfill(self):
red = ImageColor.getrgb("red") red = ImageColor.getrgb("red")

View File

@ -126,7 +126,7 @@ Methods
:returns: An image font. :returns: An image font.
.. py:method:: PIL.ImageDraw.ImageDraw.arc(xy, start, end, fill=None) .. py:method:: PIL.ImageDraw.ImageDraw.arc(xy, start, end, fill=None, width=0)
Draws an arc (a portion of a circle outline) between the start and end Draws an arc (a portion of a circle outline) between the start and end
angles, inside the given bounding box. angles, inside the given bounding box.
@ -138,6 +138,9 @@ Methods
3 o'clock, increasing clockwise. 3 o'clock, increasing clockwise.
:param end: Ending angle, in degrees. :param end: Ending angle, in degrees.
:param fill: Color to use for the arc. :param fill: Color to use for the arc.
:param width: The line width, in pixels.
.. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.bitmap(xy, bitmap, fill=None) .. py:method:: PIL.ImageDraw.ImageDraw.bitmap(xy, bitmap, fill=None)
@ -150,7 +153,7 @@ Methods
To paste pixel data into an image, use the To paste pixel data into an image, use the
:py:meth:`~PIL.Image.Image.paste` method on the image itself. :py:meth:`~PIL.Image.Image.paste` method on the image itself.
.. py:method:: PIL.ImageDraw.ImageDraw.chord(xy, start, end, fill=None, outline=None) .. py:method:: PIL.ImageDraw.ImageDraw.chord(xy, start, end, fill=None, outline=None, width=0)
Same as :py:meth:`~PIL.ImageDraw.ImageDraw.arc`, but connects the end points Same as :py:meth:`~PIL.ImageDraw.ImageDraw.arc`, but connects the end points
with a straight line. with a straight line.
@ -160,8 +163,11 @@ Methods
where ``x1 >= x0`` and ``y1 >= y0``. where ``x1 >= x0`` and ``y1 >= y0``.
:param outline: Color to use for the outline. :param outline: Color to use for the outline.
:param fill: Color to use for the fill. :param fill: Color to use for the fill.
:param width: The line width, in pixels.
.. py:method:: PIL.ImageDraw.ImageDraw.ellipse(xy, fill=None, outline=None) .. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.ellipse(xy, fill=None, outline=None, width=0)
Draws an ellipse inside the given bounding box. Draws an ellipse inside the given bounding box.
@ -170,6 +176,9 @@ Methods
where ``x1 >= x0`` and ``y1 >= y0``. where ``x1 >= x0`` and ``y1 >= y0``.
:param outline: Color to use for the outline. :param outline: Color to use for the outline.
:param fill: Color to use for the fill. :param fill: Color to use for the fill.
:param width: The line width, in pixels.
.. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.line(xy, fill=None, width=0, joint=None) .. py:method:: PIL.ImageDraw.ImageDraw.line(xy, fill=None, width=0, joint=None)
@ -188,7 +197,7 @@ Methods
.. versionadded:: 5.3.0 .. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.pieslice(xy, start, end, fill=None, outline=None) .. py:method:: PIL.ImageDraw.ImageDraw.pieslice(xy, start, end, fill=None, outline=None, width=0)
Same as arc, but also draws straight lines between the end points and the Same as arc, but also draws straight lines between the end points and the
center of the bounding box. center of the bounding box.
@ -201,6 +210,9 @@ Methods
:param end: Ending angle, in degrees. :param end: Ending angle, in degrees.
:param fill: Color to use for the fill. :param fill: Color to use for the fill.
:param outline: Color to use for the outline. :param outline: Color to use for the outline.
:param width: The line width, in pixels.
.. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.point(xy, fill=None) .. py:method:: PIL.ImageDraw.ImageDraw.point(xy, fill=None)
@ -223,7 +235,7 @@ Methods
:param outline: Color to use for the outline. :param outline: Color to use for the outline.
:param fill: Color to use for the fill. :param fill: Color to use for the fill.
.. py:method:: PIL.ImageDraw.ImageDraw.rectangle(xy, fill=None, outline=None) .. py:method:: PIL.ImageDraw.ImageDraw.rectangle(xy, fill=None, outline=None, width=0)
Draws a rectangle. Draws a rectangle.
@ -232,6 +244,9 @@ Methods
is just outside the drawn rectangle. is just outside the drawn rectangle.
:param outline: Color to use for the outline. :param outline: Color to use for the outline.
:param fill: Color to use for the fill. :param fill: Color to use for the fill.
:param width: The line width, in pixels.
.. versionadded:: 5.3.0
.. py:method:: PIL.ImageDraw.ImageDraw.shape(shape, fill=None, outline=None) .. py:method:: PIL.ImageDraw.ImageDraw.shape(shape, fill=None, outline=None)

View File

@ -119,11 +119,11 @@ class ImageDraw(object):
fill = self.draw.draw_ink(fill, self.mode) fill = self.draw.draw_ink(fill, self.mode)
return ink, fill return ink, fill
def arc(self, xy, start, end, fill=None): def arc(self, xy, start, end, fill=None, width=0):
"""Draw an arc.""" """Draw an arc."""
ink, fill = self._getink(fill) ink, fill = self._getink(fill)
if ink is not None: if ink is not None:
self.draw.draw_arc(xy, start, end, ink) self.draw.draw_arc(xy, start, end, ink, width)
def bitmap(self, xy, bitmap, fill=None): def bitmap(self, xy, bitmap, fill=None):
"""Draw a bitmap.""" """Draw a bitmap."""
@ -134,21 +134,21 @@ class ImageDraw(object):
if ink is not None: if ink is not None:
self.draw.draw_bitmap(xy, bitmap.im, ink) self.draw.draw_bitmap(xy, bitmap.im, ink)
def chord(self, xy, start, end, fill=None, outline=None): def chord(self, xy, start, end, fill=None, outline=None, width=0):
"""Draw a chord.""" """Draw a chord."""
ink, fill = self._getink(outline, fill) ink, fill = self._getink(outline, fill)
if fill is not None: if fill is not None:
self.draw.draw_chord(xy, start, end, fill, 1) self.draw.draw_chord(xy, start, end, fill, 1)
if ink is not None and ink != fill: if ink is not None and ink != fill:
self.draw.draw_chord(xy, start, end, ink, 0) self.draw.draw_chord(xy, start, end, ink, 0, width)
def ellipse(self, xy, fill=None, outline=None): def ellipse(self, xy, fill=None, outline=None, width=0):
"""Draw an ellipse.""" """Draw an ellipse."""
ink, fill = self._getink(outline, fill) ink, fill = self._getink(outline, fill)
if fill is not None: if fill is not None:
self.draw.draw_ellipse(xy, fill, 1) self.draw.draw_ellipse(xy, fill, 1)
if ink is not None and ink != fill: if ink is not None and ink != fill:
self.draw.draw_ellipse(xy, ink, 0) self.draw.draw_ellipse(xy, ink, 0, width)
def line(self, xy, fill=None, width=0, joint=None): def line(self, xy, fill=None, width=0, joint=None):
"""Draw a line, or a connected sequence of line segments.""" """Draw a line, or a connected sequence of line segments."""
@ -218,13 +218,13 @@ class ImageDraw(object):
if ink is not None and ink != fill: if ink is not None and ink != fill:
self.draw.draw_outline(shape, ink, 0) self.draw.draw_outline(shape, ink, 0)
def pieslice(self, xy, start, end, fill=None, outline=None): def pieslice(self, xy, start, end, fill=None, outline=None, width=0):
"""Draw a pieslice.""" """Draw a pieslice."""
ink, fill = self._getink(outline, fill) ink, fill = self._getink(outline, fill)
if fill is not None: if fill is not None:
self.draw.draw_pieslice(xy, start, end, fill, 1) self.draw.draw_pieslice(xy, start, end, fill, 1)
if ink is not None and ink != fill: if ink is not None and ink != fill:
self.draw.draw_pieslice(xy, start, end, ink, 0) self.draw.draw_pieslice(xy, start, end, ink, 0, width)
def point(self, xy, fill=None): def point(self, xy, fill=None):
"""Draw one or more individual pixels.""" """Draw one or more individual pixels."""
@ -240,13 +240,13 @@ class ImageDraw(object):
if ink is not None and ink != fill: if ink is not None and ink != fill:
self.draw.draw_polygon(xy, ink, 0) self.draw.draw_polygon(xy, ink, 0)
def rectangle(self, xy, fill=None, outline=None): def rectangle(self, xy, fill=None, outline=None, width=0):
"""Draw a rectangle.""" """Draw a rectangle."""
ink, fill = self._getink(outline, fill) ink, fill = self._getink(outline, fill)
if fill is not None: if fill is not None:
self.draw.draw_rectangle(xy, fill, 1) self.draw.draw_rectangle(xy, fill, 1)
if ink is not None and ink != fill: if ink is not None and ink != fill:
self.draw.draw_rectangle(xy, ink, 0) self.draw.draw_rectangle(xy, ink, 0, width)
def _multiline_check(self, text): def _multiline_check(self, text):
"""Draw text.""" """Draw text."""

View File

@ -2567,9 +2567,10 @@ _draw_arc(ImagingDrawObject* self, PyObject* args)
PyObject* data; PyObject* data;
int ink; int ink;
int width = 0;
float start, end; float start, end;
int op = 0; int op = 0;
if (!PyArg_ParseTuple(args, "Offi|i", &data, &start, &end, &ink)) if (!PyArg_ParseTuple(args, "Offi|ii", &data, &start, &end, &ink, &width))
return NULL; return NULL;
n = PyPath_Flatten(data, &xy); n = PyPath_Flatten(data, &xy);
@ -2583,7 +2584,7 @@ _draw_arc(ImagingDrawObject* self, PyObject* args)
n = ImagingDrawArc(self->image->image, n = ImagingDrawArc(self->image->image,
(int) xy[0], (int) xy[1], (int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3], (int) xy[2], (int) xy[3],
start, end, &ink, op start, end, &ink, width, op
); );
free(xy); free(xy);
@ -2639,9 +2640,10 @@ _draw_chord(ImagingDrawObject* self, PyObject* args)
PyObject* data; PyObject* data;
int ink, fill; int ink, fill;
int width = 0;
float start, end; float start, end;
if (!PyArg_ParseTuple(args, "Offii", if (!PyArg_ParseTuple(args, "Offii|i",
&data, &start, &end, &ink, &fill)) &data, &start, &end, &ink, &fill, &width))
return NULL; return NULL;
n = PyPath_Flatten(data, &xy); n = PyPath_Flatten(data, &xy);
@ -2655,7 +2657,7 @@ _draw_chord(ImagingDrawObject* self, PyObject* args)
n = ImagingDrawChord(self->image->image, n = ImagingDrawChord(self->image->image,
(int) xy[0], (int) xy[1], (int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3], (int) xy[2], (int) xy[3],
start, end, &ink, fill, self->blend start, end, &ink, fill, width, self->blend
); );
free(xy); free(xy);
@ -2676,7 +2678,8 @@ _draw_ellipse(ImagingDrawObject* self, PyObject* args)
PyObject* data; PyObject* data;
int ink; int ink;
int fill = 0; int fill = 0;
if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) int width = 0;
if (!PyArg_ParseTuple(args, "Oi|ii", &data, &ink, &fill, &width))
return NULL; return NULL;
n = PyPath_Flatten(data, &xy); n = PyPath_Flatten(data, &xy);
@ -2690,7 +2693,7 @@ _draw_ellipse(ImagingDrawObject* self, PyObject* args)
n = ImagingDrawEllipse(self->image->image, n = ImagingDrawEllipse(self->image->image,
(int) xy[0], (int) xy[1], (int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3], (int) xy[2], (int) xy[3],
&ink, fill, self->blend &ink, fill, width, self->blend
); );
free(xy); free(xy);
@ -2720,7 +2723,7 @@ _draw_lines(ImagingDrawObject* self, PyObject* args)
if (width <= 1) { if (width <= 1) {
double *p = NULL; double *p = NULL;
for (i = 0; i < n-1; i++) { for (i = 0; i < n-1; i++) {
p = &xy[i+i]; p = &xy[i+i];
if (ImagingDrawLine( if (ImagingDrawLine(
self->image->image, self->image->image,
@ -2825,8 +2828,9 @@ _draw_pieslice(ImagingDrawObject* self, PyObject* args)
PyObject* data; PyObject* data;
int ink, fill; int ink, fill;
int width = 0;
float start, end; float start, end;
if (!PyArg_ParseTuple(args, "Offii", &data, &start, &end, &ink, &fill)) if (!PyArg_ParseTuple(args, "Offii|i", &data, &start, &end, &ink, &fill, &width))
return NULL; return NULL;
n = PyPath_Flatten(data, &xy); n = PyPath_Flatten(data, &xy);
@ -2840,7 +2844,7 @@ _draw_pieslice(ImagingDrawObject* self, PyObject* args)
n = ImagingDrawPieslice(self->image->image, n = ImagingDrawPieslice(self->image->image,
(int) xy[0], (int) xy[1], (int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3], (int) xy[2], (int) xy[3],
start, end, &ink, fill, self->blend start, end, &ink, fill, width, self->blend
); );
free(xy); free(xy);
@ -2906,7 +2910,8 @@ _draw_rectangle(ImagingDrawObject* self, PyObject* args)
PyObject* data; PyObject* data;
int ink; int ink;
int fill = 0; int fill = 0;
if (!PyArg_ParseTuple(args, "Oi|i", &data, &ink, &fill)) int width = 0;
if (!PyArg_ParseTuple(args, "Oi|ii", &data, &ink, &fill, &width))
return NULL; return NULL;
n = PyPath_Flatten(data, &xy); n = PyPath_Flatten(data, &xy);
@ -2920,7 +2925,7 @@ _draw_rectangle(ImagingDrawObject* self, PyObject* args)
n = ImagingDrawRectangle(self->image->image, n = ImagingDrawRectangle(self->image->image,
(int) xy[0], (int) xy[1], (int) xy[0], (int) xy[1],
(int) xy[2], (int) xy[3], (int) xy[2], (int) xy[3],
&ink, fill, self->blend &ink, fill, width, self->blend
); );
free(xy); free(xy);

View File

@ -634,8 +634,9 @@ ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
int int
ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1, ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
const void* ink_, int fill, int op) const void* ink_, int fill, int width, int op)
{ {
int i;
int y; int y;
int tmp; int tmp;
DRAW* draw; DRAW* draw;
@ -662,13 +663,16 @@ ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
draw->hline(im, x0, y, x1, ink); draw->hline(im, x0, y, x1, ink);
} else { } else {
/* outline */ /* outline */
draw->line(im, x0, y0, x1, y0, ink); if (width == 0) {
draw->line(im, x1, y0, x1, y1, ink); width = 1;
draw->line(im, x1, y1, x0, y1, ink); }
draw->line(im, x0, y1, x0, y0, ink); for (i = 0; i < width; i++) {
draw->hline(im, x0, y0+i, x1, ink);
draw->hline(im, x0, y1-i, x1, ink);
draw->line(im, x1-i, y0, x1-i, y1, ink);
draw->line(im, x0+i, y1, x0+i, y0, ink);
}
} }
return 0; return 0;
@ -758,9 +762,10 @@ ellipsePoint(int cx, int cy, int w, int h,
static int static int
ellipse(Imaging im, int x0, int y0, int x1, int y1, ellipse(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink_, int fill, float start, float end, const void* ink_, int fill,
int mode, int op) int width, int mode, int op)
{ {
float i; float i;
int j;
int n; int n;
int cx, cy; int cx, cy;
int w, h; int w, h;
@ -770,120 +775,136 @@ ellipse(Imaging im, int x0, int y0, int x1, int y1,
DRAW* draw; DRAW* draw;
INT32 ink; INT32 ink;
w = x1 - x0;
h = y1 - y0;
if (w < 0 || h < 0)
return 0;
DRAWINIT(); DRAWINIT();
cx = (x0 + x1) / 2; if (width == 0) {
cy = (y0 + y1) / 2; width = 1;
while (end < start)
end += 360;
if (end - start > 360) {
/* no need to go in loops */
end = start + 361;
} }
if (mode != ARC && fill) { for (j = 0; j < width; j++) {
/* Build edge list */ w = x1 - x0;
/* malloc check UNDONE, FLOAT? */ h = y1 - y0;
Edge* e = calloc((end - start + 3), sizeof(Edge)); if (w < 0 || h < 0)
if (!e) { return 0;
ImagingError_MemoryError();
return -1; cx = (x0 + x1) / 2;
cy = (y0 + y1) / 2;
while (end < start)
end += 360;
if (end - start > 360) {
/* no need to go in loops */
end = start + 361;
} }
n = 0; if (mode != ARC && fill) {
for (i = start; i < end+1; i++) { /* Build edge list */
if (i > end) { /* malloc check UNDONE, FLOAT? */
i = end; Edge* e = calloc((end - start + 3), sizeof(Edge));
if (!e) {
ImagingError_MemoryError();
return -1;
} }
ellipsePoint(cx, cy, w, h, i, &x, &y); n = 0;
if (i != start)
add_edge(&e[n++], lx, ly, x, y);
else
sx = x, sy = y;
lx = x, ly = y;
}
if (n > 0) { for (i = start; i < end+1; i++) {
/* close and draw polygon */ if (i > end) {
if (mode == PIESLICE) { i = end;
if (x != cx || y != cy) {
add_edge(&e[n++], x, y, cx, cy);
add_edge(&e[n++], cx, cy, sx, sy);
} }
} else { ellipsePoint(cx, cy, w, h, i, &x, &y);
if (x != sx || y != sy) if (i != start)
add_edge(&e[n++], x, y, sx, sy); add_edge(&e[n++], lx, ly, x, y);
else
sx = x, sy = y;
lx = x, ly = y;
} }
draw->polygon(im, n, e, ink, 0);
}
free(e); if (n > 0) {
/* close and draw polygon */
} else { if (mode == PIESLICE) {
if (x != cx || y != cy) {
for (i = start; i < end+1; i++) { add_edge(&e[n++], x, y, cx, cy);
if (i > end) { add_edge(&e[n++], cx, cy, sx, sy);
i = end; }
} } else {
ellipsePoint(cx, cy, w, h, i, &x, &y); if (x != sx || y != sy)
if (i != start) add_edge(&e[n++], x, y, sx, sy);
draw->line(im, lx, ly, x, y, ink); }
else draw->polygon(im, n, e, ink, 0);
sx = x, sy = y; }
lx = x, ly = y;
} free(e);
if (i != start) { } else {
if (mode == PIESLICE) {
if (x != cx || y != cy) { for (i = start; i < end+1; i++) {
draw->line(im, x, y, cx, cy, ink); if (i > end) {
draw->line(im, cx, cy, sx, sy, ink); i = end;
}
ellipsePoint(cx, cy, w, h, i, &x, &y);
if (i != start)
draw->line(im, lx, ly, x, y, ink);
else
sx = x, sy = y;
lx = x, ly = y;
}
if (i != start) {
if (mode == PIESLICE) {
if (j == 0 && (x != cx || y != cy)) {
if (width == 1) {
draw->line(im, x, y, cx, cy, 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) {
if (x != sx || y != sy)
draw->line(im, x, y, sx, sy, ink);
} }
} else if (mode == CHORD) {
if (x != sx || y != sy)
draw->line(im, x, y, sx, sy, ink);
} }
} }
x0++;
y0++;
x1--;
y1--;
} }
return 0; return 0;
} }
int int
ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1, ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink, int op) float start, float end, const void* ink, int width, int op)
{ {
return ellipse(im, x0, y0, x1, y1, start, end, ink, 0, ARC, op); return ellipse(im, x0, y0, x1, y1, start, end, ink, 0, width, ARC, op);
} }
int int
ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1, ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink, int fill, int op) float start, float end, const void* ink, int fill,
int width, int op)
{ {
return ellipse(im, x0, y0, x1, y1, start, end, ink, fill, CHORD, op); return ellipse(im, x0, y0, x1, y1, start, end, ink, fill, width, CHORD, op);
} }
int int
ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1, ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1,
const void* ink, int fill, int op) const void* ink, int fill, int width, int op)
{ {
return ellipse(im, x0, y0, x1, y1, 0, 360, ink, fill, CHORD, op); return ellipse(im, x0, y0, x1, y1, 0, 360, ink, fill, width, CHORD, op);
} }
int int
ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1, ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink, int fill, int op) float start, float end, const void* ink, int fill,
int width, int op)
{ {
return ellipse(im, x0, y0, x1, y1, start, end, ink, fill, PIESLICE, op); return ellipse(im, x0, y0, x1, y1, start, end, ink, fill, width, PIESLICE, op);
} }
/* -------------------------------------------------------------------- */ /* -------------------------------------------------------------------- */

View File

@ -349,26 +349,27 @@ extern void ImagingCrack(Imaging im, int x0, int y0);
/* Graphics */ /* Graphics */
extern int ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1, extern int ImagingDrawArc(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink, int op); float start, float end, const void* ink, int width,
int op);
extern int ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap, extern int ImagingDrawBitmap(Imaging im, int x0, int y0, Imaging bitmap,
const void* ink, int op); const void* ink, int op);
extern int ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1, extern int ImagingDrawChord(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink, int fill, float start, float end, const void* ink, int fill,
int op); int width, int op);
extern int ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1, extern int ImagingDrawEllipse(Imaging im, int x0, int y0, int x1, int y1,
const void* ink, int fill, int op); const void* ink, int fill, int width, int op);
extern int ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1, extern int ImagingDrawLine(Imaging im, int x0, int y0, int x1, int y1,
const void* ink, int op); const void* ink, int op);
extern int ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1, extern int ImagingDrawWideLine(Imaging im, int x0, int y0, int x1, int y1,
const void* ink, int width, int op); const void* ink, int width, int op);
extern int ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1, extern int ImagingDrawPieslice(Imaging im, int x0, int y0, int x1, int y1,
float start, float end, const void* ink, int fill, float start, float end, const void* ink, int fill,
int op); int width, int op);
extern int ImagingDrawPoint(Imaging im, int x, int y, const void* ink, int op); extern int ImagingDrawPoint(Imaging im, int x, int y, const void* ink, int op);
extern int ImagingDrawPolygon(Imaging im, int points, int *xy, extern int ImagingDrawPolygon(Imaging im, int points, int *xy,
const void* ink, int fill, int op); const void* ink, int fill, int op);
extern int ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1, extern int ImagingDrawRectangle(Imaging im, int x0, int y0, int x1, int y1,
const void* ink, int fill, int op); const void* ink, int fill, int width, int op);
/* Level 2 graphics (WORK IN PROGRESS) */ /* Level 2 graphics (WORK IN PROGRESS) */
extern ImagingOutline ImagingOutlineNew(void); extern ImagingOutline ImagingOutlineNew(void);