@@ -1623,7 +1623,7 @@ surf_copy(pgSurfaceObject *self, PyObject *_null)
16231623 SURF_INIT_CHECK (surf )
16241624
16251625 pgSurface_Prep (self );
1626- newsurf = PG_ConvertSurface (surf , surf -> format );
1626+ newsurf = PG_ConvertSurface (surf , surf );
16271627 pgSurface_Unprep (self );
16281628
16291629 final = surf_subtype_new (Py_TYPE (self ), newsurf , 1 );
@@ -1683,7 +1683,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
16831683 if (argobject ) {
16841684 if (pgSurface_Check (argobject )) {
16851685 src = pgSurface_AsSurface (argobject );
1686- newsurf = PG_ConvertSurface (surf , src -> format );
1686+ newsurf = PG_ConvertSurface (surf , src );
16871687 }
16881688 else {
16891689 /* will be updated later, initialize to make static analyzer happy
@@ -1837,7 +1837,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
18371837 if (argobject ) {
18381838 if (pgSurface_Check (argobject )) {
18391839 src = pgSurface_AsSurface (argobject );
1840- newsurf = PG_ConvertSurface (surf , src -> format );
1840+ newsurf = PG_ConvertSurface (surf , src );
18411841 }
18421842 else {
18431843 /* will be updated later, initialize to make static analyzer happy
@@ -1961,7 +1961,7 @@ surf_convert(pgSurfaceObject *self, PyObject *args)
19611961 SDL_SetPixelFormatPalette (& format , palette );
19621962 }
19631963 }
1964- newsurf = PG_ConvertSurface (surf , & format );
1964+ newsurf = SDL_ConvertSurface (surf , & format , 0 );
19651965 SDL_SetSurfaceBlendMode (newsurf , SDL_BLENDMODE_NONE );
19661966 SDL_FreePalette (palette );
19671967 }
@@ -3767,7 +3767,7 @@ surf_premul_alpha(pgSurfaceObject *self, PyObject *_null)
37673767
37683768 pgSurface_Prep (self );
37693769 // Make a copy of the surface first
3770- newsurf = PG_ConvertSurface (surf , surf -> format );
3770+ newsurf = PG_ConvertSurface (surf , surf );
37713771
37723772 if ((surf -> w > 0 && surf -> h > 0 )) {
37733773 // 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,
44614461 return dstoffset < span || dstoffset > src -> pitch - span ;
44624462}
44634463
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+
44644534/*this internal blit function is accessible through the C api*/
44654535int
44664536pgSurface_Blit (pgSurfaceObject * dstobj , pgSurfaceObject * srcobj ,
@@ -4471,13 +4541,11 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
44714541 SDL_Surface * subsurface = NULL ;
44724542 int result , suboffsetx = 0 , suboffsety = 0 ;
44734543 SDL_Rect orig_clip , sub_clip , dstclip ;
4474- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
44754544 Uint8 alpha ;
4476- #endif
44774545
44784546 if (!PG_GetSurfaceClipRect (dst , & dstclip )) {
44794547 PyErr_SetString (pgExc_SDLError , SDL_GetError ());
4480- return 0 ;
4548+ return 1 ;
44814549 }
44824550
44834551 /* passthrough blits to the real surface */
@@ -4528,8 +4596,6 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45284596 result = pygame_Blit (src , srcrect , dst , dstrect , blend_flags );
45294597 /* Py_END_ALLOW_THREADS */
45304598 }
4531- // TODO SDL3: port the below bit of code. Skipping for initial surface port.
4532- #if !SDL_VERSION_ATLEAST (3 , 0 , 0 )
45334599 /* can't blit alpha to 8bit, crashes SDL */
45344600 else if (PG_SURF_BytesPerPixel (dst ) == 1 &&
45354601 (SDL_ISPIXELFORMAT_ALPHA (PG_SURF_FORMATENUM (src )) ||
@@ -4539,17 +4605,22 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45394605 result = pygame_Blit (src , srcrect , dst , dstrect , 0 );
45404606 }
45414607 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
45424618 SDL_PixelFormat * fmt = src -> format ;
45434619 SDL_PixelFormat newfmt ;
45444620
45454621 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
45504622 newfmt .BitsPerPixel = fmt -> BitsPerPixel ;
45514623 newfmt .BytesPerPixel = fmt -> BytesPerPixel ;
4552- #endif
45534624 newfmt .Amask = 0 ;
45544625 newfmt .Rmask = fmt -> Rmask ;
45554626 newfmt .Gmask = fmt -> Gmask ;
@@ -4562,13 +4633,10 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45624633 newfmt .Rloss = fmt -> Rloss ;
45634634 newfmt .Gloss = fmt -> Gloss ;
45644635 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 );
45714637#endif
4638+ if (src ) {
4639+ result = PG_BlitSurface (src , srcrect , dst , dstrect );
45724640 SDL_FreeSurface (src );
45734641 }
45744642 else {
@@ -4577,7 +4645,6 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45774645 }
45784646 /* Py_END_ALLOW_THREADS */
45794647 }
4580- #endif
45814648 else if (blend_flags != PYGAME_BLEND_ALPHA_SDL2 &&
45824649 !(pg_EnvShouldBlendAlphaSDL2 ()) && !SDL_HasColorKey (src ) &&
45834650 (PG_SURF_BytesPerPixel (dst ) == 4 ||
@@ -4598,11 +4665,7 @@ pgSurface_Blit(pgSurfaceObject *dstobj, pgSurfaceObject *srcobj,
45984665 }
45994666 else {
46004667 /* 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 );
46064669 /* Py_END_ALLOW_THREADS */
46074670 }
46084671
0 commit comments