@@ -1985,9 +1985,8 @@ extract_color(SDL_Surface *surf, PyObject *color_obj, Uint8 rgba_color[],
1985
1985
*/
1986
1986
static void
1987
1987
draw_to_surface (SDL_Surface * surf , bitmask_t * bitmask , int x_dest , int y_dest ,
1988
- SDL_Rect * area_rect , int draw_setbits , int draw_unsetbits ,
1989
- SDL_Surface * setsurf , SDL_Surface * unsetsurf , Uint32 * setcolor ,
1990
- Uint32 * unsetcolor )
1988
+ int draw_setbits , int draw_unsetbits , SDL_Surface * setsurf ,
1989
+ SDL_Surface * unsetsurf , Uint32 * setcolor , Uint32 * unsetcolor )
1991
1990
{
1992
1991
Uint8 * pixel = NULL ;
1993
1992
Uint8 bpp ;
@@ -2003,15 +2002,6 @@ draw_to_surface(SDL_Surface *surf, bitmask_t *bitmask, int x_dest, int y_dest,
2003
2002
return ;
2004
2003
}
2005
2004
2006
- if (area_rect -> x < 0 ) {
2007
- x_dest -= area_rect -> x ;
2008
- area_rect -> w += area_rect -> x ;
2009
- }
2010
- if (area_rect -> y < 0 ) {
2011
- y_dest -= area_rect -> y ;
2012
- area_rect -> h += area_rect -> y ;
2013
- }
2014
-
2015
2005
/* There is also nothing to do when the destination position is such that
2016
2006
* nothing will be drawn on the surface. */
2017
2007
if ((x_dest >= surf -> w ) || (y_dest >= surf -> h ) || (- x_dest > bitmask -> w ) ||
@@ -2021,23 +2011,13 @@ draw_to_surface(SDL_Surface *surf, bitmask_t *bitmask, int x_dest, int y_dest,
2021
2011
2022
2012
bpp = PG_SURF_BytesPerPixel (surf );
2023
2013
2024
- // clamp rect width and height to not stick out of the mask
2025
- area_rect -> w = MIN (area_rect -> w , bitmask -> w - area_rect -> x );
2026
- area_rect -> h = MIN (area_rect -> h , bitmask -> h - area_rect -> y );
2027
-
2028
2014
xm_start = (x_dest < 0 ) ? - x_dest : 0 ;
2029
- if (area_rect -> x > 0 ) {
2030
- xm_start += area_rect -> x ;
2031
- }
2032
2015
x_start = (x_dest > 0 ) ? x_dest : 0 ;
2033
- x_end = MIN (MIN ( surf -> w , bitmask -> w + x_dest ), x_dest + area_rect -> w );
2016
+ x_end = MIN (surf -> w , bitmask -> w + x_dest );
2034
2017
2035
2018
ym_start = (y_dest < 0 ) ? - y_dest : 0 ;
2036
- if (area_rect -> y > 0 ) {
2037
- ym_start += area_rect -> y ;
2038
- }
2039
2019
y_start = (y_dest > 0 ) ? y_dest : 0 ;
2040
- y_end = MIN (MIN ( surf -> h , bitmask -> h + y_dest ), y_dest + area_rect -> h );
2020
+ y_end = MIN (surf -> h , bitmask -> h + y_dest );
2041
2021
2042
2022
if (NULL == setsurf && NULL == unsetsurf ) {
2043
2023
/* Draw just using color values. No surfaces. */
@@ -2181,7 +2161,7 @@ mask_to_surface(PyObject *self, PyObject *args, PyObject *kwargs)
2181
2161
PyObject * destobj = NULL , * areaobj = NULL ;
2182
2162
SDL_Rect * area_rect , temp_rect ;
2183
2163
SDL_Surface * surf = NULL , * setsurf = NULL , * unsetsurf = NULL ;
2184
- bitmask_t * bitmask = pgMask_AsBitmap (self );
2164
+ bitmask_t * bitmask = pgMask_AsBitmap (self ), * area_bitmask ;
2185
2165
Uint32 * setcolor_ptr = NULL , * unsetcolor_ptr = NULL ;
2186
2166
Uint32 setcolor , unsetcolor ;
2187
2167
int draw_setbits = 0 , draw_unsetbits = 0 ;
@@ -2200,10 +2180,64 @@ mask_to_surface(PyObject *self, PyObject *args, PyObject *kwargs)
2200
2180
return NULL ; /* Exception already set. */
2201
2181
}
2202
2182
2183
+ if (NULL != destobj ) {
2184
+ int tempx = 0 , tempy = 0 ;
2185
+
2186
+ /* Destination coordinates can be extracted from:
2187
+ * - lists/tuples with 2 items
2188
+ * - Rect (or Rect like) objects (uses x, y values) */
2189
+ if (pg_TwoIntsFromObj (destobj , & tempx , & tempy )) {
2190
+ x_dest = tempx ;
2191
+ y_dest = tempy ;
2192
+ }
2193
+ else {
2194
+ SDL_Rect temp_rect ;
2195
+ SDL_Rect * dest_rect = pgRect_FromObject (destobj , & temp_rect );
2196
+
2197
+ if (NULL != dest_rect ) {
2198
+ x_dest = dest_rect -> x ;
2199
+ y_dest = dest_rect -> y ;
2200
+ }
2201
+ else {
2202
+ PyErr_SetString (PyExc_TypeError , "invalid dest argument" );
2203
+ goto to_surface_error ;
2204
+ }
2205
+ }
2206
+ }
2207
+
2208
+ if (areaobj && areaobj != Py_None ) {
2209
+ if (!(area_rect = pgRect_FromObject (areaobj , & temp_rect ))) {
2210
+ PyErr_SetString (PyExc_TypeError , "invalid rectstyle argument" );
2211
+ goto to_surface_error ;
2212
+ }
2213
+ }
2214
+ else {
2215
+ temp_rect .x = temp_rect .y = 0 ;
2216
+ temp_rect .w = bitmask -> w ;
2217
+ temp_rect .h = bitmask -> h ;
2218
+ area_rect = & temp_rect ;
2219
+ }
2220
+
2221
+ if (area_rect -> x < 0 ) {
2222
+ // x_dest -= area_rect->x;
2223
+ area_rect -> w += area_rect -> x ;
2224
+ area_rect -> x = 0 ;
2225
+ }
2226
+ if (area_rect -> y < 0 ) {
2227
+ // y_dest -= area_rect->y;
2228
+ area_rect -> h += area_rect -> y ;
2229
+ area_rect -> y = 0 ;
2230
+ }
2231
+
2232
+ // clamp rect width and height to not stick out of the mask
2233
+ area_rect -> w = MAX (MIN (area_rect -> w , bitmask -> w - area_rect -> x ), 0 );
2234
+ area_rect -> h = MAX (MIN (area_rect -> h , bitmask -> h - area_rect -> y ), 0 );
2235
+ // pgRect_Normalize(area_rect);
2236
+
2203
2237
if (Py_None == surfobj ) {
2204
- surfobj =
2205
- PyObject_CallFunction (( PyObject * ) & pgSurface_Type , "(ii)ii" ,
2206
- bitmask -> w , bitmask -> h , PGS_SRCALPHA , 32 );
2238
+ surfobj = PyObject_CallFunction (( PyObject * ) & pgSurface_Type , "(ii)ii" ,
2239
+ area_rect -> w , area_rect -> h ,
2240
+ PGS_SRCALPHA , 32 );
2207
2241
2208
2242
if (NULL == surfobj ) {
2209
2243
if (!PyErr_Occurred ()) {
@@ -2287,44 +2321,6 @@ mask_to_surface(PyObject *self, PyObject *args, PyObject *kwargs)
2287
2321
draw_unsetbits = 1 ;
2288
2322
}
2289
2323
2290
- if (NULL != destobj ) {
2291
- int tempx = 0 , tempy = 0 ;
2292
-
2293
- /* Destination coordinates can be extracted from:
2294
- * - lists/tuples with 2 items
2295
- * - Rect (or Rect like) objects (uses x, y values) */
2296
- if (pg_TwoIntsFromObj (destobj , & tempx , & tempy )) {
2297
- x_dest = tempx ;
2298
- y_dest = tempy ;
2299
- }
2300
- else {
2301
- SDL_Rect temp_rect ;
2302
- SDL_Rect * dest_rect = pgRect_FromObject (destobj , & temp_rect );
2303
-
2304
- if (NULL != dest_rect ) {
2305
- x_dest = dest_rect -> x ;
2306
- y_dest = dest_rect -> y ;
2307
- }
2308
- else {
2309
- PyErr_SetString (PyExc_TypeError , "invalid dest argument" );
2310
- goto to_surface_error ;
2311
- }
2312
- }
2313
- }
2314
-
2315
- if (areaobj && areaobj != Py_None ) {
2316
- if (!(area_rect = pgRect_FromObject (areaobj , & temp_rect ))) {
2317
- PyErr_SetString (PyExc_TypeError , "invalid rectstyle argument" );
2318
- goto to_surface_error ;
2319
- }
2320
- }
2321
- else {
2322
- temp_rect .x = temp_rect .y = 0 ;
2323
- temp_rect .w = bitmask -> w ;
2324
- temp_rect .h = bitmask -> h ;
2325
- area_rect = & temp_rect ;
2326
- }
2327
-
2328
2324
if (!pgSurface_Lock ((pgSurfaceObject * )surfobj )) {
2329
2325
PyErr_SetString (PyExc_RuntimeError , "cannot lock surface" );
2330
2326
goto to_surface_error ;
@@ -2345,14 +2341,42 @@ mask_to_surface(PyObject *self, PyObject *args, PyObject *kwargs)
2345
2341
goto to_surface_error ;
2346
2342
}
2347
2343
2344
+ if (areaobj ) {
2345
+ assert (area_rect -> w >= 0 && area_rect -> w >= 0 );
2346
+ area_bitmask = bitmask_create (area_rect -> w , area_rect -> h );
2347
+ if (NULL == area_bitmask ) {
2348
+ PyErr_Format (PyExc_MemoryError , "failed to allocate memory for a mask" );
2349
+ return NULL ;
2350
+ }
2351
+
2352
+ bitmask_t * overlap_bitmask = bitmask_copy (area_bitmask );
2353
+ if (NULL == overlap_bitmask ) {
2354
+ PyErr_SetString (PyExc_MemoryError , "failed to allocate memory for a mask" );
2355
+ return NULL ;
2356
+ }
2357
+
2358
+ bitmask_fill (overlap_bitmask );
2359
+
2360
+ bitmask_overlap_mask (bitmask , overlap_bitmask , area_bitmask ,
2361
+ area_rect -> x , area_rect -> y );
2362
+ bitmask_free (overlap_bitmask );
2363
+ }
2364
+ else {
2365
+ area_bitmask = bitmask ;
2366
+ }
2367
+
2348
2368
Py_BEGIN_ALLOW_THREADS ; /* Release the GIL. */
2349
2369
2350
- draw_to_surface (surf , bitmask , x_dest , y_dest , area_rect , draw_setbits ,
2370
+ draw_to_surface (surf , area_bitmask , x_dest , y_dest , draw_setbits ,
2351
2371
draw_unsetbits , setsurf , unsetsurf , setcolor_ptr ,
2352
2372
unsetcolor_ptr );
2353
2373
2354
2374
Py_END_ALLOW_THREADS ; /* Obtain the GIL. */
2355
2375
2376
+ if (areaobj ) {
2377
+ bitmask_free (area_bitmask );
2378
+ }
2379
+
2356
2380
if (NULL != unsetsurf &&
2357
2381
!pgSurface_Unlock ((pgSurfaceObject * )unsetsurfobj )) {
2358
2382
PyErr_SetString (PyExc_RuntimeError , "cannot unlock unsetsurface" );
0 commit comments