Exemplo n.º 1
0
 def set_clip(self, rect):
     """ set_clip(rect) -> None
     set the current clipping area of the Surface
     """
     self.check_surface()
     if rect:
         sdlrect = ffi.new('SDL_Rect*')
         sdlrect.x, sdlrect.y, sdlrect.w, sdlrect.h = \
                 rect_vals_from_obj(rect)
         res = sdl.SDL_SetClipRect(self._c_surface, sdlrect)
     else:
         res = sdl.SDL_SetClipRect(self._c_surface, ffi.NULL)
     if res == -1:
         raise SDLError.from_sdl_error()
Exemplo n.º 2
0
    def blit(self, source, dest, area=None, special_flags=0):
        """ blit(source, dest, area=None, special_flags = 0) -> Rect
        draw one image onto another
        """
        if not self._c_surface or not source._c_surface:
            raise SDLError("display Surface quit")
        if self.is_pure_opengl():
            raise SDLError("Cannot blit to OPENGL Surfaces (OPENGLBLIT is ok)")

        srcrect = ffi.new('SDL_Rect*')
        destrect = ffi.new('SDL_Rect*')
        if area is not None:
            srcrect.x, srcrect.y, srcrect.w, srcrect.h = \
                    rect_vals_from_obj(area)
        else:
            srcrect.w = source._w
            srcrect.h = source._h
        if isinstance(dest, tuple) and len(dest) == 2:
            destrect.x = int(dest[0])
            destrect.y = int(dest[1])
            destrect.w = source._w
            destrect.h = source._h
        else:
            destrect.x, destrect.y, destrect.w, destrect.h = \
                    rect_vals_from_obj(dest)

        c_dest = self._c_surface
        c_src = source._c_surface
        c_subsurface = None
        flags = special_flags

        if self.subsurfacedata:
            owner = self.subsurfacedata.owner
            c_subsurface = owner._c_surface
            suboffsetx = self.subsurfacedata.xoffset
            suboffsety = self.subsurfacedata.yoffset
            while owner.subsurfacedata:
                subdata = owner.subsurfacedata
                owner = subdata.owner
                c_subsurface = owner._c_surface
                suboffsetx += subdata.xoffset
                suboffsety += subdata.yoffset

            orig_clip = ffi.new('SDL_Rect*')
            sub_clip = ffi.new('SDL_Rect*')
            sdl.SDL_GetClipRect(c_subsurface, orig_clip)
            sdl.SDL_GetClipRect(self._c_surface, sub_clip)
            sub_clip[0].x += suboffsetx
            sub_clip[0].y += suboffsety
            sdl.SDL_SetClipRect(c_subsurface, sub_clip)
            destrect.x += suboffsetx
            destrect.y += suboffsety
            c_dest = c_subsurface

        # TODO: implement special blend flags
        # these checks come straight from pygame - copied comments
        if (c_dest.format.Amask and (c_dest.flags & sdl.SDL_SRCALPHA)
                and not (c_src.format.Amask
                         and not (c_src.flags & sdl.SDL_SRCALPHA))
                and (c_dest.format.BytesPerPixel == 2
                     or c_dest.format.BytesPerPixel == 4)):
            # SDL works for 2 and 4 bytes
            res = sdl.pygame_Blit(c_src, srcrect, c_dest, destrect, flags)
        elif flags or (c_src.flags & (sdl.SDL_SRCALPHA | sdl.SDL_SRCCOLORKEY)
                       and c_dest.pixels == c_src.pixels
                       and check_surface_overlap(c_src, srcrect, c_dest,
                                                 destrect)):
            '''
            This simplification is possible because a source subsurface
            is converted to its owner with a clip rect and a dst
            subsurface cannot be blitted to its owner because the
            owner is locked.
            '''
            res = sdl.pygame_Blit(c_src, srcrect, c_dest, destrect, flags)
        # can't blit alpha to 8bit, crashes SDL
        elif (c_dest.format.BytesPerPixel == 1
              and (c_src.format.Amask or c_src.flags & sdl.SDL_SRCALPHA)):
            if c_src.format.BytesPerPixel == 1:
                res = sdl.pygame_Blit(c_src, srcrect, c_dest, destrect, 0)
            elif sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO):
                # TODO: SDL_DisplayFormat segfaults
                c_src = sdl.SDL_DisplayFormat(c_src)
                if c_src:
                    res = sdl.SDL_BlitSurface(c_src, srcrect, c_dest, destrect)
                    sdl.SDL_FreeSurface(c_src)
                else:
                    res = -1
            else:
                raise NotImplementedError()
        else:
            res = sdl.SDL_BlitSurface(c_src, srcrect, c_dest, destrect)

        if c_subsurface:
            sdl.SDL_SetClipRect(c_subsurface, orig_clip)
            destrect.x -= suboffsetx
            destrect.y -= suboffsety
        else:
            # TODO: prep/unprep
            pass

        if res == -1:
            raise SDLError.from_sdl_error()
        elif res == -2:
            raise SDLError("Surface was lost")

        return Rect._from4(destrect.x, destrect.y, destrect.w, destrect.h)