Skip to content

Commit b473f0b

Browse files
clang-format, docs, report error
1 parent 8b019c9 commit b473f0b

File tree

3 files changed

+112
-73
lines changed

3 files changed

+112
-73
lines changed

docs/reST/ref/draw.rst

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -541,6 +541,33 @@ object around the draw calls (see :func:`pygame.Surface.lock` and
541541
.. versionchanged:: 2.5.0 ``blend`` argument readded for backcompat, but will always raise a deprecation exception when used
542542

543543
.. ## pygame.draw.aalines ##
544+
545+
.. function:: flood_fill
546+
547+
| :sl:`fill in a connected area of same-color pixels`
548+
| :sg:`flood_fill(surface, color, starting_point) -> Rect`
549+
| :sg:`flood_fill(surface, pattern_surface, starting_point) -> Rect`
550+
551+
Replace the color of a cluster of connected same-color pixels, beginning
552+
from the starting point, with a repeating pattern or solid single color
553+
554+
:param Surface surface: surface to draw on
555+
:param color: color to draw with, the alpha value is optional if using a
556+
tuple ``(RGB[A])``
557+
:type color: Color or string (for :doc:`color_list`) or int or tuple(int, int, int, [int])
558+
:param pattern_surface: pattern to fill with, as a surface
559+
:param starting_point: starting point as a sequence of 2 ints/floats,
560+
e.g. ``(x, y)``
561+
:type starting_point: tuple(int or float, int or float) or
562+
list(int or float, int or float) or Vector2(int or float, int or float)
563+
564+
:returns: a rect bounding the changed pixels, if nothing is drawn the
565+
bounding rect's position will be the position of the starting point
566+
and its width and height will be 0
567+
:rtype: Rect
568+
569+
.. versionadded:: 2.5.0
570+
.. ## pygame.draw.flood_fill ##
544571
545572
.. ## pygame.draw ##
546573

src_c/doc/draw_doc.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,4 @@
99
#define DOC_DRAW_LINES "lines(surface, color, closed, points) -> Rect\nlines(surface, color, closed, points, width=1) -> Rect\ndraw multiple contiguous straight line segments"
1010
#define DOC_DRAW_AALINE "aaline(surface, color, start_pos, end_pos) -> Rect\ndraw a straight antialiased line"
1111
#define DOC_DRAW_AALINES "aalines(surface, color, closed, points) -> Rect\ndraw multiple contiguous straight antialiased line segments"
12+
#define DOC_DRAW_FLOODFILL "flood_fill(surface, color, starting_point) -> Rect\nflood_fill(surface, pattern_surface, starting_point) -> Rect\nfill in a connected area of same-color pixels"

src_c/draw.c

Lines changed: 84 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -995,7 +995,8 @@ flood_fill(PyObject *self, PyObject *arg, PyObject *kwargs)
995995
int startx, starty;
996996
Uint32 color;
997997
SDL_Surface *pattern = NULL;
998-
SDL_bool did_lock=SDL_FALSE;
998+
SDL_bool did_lock = SDL_FALSE;
999+
int flood_fill_result;
9991000

10001001
int drawn_area[4] = {INT_MAX, INT_MAX, INT_MIN,
10011002
INT_MIN}; /* Used to store bounding box values */
@@ -1016,47 +1017,50 @@ flood_fill(PyObject *self, PyObject *arg, PyObject *kwargs)
10161017
PG_SURF_BytesPerPixel(surf));
10171018
}
10181019

