I currently have some code that draws using pycairo and renders to an SDL surface by way of PyGame. This works nicely on Linux and Windows but the Mac is giving me headaches. Everything just comes out blue or pink The byte order seems to be BGRA instead of ARGB and I have tried using pygame.Surface.set_masks and set_shifts to no avail. This is only broken on the mac (osx 10.6):
import cairo
import pygame
width = 300
height = 200
pygame.init()
pygame.fastevent.init()
clock = pygame.time.Clock()
sdl_surface = pygame.display.set_mode((width, height))
c_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(c_surface)
while True:
pygame.fastevent.get()
clock.tick(30)
ctx.rectangle(10, 10, 50, 50)
ctx.set_source_rgba(0.0, 0.0, 0.0, 1.0)
ctx.fill_preserve()
dest = pygame.surfarray.pixels2d(sdl_surface)
dest.data[:] = c_surface.get_data()
pygame.display.flip()
I can fix it with array slicing or using PIL but this kills my frame rate. Is there a way to do this in-place or with settings?
After a lot of hair tearing I have a workaround that does not hurt my frame rate too much by simply reversing the array:
import cairo
import pygame
width = 300
height = 200
pygame.init()
pygame.fastevent.init()
clock = pygame.time.Clock()
sdl_surface = pygame.display.set_mode((width, height))
c_surface = cairo.ImageSurface(cairo.FORMAT_ARGB32, width, height)
ctx = cairo.Context(c_surface)
while True:
pygame.fastevent.get()
clock.tick(30)
ctx.rectangle(10, 10, 50, 50)
ctx.set_source_rgba(1.0, 0.0, 0.0, 1.0)
ctx.fill_preserve()
dest = pygame.surfarray.pixels2d(sdl_surface)
dest.data[:] = c_surface.get_data()[::-1]
tmp = pygame.transform.flip(sdl_surface, True, True)
sdl_surface.fill((0,0,0)) #workaround to clear the display
del dest #this is needed to unlock the display surface
sdl_surface.blit(tmp, (0,0))
pygame.display.flip()
The fact that I have to delete the array and blit from a temporary Surface does not seem right but it was the only way to flip the display. If anyone has a cleaner suggestion here, please comment.