diff --git a/src_c/SDL_gfx/SDL_gfxPrimitives.c b/src_c/SDL_gfx/SDL_gfxPrimitives.c index a1cceba80d..1391d73820 100644 --- a/src_c/SDL_gfx/SDL_gfxPrimitives.c +++ b/src_c/SDL_gfx/SDL_gfxPrimitives.c @@ -293,17 +293,13 @@ _putPixelAlpha(SDL_Surface *dst, Sint16 x, Sint16 y, Uint32 color, Uint8 alpha) *((Uint8 *)dst->pixels + y * dst->pitch + x) = color; } else { + /* Patched on pygame-ce end to fix segfault when no palette + */ Uint8 *pixel = (Uint8 *)dst->pixels + y * dst->pitch + x; - SDL_Palette *palette = format->palette; - SDL_Color *colors = palette->colors; - SDL_Color dColor = colors[*pixel]; - SDL_Color sColor = colors[color]; - Uint8 dR = dColor.r; - Uint8 dG = dColor.g; - Uint8 dB = dColor.b; - Uint8 sR = sColor.r; - Uint8 sG = sColor.g; - Uint8 sB = sColor.b; + Uint8 dR, dG, dB; + Uint8 sR, sG, sB; + SDL_GetRGB(*pixel, format, &dR, &dG, &dB); + SDL_GetRGB(color, format, &sR, &sG, &sB); dR = dR + ((sR - dR) * alpha >> 8); dG = dG + ((sG - dG) * alpha >> 8); @@ -604,22 +600,17 @@ _filledRectAlpha(SDL_Surface *dst, Sint16 x1, Sint16 y1, Sint16 x2, Sint16 y2, format = dst->format; switch (GFX_FORMAT_BytesPerPixel(format)) { case 1: { /* Assuming 8-bpp */ + /* Patched on pygame-ce end to fix segfault when no palette */ Uint8 *row, *pixel; Uint8 dR, dG, dB; - SDL_Palette *palette = format->palette; - SDL_Color *colors = palette->colors; - sR = colors[color].r; - sG = colors[color].g; - sB = colors[color].b; + SDL_GetRGB(color, format, &sR, &sG, &sB); for (y = y1; y <= y2; y++) { row = (Uint8 *)dst->pixels + y * dst->pitch; for (x = x1; x <= x2; x++) { pixel = row + x; - dR = colors[*pixel].r; - dG = colors[*pixel].g; - dB = colors[*pixel].b; + SDL_GetRGB(*pixel, format, &dR, &dG, &dB); dR = dR + ((sR - dR) * alpha >> 8); dG = dG + ((sG - dG) * alpha >> 8); diff --git a/test/gfxdraw_test.py b/test/gfxdraw_test.py index 76f9aa80b8..580ab283b2 100644 --- a/test/gfxdraw_test.py +++ b/test/gfxdraw_test.py @@ -872,6 +872,46 @@ def test_bezier(self): for posn in bg_test_points: self.check_at(surf, posn, bg_adjusted) + def test_no_pal_8bit_surf(self): + """ + Test that gfxdraw methods do not segfault when passed with no palette + 8 bit surface. + """ + s = pygame.Surface( + size=(512, 512), flags=0, depth=8, masks=(0xE0, 0x1C, 0x03, 0x00) + ) + + fg = (255, 255, 255) + points = [(10, 10), (100, 50), (50, 100)] + for name, args in ( + ("pixel", (s, 2, 2, fg)), + ("hline", (s, 5, 50, 10, fg)), + ("vline", (s, 10, 5, 50, fg)), + ("line", (s, 0, 0, 100, 100, fg)), + ("rectangle", (s, pygame.Rect(50, 50, 80, 40), fg)), + ("box", (s, pygame.Rect(60, 60, 80, 40), fg)), + ("circle", (s, 256, 256, 64, fg)), + ("aacircle", (s, 256, 256, 64, fg)), + ("filled_circle", (s, 256, 256, 32, fg)), + ("ellipse", (s, 200, 200, 50, 30, fg)), + ("aaellipse", (s, 200, 200, 50, 30, fg)), + ("filled_ellipse", (s, 200, 200, 50, 30, fg)), + ("arc", (s, 256, 256, 60, 0, 180, fg)), + ("pie", (s, 300, 300, 60, 0, 270, fg)), + ("trigon", (s, 100, 100, 150, 200, 50, 200, fg)), + ("aatrigon", (s, 100, 100, 150, 200, 50, 200, fg)), + ("filled_trigon", (s, 100, 100, 150, 200, 50, 200, fg)), + ("polygon", (s, points, fg)), + ("aapolygon", (s, points, fg)), + ("filled_polygon", (s, points, fg)), + ("textured_polygon", (s, points, s, 0, 0)), # use same surface as texture + ): + try: + func = getattr(pygame.gfxdraw, name) + func(*args) + except Exception as e: + self.fail(f"gfxdraw.{name} raised an exception: {e}") + if __name__ == "__main__": unittest.main()