1019-
if (pgSurface_Check(colorobj)){
1020-
pat_surfobj = ((pgSurfaceObject *) colorobj);
1020+
if (pgSurface_Check(colorobj)) {
1021+
pat_surfobj = ((pgSurfaceObject *)colorobj);
10211022

1022-
pattern= SDL_ConvertSurface
1023-
(pat_surfobj->surf, surf->format, 0);
1023+
pattern = SDL_ConvertSurface(pat_surfobj->surf, surf->format, 0);
10241024

1025-
if(pattern==NULL){
1025+
if (pattern == NULL) {
10261026
return RAISE(PyExc_RuntimeError, "error converting pattern surf");
10271027
}
10281028

1029-
SDL_SetSurfaceRLE(pattern,
1030-
SDL_FALSE);
1029+
SDL_SetSurfaceRLE(pattern, SDL_FALSE);
10311030

1032-
color=0;
1033-
} else {
1031+
color = 0;
1032+
}
1033+
else {
10341034
CHECK_LOAD_COLOR(colorobj);
10351035
}
10361036

10371037
if (!pg_TwoIntsFromObj(start, &startx, &starty)) {
10381038
return RAISE(PyExc_TypeError, "invalid start_pos argument");
10391039
}
10401040

1041-
if(SDL_MUSTLOCK(surf)){
1042-
did_lock=SDL_TRUE;
1041+
if (SDL_MUSTLOCK(surf)) {
1042+
did_lock = SDL_TRUE;
10431043
if (!pgSurface_Lock(surfobj)) {
10441044
return RAISE(PyExc_RuntimeError, "error locking surface");
10451045
}
10461046
}
10471047

1048-
flood_fill_inner(surf, startx, starty, color, pattern, drawn_area);
1048+
flood_fill_result = flood_fill_inner(surf, startx, starty, color, pattern, drawn_area);
10491049

1050-
if(pattern!=NULL){
1050+
if (pattern != NULL) {
10511051
SDL_FreeSurface(pattern);
10521052
}
10531053

1054-
if(did_lock){
1054+
if (did_lock) {
10551055
if (!pgSurface_Unlock(surfobj)) {
10561056
return RAISE(PyExc_RuntimeError, "error unlocking surface");
10571057
}
10581058
}
10591059

1060+
if(flood_fill_result == -1){
1061+
return RAISE(PyExc_RuntimeError, "flood fill allocation fail");
1062+
}
1063+
10601064
/* Compute return rect. */
10611065
if (drawn_area[0] != INT_MAX && drawn_area[1] != INT_MAX &&
10621066
drawn_area[2] != INT_MIN && drawn_area[3] != INT_MIN)
@@ -1079,20 +1083,25 @@ swap(float *a, float *b)
10791083

10801084
#define WORD_BITS (8 * sizeof(unsigned int))
10811085

1082-
struct point2d{
1086+
struct point2d {
10831087
Uint32 x;
10841088
Uint32 y;
10851089
};
10861090

1087-
static inline void _bitarray_set(unsigned int * bitarray, size_t idx, SDL_bool value){
1088-
if(value){
1091+
static inline void
1092+
_bitarray_set(unsigned int *bitarray, size_t idx, SDL_bool value)
1093+
{
1094+
if (value) {
10891095
bitarray[idx / WORD_BITS] |= (1 << (idx % WORD_BITS));
1090-
} else {
1096+
}
1097+
else {
10911098
bitarray[idx / WORD_BITS] &= (~(1) << (idx % WORD_BITS));
10921099
}
10931100
}
10941101

1095-
static inline SDL_bool _bitarray_get(unsigned int * bitarray, size_t idx) {
1102+
static inline SDL_bool
1103+
_bitarray_get(unsigned int *bitarray, size_t idx)
1104+
{
10961105
if (bitarray[idx / WORD_BITS] & (1 << (idx % WORD_BITS)))
10971106
return SDL_TRUE;
10981107
else
@@ -1786,42 +1795,44 @@ draw_line(SDL_Surface *surf, int x1, int y1, int x2, int y2, Uint32 color,
17861795

17871796

17881797
static int
1789-
flood_fill_inner(SDL_Surface *surf, int x1, int y1, Uint32 new_color, SDL_Surface *pattern, int *drawn_area)
1798+
flood_fill_inner(SDL_Surface *surf, int x1, int y1, Uint32 new_color,
1799+
SDL_Surface *pattern, int *drawn_area)
17901800
{
17911801
SDL_Rect cliprect;
17921802

17931803
SDL_GetClipRect(surf, &cliprect);
1794-
size_t frontier_bufsize=8, frontier_size=1, next_frontier_size=0;
1804+
size_t frontier_bufsize = 8, frontier_size = 1, next_frontier_size = 0;
17951805

1796-
struct point2d *frontier = malloc(frontier_bufsize * sizeof(struct point2d));
1797-
if(frontier==NULL){
1806+
struct point2d *frontier =
1807+
malloc(frontier_bufsize * sizeof(struct point2d));
1808+
if (frontier == NULL) {
17981809
return -1;
17991810
}
18001811

1801-
struct point2d *frontier_next = malloc(frontier_bufsize * sizeof(struct point2d));
1812+
struct point2d *frontier_next =
1813+
malloc(frontier_bufsize * sizeof(struct point2d));
18021814

1803-
if(frontier_next==NULL){
1815+
if (frontier_next == NULL) {
18041816
free(frontier);
18051817
return -1;
18061818
}
1807-
size_t mask_size = cliprect.w*cliprect.h;
1819+
size_t mask_size = cliprect.w * cliprect.h;
18081820

18091821
unsigned int *mask = calloc((mask_size) / 8 + 1, sizeof(unsigned int));
1810-
if (mask==NULL){
1822+
if (mask == NULL) {
18111823
free(frontier);
18121824
free(frontier_next);
18131825
free(mask);
18141826
return -1;
18151827
}
1816-
Uint32 old_color=0;
1828+
Uint32 old_color = 0;
18171829
Uint8 *pix;
18181830

1819-
int VN_X[]= {0,0,1,-1};
1820-
int VN_Y[]= {1,-1,0,0};
1831+
int VN_X[] = {0, 0, 1, -1};
1832+
int VN_Y[] = {1, -1, 0, 0};
18211833

1822-
1823-
if (!(x1>=cliprect.x && x1<(cliprect.x+cliprect.w)
1824-
&& y1>=cliprect.y && y1<(cliprect.y+cliprect.h))) {
1834+
if (!(x1 >= cliprect.x && x1 < (cliprect.x + cliprect.w) &&
1835+
y1 >= cliprect.y && y1 < (cliprect.y + cliprect.h))) {
18251836
free(frontier);
18261837
free(mask);
18271838
return 0;
@@ -1830,99 +1841,99 @@ flood_fill_inner(SDL_Surface *surf, int x1, int y1, Uint32 new_color, SDL_Surfac
18301841
SURF_GET_AT(old_color, surf, x1, y1, (Uint8 *)surf->pixels, surf->format,
18311842
pix);
18321843

1833-
if (pattern==NULL && old_color == new_color){
1844+
if (pattern == NULL && old_color == new_color) {
18341845
free(frontier);
18351846
free(mask);
18361847
free(frontier_next);
18371848
return 0;
18381849
}
18391850

1840-
frontier[0].x=x1;
1841-
frontier[0].y=y1;
1851+
frontier[0].x = x1;
1852+
frontier[0].y = y1;
18421853

1843-
while (frontier_size!=0){
1844-
next_frontier_size=0;
1854+
while (frontier_size != 0) {
1855+
next_frontier_size = 0;
18451856

1846-
for (size_t i=0; i<frontier_size; i++){
1847-
unsigned int x=frontier[i].x;
1848-
unsigned int y=frontier[i].y;
1849-
size_t mask_idx = (y-cliprect.y)*cliprect.w+(x-cliprect.x);
1857+
for (size_t i = 0; i < frontier_size; i++) {
1858+
unsigned int x = frontier[i].x;
1859+
unsigned int y = frontier[i].y;
1860+
size_t mask_idx = (y - cliprect.y) * cliprect.w + (x - cliprect.x);
18501861

1851-
Uint32 current_color=0;
1862+
Uint32 current_color = 0;
18521863

18531864
_bitarray_set(mask, mask_idx, SDL_TRUE);
18541865

1855-
SURF_GET_AT(current_color, surf, x, y,
1856-
(Uint8 *)surf->pixels, surf->format,
1857-
pix);
1866+
SURF_GET_AT(current_color, surf, x, y, (Uint8 *)surf->pixels,
1867+
surf->format, pix);
18581868

1859-
if (current_color!=old_color){
1869+
if (current_color != old_color) {
18601870
continue;
18611871
}
18621872

1863-
if (pattern!=NULL){
1864-
SURF_GET_AT(new_color, pattern, x%pattern->w, y%pattern->h,
1865-
(Uint8 *)pattern->pixels, pattern->format,
1866-
pix);
1873+
if (pattern != NULL) {
1874+
SURF_GET_AT(new_color, pattern, x % pattern->w, y % pattern->h,
1875+
(Uint8 *)pattern->pixels, pattern->format, pix);
18671876
}
18681877

18691878
unsafe_set_at(surf, x, y, new_color);
18701879
add_pixel_to_drawn_list(x, y, drawn_area);
18711880

1872-
for (int n=0; n<4; n++){
1873-
long nx=x+VN_X[n];
1874-
long ny=y+VN_Y[n];
1881+
for (int n = 0; n < 4; n++) {
1882+
long nx = x + VN_X[n];
1883+
long ny = y + VN_Y[n];
18751884
SDL_bool found_in_frontier = SDL_FALSE;
18761885

1877-
if (!(nx>=cliprect.x && nx<cliprect.x+cliprect.w
1878-
&& ny>=cliprect.y && ny<cliprect.y+cliprect.h)) {
1886+
if (!(nx >= cliprect.x && nx < cliprect.x + cliprect.w &&
1887+
ny >= cliprect.y && ny < cliprect.y + cliprect.h)) {
18791888
continue;
18801889
}
18811890

1882-
mask_idx = (ny-cliprect.y)*cliprect.w+(nx-cliprect.x);
1891+
mask_idx = (ny - cliprect.y) * cliprect.w + (nx - cliprect.x);
18831892
if (_bitarray_get(mask, mask_idx))
18841893
continue;
18851894

18861895
_bitarray_set(mask, mask_idx, SDL_TRUE);
1887-
if(found_in_frontier){
1896+
if (found_in_frontier) {
18881897
continue;
18891898
}
18901899

1891-
if (next_frontier_size==frontier_bufsize){
1900+
if (next_frontier_size == frontier_bufsize) {
18921901
struct point2d *old_buf = frontier_next;
18931902

1894-
frontier_bufsize*=4;
1903+
frontier_bufsize *= 4;
18951904

1896-
frontier_next = realloc(frontier_next, frontier_bufsize*sizeof(struct point2d));
1897-
if(frontier_next==NULL){
1905+
frontier_next =
1906+
realloc(frontier_next,
1907+
frontier_bufsize * sizeof(struct point2d));
1908+
if (frontier_next == NULL) {
18981909
free(mask);
18991910
free(frontier);
19001911
free(old_buf);
19011912
return -1;
19021913
}
19031914

19041915
old_buf = frontier;
1905-
frontier = realloc(frontier, frontier_bufsize*sizeof(struct point2d));
1906-
if(frontier==NULL){
1916+
frontier = realloc(
1917+
frontier, frontier_bufsize * sizeof(struct point2d));
1918+
if (frontier == NULL) {
19071919
free(old_buf);
19081920
free(mask);
19091921
free(frontier_next);
19101922
return -1;
19111923
}
19121924
}
19131925

1914-
frontier_next[next_frontier_size].x=nx;
1915-
frontier_next[next_frontier_size].y=ny;
1926+
frontier_next[next_frontier_size].x = nx;
1927+
frontier_next[next_frontier_size].y = ny;
19161928
next_frontier_size++;
1917-
19181929
}
19191930
}
19201931
struct point2d *temp_buf;
1921-
temp_buf=frontier;
1922-
frontier=frontier_next;
1923-
frontier_next=temp_buf;
1932+
temp_buf = frontier;
1933+
frontier = frontier_next;
1934+
frontier_next = temp_buf;
19241935

1925-
frontier_size=next_frontier_size;
1936+
frontier_size = next_frontier_size;
19261937
}
19271938
free(frontier);
19281939
free(mask);
@@ -3134,7 +3145,7 @@ static PyMethodDef _draw_methods[] = {
31343145
{"ellipse", (PyCFunction)ellipse, METH_VARARGS | METH_KEYWORDS,
31353146
DOC_DRAW_ELLIPSE},
31363147
{"flood_fill", (PyCFunction)flood_fill, METH_VARARGS | METH_KEYWORDS,
3137-
""},
3148+
DOC_DRAW_FLOODFILL},
31383149
{"arc", (PyCFunction)arc, METH_VARARGS | METH_KEYWORDS, DOC_DRAW_ARC},
31393150
{"circle", (PyCFunction)circle, METH_VARARGS | METH_KEYWORDS,
31403151
DOC_DRAW_CIRCLE},

0 commit comments

Comments
 (0)