@@ -1623,7 +1623,7 @@ surf_copy(pgSurfaceObject *self, PyObject *_null)
1623
1623
SURF_INIT_CHECK (surf )
1624
1624
1625
1625
pgSurface_Prep (self );
1626
- newsurf = PG_ConvertSurface (surf , surf -> format );
1626
+ newsurf = PG_ConvertSurface (surf , surf );
1627
1627
pgSurface_Unprep (self );
1628
1628
1629
1629
final = surf_subtype_new (Py_TYPE (self ), newsurf , 1 );
@@ -1683,7 +1683,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
1683
1683
if (argobject ) {
1684
1684
if (pgSurface_Check (argobject )) {
1685
1685
src = pgSurface_AsSurface (argobject );
1686
- newsurf = PG_ConvertSurface (surf , src -> format );
1686
+ newsurf = PG_ConvertSurface (surf , src );
1687
1687
}
1688
1688
else {
1689
1689
/* will be updated later, initialize to make static analyzer happy
@@ -1837,7 +1837,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
1837
1837
if (argobject ) {
1838
1838
if (pgSurface_Check (argobject )) {
1839
1839
src = pgSurface_AsSurface (argobject );
1840
- newsurf = PG_ConvertSurface (surf , src -> format );
1840
+ newsurf = PG_ConvertSurface (surf , src );
1841
1841
}
1842
1842
else {
1843
1843
/* will be updated later, initialize to make static analyzer happy
@@ -1961,7 +1961,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
1961
1961
SDL_SetPixelFormatPalette (& format , palette );
1962
1962
}
1963
1963
}
1964
- newsurf = PG_ConvertSurface (surf , & format );
1964
+ newsurf = SDL_ConvertSurface (surf , & format , 0 );
1965
1965
SDL_SetSurfaceBlendMode (newsurf , SDL_BLENDMODE_NONE );
1966
1966
SDL_FreePalette (palette );
1967
1967
}
@@ -3767,7 +3767,7 @@ surf_premul_alpha(pgSurfaceObject *self, PyObject *_null)
3767
3767
3768
3768
pgSurface_Prep (self );
3769
3769
// Make a copy of the surface first
3770
- newsurf = PG_ConvertSurface (surf , surf -> format );
3770
+ newsurf = PG_ConvertSurface (surf , surf );
3771
3771
3772
3772
if ((surf -> w > 0 && surf -> h > 0 )) {
3773
3773
// If the surface has no pixels we don't need to premul
@@ -4461,6 +4461,76 @@ surface_do_overlap(SDL_Surface *src, SDL_Rect *srcrect, SDL_Surface *dst,
4461
4461
return dstoffset < span || dstoffset > src -> pitch - span ;
4462
4462
}
4463
4463
4464
+ int
4465
+ PG_BlitSurface (SDL_Surface * src , const SDL_Rect * srcrect , SDL_Surface * dst ,
4466
+ SDL_Rect * dstrect )
4467
+ {
4468
+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4469
+ /* SDL3 doesn't modify dstrect, so compat for that.
4470
+ * Below logic taken from SDL2 source with slight modifications */
4471
+ SDL_Rect r_src , r_dst ;
4472
+
4473
+ r_src .x = 0 ;
4474
+ r_src .y = 0 ;
4475
+ r_src .w = src -> w ;
4476
+ r_src .h = src -> h ;
4477
+
4478
+ if (dstrect ) {
4479
+ r_dst .x = dstrect -> x ;
4480
+ r_dst .y = dstrect -> y ;
4481
+ }
4482
+ else {
4483
+ r_dst .x = 0 ;
4484
+ r_dst .y = 0 ;
4485
+ }
4486
+
4487
+ /* clip the source rectangle to the source surface */
4488
+ if (srcrect ) {
4489
+ SDL_Rect tmp ;
4490
+ if (SDL_IntersectRect (srcrect , & r_src , & tmp ) == SDL_FALSE ) {
4491
+ goto end ;
4492
+ }
4493
+
4494
+ /* Shift dstrect, if srcrect origin has changed */
4495
+ r_dst .x += tmp .x - srcrect -> x ;
4496
+ r_dst .y += tmp .y - srcrect -> y ;
4497
+
4498
+ /* Update srcrect */
4499
+ r_src = tmp ;
4500
+ }
4501
+
4502
+ /* There're no dstrect.w/h parameters. It's the same as srcrect */
4503
+ r_dst .w = r_src .w ;
4504
+ r_dst .h = r_src .h ;
4505
+
4506
+ /* clip the destination rectangle against the clip rectangle */
4507
+ {
4508
+ SDL_Rect tmp , clip_rect ;
4509
+ SDL_GetSurfaceClipRect (dst , & clip_rect );
4510
+ if (SDL_IntersectRect (& r_dst , & clip_rect , & tmp ) == SDL_FALSE ) {
4511
+ goto end ;
4512
+ }
4513
+
4514
+ /* Update dstrect */
4515
+ r_dst = tmp ;
4516
+ }
4517
+
4518
+ if (r_dst .w > 0 && r_dst .h > 0 ) {
4519
+ if (dstrect ) { /* update output parameter */
4520
+ * dstrect = r_dst ;
4521
+ }
4522
+ return SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4523
+ }
4524
+ end :
4525
+ if (dstrect ) {
4526
+ dstrect -> w = dstrect -> h = 0 ;
4527
+ }
4528
+ return 0 ;
4529
+ #else
4530
+ return SDL_BlitSurface (src , srcrect , dst , dstrect );
4531
+ #endif
4532
+ }
4533
+
4464
4534
/*this internal blit function is accessible through the C api*/
4465
4535
int
4466
4536
pgSurface_Blit (pgSurfaceObject * dstobj , pgSurfaceObject * srcobj ,
@@ -4471,13 +4541,11 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4471
4541
SDL_Surface * subsurface = NULL ;
4472
4542
int result , suboffsetx = 0 , suboffsety = 0 ;
4473
4543
SDL_Rect orig_clip , sub_clip , dstclip ;
4474
- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
4475
4544
Uint8 alpha ;
4476
- #endif
4477
4545
4478
4546
if (!PG_GetSurfaceClipRect (dst , & dstclip )) {
4479
4547
PyErr_SetString (pgExc_SDLError , SDL_GetError ());
4480
- return 0 ;
4548
+ return 1 ;
4481
4549
}
4482
4550
4483
4551
/* passthrough blits to the real surface */
@@ -4528,8 +4596,6 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4528
4596
result = pygame_Blit (src , srcrect , dst , dstrect , blend_flags );
4529
4597
/* Py_END_ALLOW_THREADS */
4530
4598
}
4531
- // TODO SDL3: port the below bit of code. Skipping for initial surface port.
4532
- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
4533
4599
/* can't blit alpha to 8bit, crashes SDL */
4534
4600
else if (PG_SURF_BytesPerPixel (dst ) == 1 &&
4535
4601
(SDL_ISPIXELFORMAT_ALPHA (PG_SURF_FORMATENUM (src )) ||
@@ -4539,17 +4605,22 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4539
4605
result = pygame_Blit (src , srcrect , dst , dstrect , 0 );
4540
4606
}
4541
4607
else {
4608
+ #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4609
+ const SDL_PixelFormatDetails * fmt =
4610
+ SDL_GetPixelFormatDetails (src -> format );
4611
+ src = fmt ? SDL_ConvertSurface (src ,
4612
+ SDL_GetPixelFormatForMasks (
4613
+ fmt -> bits_per_pixel , fmt -> Rmask ,
4614
+ fmt -> Gmask , fmt -> Bmask , 0 ))
4615
+ : NULL ;
4616
+
4617
+ #else
4542
4618
SDL_PixelFormat * fmt = src -> format ;
4543
4619
SDL_PixelFormat newfmt ;
4544
4620
4545
4621
newfmt .palette = 0 ; /* Set NULL (or SDL gets confused) */
4546
- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4547
- newfmt .bits_per_pixel = fmt -> bits_per_pixel ;
4548
- newfmt .bytes_per_pixel = fmt -> bytes_per_pixel ;
4549
- #else
4550
4622
newfmt .BitsPerPixel = fmt -> BitsPerPixel ;
4551
4623
newfmt .BytesPerPixel = fmt -> BytesPerPixel ;
4552
- #endif
4553
4624
newfmt .Amask = 0 ;
4554
4625
newfmt .Rmask = fmt -> Rmask ;
4555
4626
newfmt .Gmask = fmt -> Gmask ;
@@ -4562,13 +4633,10 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4562
4633
newfmt .Rloss = fmt -> Rloss ;
4563
4634
newfmt .Gloss = fmt -> Gloss ;
4564
4635
newfmt .Bloss = fmt -> Bloss ;
4565
- src = PG_ConvertSurface (src , & newfmt );
4566
- if (src ) {
4567
- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4568
- result = SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4569
- #else
4570
- result = SDL_BlitSurface (src , srcrect , dst , dstrect );
4636
+ src = SDL_ConvertSurface (src , & newfmt , 0 );
4571
4637
#endif
4638
+ if (src ) {
4639
+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
4572
4640
SDL_FreeSurface (src );
4573
4641
}
4574
4642
else {
@@ -4577,7 +4645,6 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4577
4645
}
4578
4646
/* Py_END_ALLOW_THREADS */
4579
4647
}
4580
- #endif
4581
4648
else if (blend_flags != PYGAME_BLEND_ALPHA_SDL2 &&
4582
4649
!(pg_EnvShouldBlendAlphaSDL2 ()) && !SDL_HasColorKey (src ) &&
4583
4650
(PG_SURF_BytesPerPixel (dst ) == 4 ||
@@ -4598,11 +4665,7 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
4598
4665
}
4599
4666
else {
4600
4667
/* Py_BEGIN_ALLOW_THREADS */
4601
- #if SDL_VERSION_ATLEAST (3 , 0 , 0 )
4602
- result = SDL_BlitSurface (src , srcrect , dst , dstrect ) ? 0 : -1 ;
4603
- #else
4604
- result = SDL_BlitSurface (src , srcrect , dst , dstrect );
4605
- #endif
4668
+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
4606
4669
/* Py_END_ALLOW_THREADS */
4607
4670
}
4608
4671
0 commit comments