1# Copyright 2014 Patrick Dawson <pat@dw.is>
2#
3# This software is provided 'as-is', without any express or implied
4# warranty.  In no event will the authors be held liable for any damages
5# arising from the use of this software.
6#
7# Permission is granted to anyone to use this software for any purpose,
8# including commercial applications, and to alter it and redistribute it
9# freely, subject to the following restrictions:
10#
11# 1. The origin of this software must not be misrepresented; you must not
12#    claim that you wrote the original software. If you use this software
13#    in a product, an acknowledgment in the product documentation would be
14#    appreciated but is not required.
15# 2. Altered source versions must be plainly marked as such, and must not be
16#    misrepresented as being the original software.
17# 3. This notice may not be removed or altered from any source distribution.
18
19from sdl2 cimport *
20from pygame_sdl2.surface cimport Surface
21
22import pygame_sdl2.gfxdraw as gfxdraw
23from pygame_sdl2.rect import Rect
24from pygame_sdl2.error import error
25
26def rect(Surface surface, color, rect, width=0):
27    if not isinstance(rect, Rect):
28        rect = Rect(rect)
29
30    if width == 0:
31        gfxdraw.box(surface, rect, color)
32    else:
33        gfxdraw.rectangle(surface, rect, color)
34        n = 1
35        while n < width:
36            r = Rect(rect.x - n, rect.y - n, rect.w + (n*2), rect.h + (n*2))
37            gfxdraw.rectangle(surface, r, color)
38            r = Rect(rect.x + n, rect.y + n, rect.w - (n*2), rect.h - (n*2))
39            gfxdraw.rectangle(surface, r, color)
40            n += 1
41    dirty = Rect(rect.x - width, rect.y - width, rect.w + (width*2), rect.h + (width*2))
42    return dirty.clip(surface.get_rect())
43
44def polygon(Surface surface, color, pointlist, width=0):
45    if width == 0:
46        gfxdraw.filled_polygon(surface, pointlist, color)
47        dirty = Rect(pointlist[0], (1, 1))
48        n = 1
49        while n < len(pointlist):
50            dirty.union_ip(Rect(pointlist[n], (1,1)))
51            n += 1
52        return dirty.clip(surface.get_rect())
53    else:
54        return lines(surface, color, True, pointlist, width)
55
56def circle(Surface surface, color, pos, radius, width=0):
57    x, y = pos
58    if width == 0:
59        gfxdraw.filled_circle(surface, x, y, radius, color)
60        dirty = Rect((x - radius, y - radius), (radius*2, radius*2))
61        return dirty.clip(surface.get_rect())
62    else:
63        gfxdraw.circle(surface, x, y, radius, color)
64        n = 1
65        while n < width:
66            gfxdraw.circle(surface, x, y, radius - n, color)
67            gfxdraw.circle(surface, x + 1, y, radius - n, color)
68            gfxdraw.circle(surface, x - 1, y, radius - n, color)
69            n += 1
70        dirty = Rect(x - radius - width, y - radius - width, (radius*2) + width, (radius*2) + width)
71        return dirty.clip(surface.get_rect())
72
73def ellipse(Surface surface, color, rect, width=0):
74    raise error("Not implemented.")
75
76def arc(Surface surface, color, rect, start_angle, stop_angle, width=1):
77    raise error("Not implemented.")
78
79def line(Surface surface, color, start_pos, end_pos, width=1):
80    gfxdraw.thick_line(surface, start_pos[0], start_pos[1],
81                       end_pos[0], end_pos[1], width, color)
82    dirty = Rect(start_pos, (width, width))
83    dirty.union_ip(Rect(end_pos, (width, width)))
84    return dirty.clip(surface.get_rect())
85
86def lines(Surface surface, color, closed, pointlist, width=1):
87    n = 0
88    dirty = Rect(pointlist[0], (width, width))
89    while n < len(pointlist) - 1:
90        line(surface, color, pointlist[n], pointlist[n+1], width)
91        dirty.union_ip(Rect(pointlist[n+1], (width, width)))
92        n += 1
93    if closed:
94        line(surface, color, pointlist[n], pointlist[0], width)
95    return dirty.clip(surface.get_rect())
96
97def aaline(Surface surface, color, startpos, endpos, blend=1):
98    x1, y1 = startpos
99    x2, y2 = endpos
100    gfxdraw.aaline(surface, x1, y1, x2, y2, color)
101    dirty = Rect(x1, y1, x2 - x1, y2 - y1)
102    return dirty.clip(surface.get_rect())
103
104def aalines(Surface surface, color, closed, pointlist, blend=1):
105    n = 0
106    dirty = Rect(pointlist[0], (1,1))
107    while n < len(pointlist) - 1:
108        r = aaline(surface, color, pointlist[n], pointlist[n+1])
109        dirty.union_ip(r)
110        n += 1
111    if closed:
112        aaline(surface, color, pointlist[n], pointlist[0])
113    return dirty.clip(surface.get_rect())
114