@@ -2159,91 +2159,36 @@ surf_blits(pgSurfaceObject *self, PyObject *args, PyObject *keywds)
2159
2159
#define FBLITS_ERR_NO_MEMORY 18
2160
2160
#define FBLITS_ERR_INVALID_SEQUENCE_LENGTH 19
2161
2161
#define FBLITS_ERR_INVALID_DESTINATION 20
2162
+ #define FBLITS_ERR_INVALID_SEQUENCE 21
2162
2163
2163
2164
int
2164
- _surf_fblits_item_check_and_blit (pgSurfaceObject * self , PyObject * item ,
2165
+ _surf_fblits_item_check_and_blit (PyObject * src_surf , SDL_Surface * src ,
2166
+ pgSurfaceObject * dest , int x , int y ,
2165
2167
int blend_flags )
2166
2168
{
2167
- PyObject * src_surf , * blit_pos ;
2168
- SDL_Surface * src ;
2169
- SDL_Rect * src_rect , temp , dest_rect ;
2170
-
2171
- /* Check that the item is a tuple of length 2 */
2172
- if (!PyTuple_Check (item ) || PyTuple_GET_SIZE (item ) != 2 ) {
2173
- return FBLITS_ERR_TUPLE_REQUIRED ;
2174
- }
2175
-
2176
- /* Extract the Surface and destination objects from the
2177
- * (Surface, dest) tuple */
2178
- src_surf = PyTuple_GET_ITEM (item , 0 );
2179
- blit_pos = PyTuple_GET_ITEM (item , 1 );
2180
-
2181
- /* Check that the source is a Surface */
2182
- if (!pgSurface_Check (src_surf )) {
2183
- return BLITS_ERR_SOURCE_NOT_SURFACE ;
2184
- }
2185
- if (!(src = pgSurface_AsSurface (src_surf ))) {
2186
- return BLITS_ERR_SEQUENCE_SURF ;
2187
- }
2169
+ SDL_Rect dest_rect = {x , y , src -> w , src -> h };
2188
2170
2189
- /* Try to extract a valid blit position */
2190
- if (pg_TwoIntsFromObj (blit_pos , & dest_rect .x , & dest_rect .y )) {
2191
- }
2192
- else if ((src_rect = pgRect_FromObject (blit_pos , & temp ))) {
2193
- dest_rect .x = src_rect -> x ;
2194
- dest_rect .y = src_rect -> y ;
2195
- }
2196
- else {
2197
- return BLITS_ERR_INVALID_DESTINATION ;
2198
- }
2199
-
2200
- dest_rect .w = src -> w ;
2201
- dest_rect .h = src -> h ;
2202
-
2203
- /* Perform the blit */
2204
- if (pgSurface_Blit (self , (pgSurfaceObject * )src_surf , & dest_rect , NULL ,
2205
- blend_flags )) {
2171
+ if (pgSurface_Blit (dest , (pgSurfaceObject * )src_surf , & dest_rect , NULL ,
2172
+ blend_flags ))
2206
2173
return BLITS_ERR_BLIT_FAIL ;
2207
- }
2208
2174
2209
2175
return 0 ;
2210
2176
}
2211
2177
2212
2178
int
2213
- _surf_fblits_cached_item_check_and_blit (pgSurfaceObject * self , PyObject * item ,
2179
+ _surf_fblits_cached_item_check_and_blit (pgSurfaceObject * self ,
2180
+ SDL_Surface * src , SDL_Surface * dst ,
2181
+ PyObject * pos_sequence ,
2214
2182
int blend_flags ,
2215
2183
BlitSequence * destinations )
2216
2184
{
2217
- PyObject * src_surf , * pos_list ;
2218
- SDL_Surface * src , * dst = pgSurface_AsSurface (self );
2185
+ PyObject * src_surf ;
2219
2186
SDL_Surface * subsurface ;
2220
2187
int suboffsetx = 0 , suboffsety = 0 ;
2221
2188
SDL_Rect orig_clip , sub_clip ;
2222
2189
int error = 0 ;
2223
2190
Py_ssize_t i ;
2224
2191
2225
- /* Check that the item is a tuple of length 2 */
2226
- if (!PyTuple_Check (item ) || PyTuple_GET_SIZE (item ) != 2 ) {
2227
- return FBLITS_ERR_TUPLE_REQUIRED ;
2228
- }
2229
-
2230
- /* Extract the Surface and sequence of destination objects from the
2231
- * (Surface, positions) tuple */
2232
- src_surf = PyTuple_GET_ITEM (item , 0 );
2233
- pos_list = PyTuple_GET_ITEM (item , 1 );
2234
-
2235
- if (!PyList_Check (pos_list )) {
2236
- return BLITS_ERR_SEQUENCE_REQUIRED ;
2237
- }
2238
-
2239
- /* Check that the source is a Surface */
2240
- if (!pgSurface_Check (src_surf )) {
2241
- return BLITS_ERR_SOURCE_NOT_SURFACE ;
2242
- }
2243
- if (!(src = pgSurface_AsSurface (src_surf ))) {
2244
- return BLITS_ERR_SEQUENCE_SURF ;
2245
- }
2246
-
2247
2192
/* Check that the source and destination surfaces have the same format */
2248
2193
if (src -> format -> format != dst -> format -> format ||
2249
2194
src -> format -> BytesPerPixel != dst -> format -> BytesPerPixel ||
@@ -2258,7 +2203,7 @@ _surf_fblits_cached_item_check_and_blit(pgSurfaceObject *self, PyObject *item,
2258
2203
}
2259
2204
2260
2205
/* manage destinations memory */
2261
- Py_ssize_t new_size = PyList_GET_SIZE ( pos_list );
2206
+ Py_ssize_t new_size = PySequence_Fast_GET_SIZE ( pos_sequence );
2262
2207
if (new_size > destinations -> alloc_size ) {
2263
2208
destinations -> sequence = (CachedBlitDest * )realloc (
2264
2209
destinations -> sequence , new_size * sizeof (CachedBlitDest ));
@@ -2311,12 +2256,12 @@ _surf_fblits_cached_item_check_and_blit(pgSurfaceObject *self, PyObject *item,
2311
2256
}
2312
2257
2313
2258
/* load destinations */
2314
- PyObject * * list_items = PySequence_Fast_ITEMS (pos_list );
2259
+ PyObject * * seq_items = PySequence_Fast_ITEMS (pos_sequence );
2315
2260
Py_ssize_t current_size = 0 ;
2316
2261
SDL_Rect src_dest = {0 , 0 , src -> w , src -> h };
2317
2262
SDL_Rect temp , * argrect ;
2318
2263
for (i = 0 ; i < destinations -> size ; i ++ ) {
2319
- PyObject * item = list_items [i ];
2264
+ PyObject * item = seq_items [i ];
2320
2265
2321
2266
if (pg_TwoIntsFromObj (item , & src_dest .x , & src_dest .y )) {
2322
2267
}
@@ -2372,6 +2317,70 @@ _surf_fblits_cached_item_check_and_blit(pgSurfaceObject *self, PyObject *item,
2372
2317
return error ;
2373
2318
}
2374
2319
2320
+ static void
2321
+ _surf_fblits_blit (pgSurfaceObject * self , PyObject * item , int blend_flags ,
2322
+ BlitSequence * destinations , int * error )
2323
+ {
2324
+ PyObject * src_surf , * pos_or_seq ;
2325
+ SDL_Surface * src , * dst = pgSurface_AsSurface (self );
2326
+ if (!dst ) {
2327
+ * error = BLITS_ERR_DISPLAY_SURF_QUIT ;
2328
+ return ;
2329
+ }
2330
+
2331
+ int x , y ;
2332
+
2333
+ if (PyTuple_Check (item ) && PyTuple_GET_SIZE (item ) == 2 ) {
2334
+ /* (Surface, dest) */
2335
+ src_surf = PyTuple_GET_ITEM (item , 0 );
2336
+ pos_or_seq = PyTuple_GET_ITEM (item , 1 );
2337
+ }
2338
+ else {
2339
+ * error = FBLITS_ERR_TUPLE_REQUIRED ;
2340
+ return ;
2341
+ }
2342
+
2343
+ /* Check that the source is a Surface */
2344
+ if (!pgSurface_Check (src_surf )) {
2345
+ * error = BLITS_ERR_SOURCE_NOT_SURFACE ;
2346
+ return ;
2347
+ }
2348
+ if (!(src = pgSurface_AsSurface (src_surf ))) {
2349
+ * error = BLITS_ERR_SEQUENCE_SURF ;
2350
+ return ;
2351
+ }
2352
+
2353
+ if (pgRect_Check (pos_or_seq )) {
2354
+ SDL_Rect * r = & pgRect_AsRect (pos_or_seq );
2355
+ x = r -> x ;
2356
+ y = r -> y ;
2357
+ * error = _surf_fblits_item_check_and_blit (src_surf , src , self , x , y ,
2358
+ blend_flags );
2359
+ return ;
2360
+ }
2361
+ else if (pgFRect_Check (pos_or_seq )) {
2362
+ SDL_FRect * r = & pgFRect_AsRect (pos_or_seq );
2363
+ x = (int )r -> x ;
2364
+ y = (int )r -> y ;
2365
+ * error = _surf_fblits_item_check_and_blit (src_surf , src , self , x , y ,
2366
+ blend_flags );
2367
+ return ;
2368
+ }
2369
+ else if (pg_TwoIntsFromObj (pos_or_seq , & x , & y )) {
2370
+ * error = _surf_fblits_item_check_and_blit (src_surf , src , self , x , y ,
2371
+ blend_flags );
2372
+ return ;
2373
+ }
2374
+
2375
+ if (!pgSequenceFast_Check (pos_or_seq )) {
2376
+ * error = FBLITS_ERR_INVALID_SEQUENCE ;
2377
+ return ;
2378
+ }
2379
+
2380
+ * error = _surf_fblits_cached_item_check_and_blit (
2381
+ self , src , dst , pos_or_seq , blend_flags , destinations );
2382
+ }
2383
+
2375
2384
static PyObject *
2376
2385
surf_fblits (pgSurfaceObject * self , PyObject * const * args , Py_ssize_t nargs )
2377
2386
{
@@ -2382,15 +2391,14 @@ surf_fblits(pgSurfaceObject *self, PyObject *const *args, Py_ssize_t nargs)
2382
2391
int blend_flags = 0 ; /* Default flag is 0, opaque */
2383
2392
int error = 0 ;
2384
2393
int is_generator = 0 ;
2385
- int cache = 0 ;
2386
2394
BlitSequence destinations = {NULL , 0 , 0 };
2387
2395
2388
- if (nargs == 0 || nargs > 3 ) {
2396
+ if (nargs == 0 || nargs > 2 ) {
2389
2397
error = FBLITS_ERR_INCORRECT_ARGS_NUM ;
2390
2398
goto on_error ;
2391
2399
}
2392
2400
/* Get the blend flags if they are passed */
2393
- else if (nargs > = 2 ) {
2401
+ else if (nargs = = 2 ) {
2394
2402
if (!PyLong_Check (args [1 ])) {
2395
2403
error = FBLITS_ERR_FLAG_NOT_NUMERIC ;
2396
2404
goto on_error ;
@@ -2399,17 +2407,6 @@ surf_fblits(pgSurfaceObject *self, PyObject *const *args, Py_ssize_t nargs)
2399
2407
if (PyErr_Occurred ()) {
2400
2408
return NULL ;
2401
2409
}
2402
-
2403
- if (nargs == 3 ) {
2404
- if (!PyBool_Check (args [2 ])) {
2405
- error = FBLITS_ERR_CACHE_NOT_NUMERIC ;
2406
- goto on_error ;
2407
- }
2408
- cache = PyObject_IsTrue (args [2 ]);
2409
- if (PyErr_Occurred ()) {
2410
- return NULL ;
2411
- }
2412
- }
2413
2410
}
2414
2411
2415
2412
blit_sequence = args [0 ];
@@ -2420,33 +2417,21 @@ surf_fblits(pgSurfaceObject *self, PyObject *const *args, Py_ssize_t nargs)
2420
2417
PyObject * * sequence_items = PySequence_Fast_ITEMS (blit_sequence );
2421
2418
for (i = 0 ; i < PySequence_Fast_GET_SIZE (blit_sequence ); i ++ ) {
2422
2419
item = sequence_items [i ];
2423
- if (cache ) {
2424
- error = _surf_fblits_cached_item_check_and_blit (
2425
- self , item , blend_flags , & destinations );
2426
- }
2427
- else {
2428
- error =
2429
- _surf_fblits_item_check_and_blit (self , item , blend_flags );
2430
- }
2431
- if (error ) {
2420
+
2421
+ _surf_fblits_blit (self , item , blend_flags , & destinations , & error );
2422
+
2423
+ if (error )
2432
2424
goto on_error ;
2433
- }
2434
2425
}
2435
2426
}
2436
2427
else if (PyIter_Check (blit_sequence )) {
2437
2428
is_generator = 1 ;
2438
2429
while ((item = PyIter_Next (blit_sequence ))) {
2439
- if (cache ) {
2440
- error = _surf_fblits_cached_item_check_and_blit (
2441
- self , item , blend_flags , & destinations );
2442
- }
2443
- else {
2444
- error =
2445
- _surf_fblits_item_check_and_blit (self , item , blend_flags );
2446
- }
2447
- if (error ) {
2430
+ _surf_fblits_blit (self , item , blend_flags , & destinations , & error );
2431
+
2432
+ if (error )
2448
2433
goto on_error ;
2449
- }
2434
+
2450
2435
Py_DECREF (item );
2451
2436
}
2452
2437
@@ -2521,11 +2506,12 @@ surf_fblits(pgSurfaceObject *self, PyObject *const *args, Py_ssize_t nargs)
2521
2506
case FBLITS_ERR_NO_MEMORY :
2522
2507
return RAISE (PyExc_MemoryError , "No memory available" );
2523
2508
case FBLITS_ERR_INVALID_SEQUENCE_LENGTH :
2524
- return RAISE (PyExc_ValueError ,
2525
- "Invalid sequence length for cached blit" );
2509
+ return RAISE (PyExc_ValueError , "Invalid sequence length for blit" );
2526
2510
case FBLITS_ERR_INVALID_DESTINATION :
2527
2511
return RAISE (PyExc_TypeError ,
2528
- "Invalid destination position for cached blit" );
2512
+ "Invalid destination position for blit" );
2513
+ case FBLITS_ERR_INVALID_SEQUENCE :
2514
+ return RAISE (PyExc_TypeError , "Invalid sequence for multi-blit" );
2529
2515
}
2530
2516
return RAISE (PyExc_TypeError , "Unknown error" );
2531
2517
}
0 commit comments