Exemplo n.º 1
0
 def get_clip(self):
     """ get_clip() -> Rect
     get the current clipping area of the Surface
     """
     self.check_surface()
     c_rect = self._c_surface.clip_rect
     return Rect._from4(c_rect.x, c_rect.y, c_rect.w, c_rect.h)
Exemplo n.º 2
0
 def get_clip(self):
     """ get_clip() -> Rect
     get the current clipping area of the Surface
     """
     self.check_surface()
     c_rect = self._c_surface.clip_rect
     return Rect._from4(c_rect.x, c_rect.y, c_rect.w, c_rect.h)
Exemplo n.º 3
0
 def get_rect(self, **kwargs):
     r = Rect._from4(0, 0, self._w, self._h)
     if kwargs:
         for attr, value in kwargs.items():
             # Logic copied form pygame/surface.c - blame them
             setattr(r, attr, value)
     return r
Exemplo n.º 4
0
    def fill(self, color, rect=None, special_flags=0):
        """ fill(color, rect=None, special_flags=0) -> Rect
        fill Surface with a solid color
        """
        self.check_opengl()

        c_color = create_color(color, self._format)
        sdlrect = ffi.new('SDL_Rect*')
        if rect is not None:
            sdlrect.x, sdlrect.y, sdlrect.w, sdlrect.h = rect_vals_from_obj(
                rect)
        else:
            sdlrect.w = self._w
            sdlrect.h = self._h

        if self.crop_to_surface(sdlrect):
            if special_flags:
                res = sdl.surface_fill_blend(self._c_surface, sdlrect, c_color,
                                             special_flags)
            else:
                with locked(self._c_surface):
                    # TODO: prep/unprep
                    res = sdl.SDL_FillRect(self._c_surface, sdlrect, c_color)

            if res == -1:
                raise SDLError.from_sdl_error()

        return Rect._from4(sdlrect.x, sdlrect.y, sdlrect.w, sdlrect.h)
Exemplo n.º 5
0
 def get_rect(self, **kwargs):
     r = Rect._from4(0, 0, self._w, self._h)
     if kwargs:
         for attr, value in kwargs.items():
             # Logic copied form pygame/surface.c - blame them
             setattr(r, attr, value)
     return r
Exemplo n.º 6
0
    def fill(self, color, rect=None, special_flags=0):
        """ fill(color, rect=None, special_flags=0) -> Rect
        fill Surface with a solid color
        """
        self.check_opengl()

        c_color = create_color(color, self._format)
        sdlrect = ffi.new('SDL_Rect*')
        if rect is not None:
            sdlrect.x, sdlrect.y, sdlrect.w, sdlrect.h = rect_vals_from_obj(rect)
        else:
            sdlrect.w = self._w
            sdlrect.h = self._h

        if self.crop_to_surface(sdlrect):
            if special_flags:
                res = sdl.surface_fill_blend(self._c_surface, sdlrect,
                                             c_color, special_flags)
            else:
                with locked(self._c_surface):
                    # TODO: prep/unprep
                    res = sdl.SDL_FillRect(self._c_surface, sdlrect, c_color)

            if res == -1:
                raise SDLError.from_sdl_error()

        return Rect._from4(sdlrect.x, sdlrect.y, sdlrect.w, sdlrect.h)
Exemplo n.º 7
0
 def get_clip(self):
     """ get_clip() -> Rect
     get the current clipping area of the Surface
     """
     if not self._c_surface:
         raise SDLError("display Surface quit")
     c_rect = self._c_surface.clip_rect
     return Rect._from4(c_rect.x, c_rect.y, c_rect.w, c_rect.h)
Exemplo n.º 8
0
    def get_bounding_rect(self, min_alpha=1):
        """ get_bounding_rect(min_alpha = 1) -> Rect
        find the smallest rect containing data
        """
        self.check_surface()

        min_alpha = int(min_alpha)
        if min_alpha > 255:
            min_alpha = 255
        elif min_alpha < 0:
            min_alpha = 0

        r, g, b, a = (ffi.new('uint8_t *'), ffi.new('uint8_t *'),
                      ffi.new('uint8_t *'), ffi.new('uint8_t *'))
        format = self._c_surface.format

        if self._c_surface.flags & sdl.SDL_SRCCOLORKEY:
            keyr = ffi.new('uint8_t *')
            keyg = ffi.new('uint8_t *')
            keyb = ffi.new('uint8_t *')
            sdl.SDL_GetRGBA(self._c_surface.format.colorkey, format, keyr,
                            keyg, keyb, a)
            keyr, keyg, keyb = keyr[0], keyg[0], keyb[0]
        else:
            keyr = keyg = keyb = None

        min_x, min_y, max_x, max_y = 0, 0, self._w, self._h

        def check_alpha(x, y):
            value = self._get_at(x, y)
            sdl.SDL_GetRGBA(value, format, r, g, b, a)
            if (keyr is None and a[0] >= min_alpha) or \
               (keyr is not None and (r[0] != keyr or
                                      g[0] != keyg or
                                      b[0] != keyb)):
                return True
            return False

        with locked(self._c_surface):
            found_alpha = False
            for y in range(max_y - 1, -1, -1):
                for x in range(min_x, max_x):
                    found_alpha = check_alpha(x, y)
                    if found_alpha:
                        break
                if found_alpha:
                    break
                max_y = y

            found_alpha = False
            for x in range(max_x - 1, -1, -1):
                for y in range(min_y, max_y):
                    found_alpha = check_alpha(x, y)
                    if found_alpha:
                        break
                if found_alpha:
                    break
                max_x = x

            found_alpha = False
            for y in range(min_y, max_y):
                min_y = y
                for x in range(min_x, max_x):
                    found_alpha = check_alpha(x, y)
                    if found_alpha:
                        break
                if found_alpha:
                    break

            found_alpha = False
            for x in range(min_x, max_x):
                min_x = x
                for y in range(min_y, max_y):
                    found_alpha = check_alpha(x, y)
                    if found_alpha:
                        break
                if found_alpha:
                    break

        return Rect._from4(min_x, min_y, max_x - min_x, max_y - min_y)
Exemplo n.º 9
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)
Exemplo n.º 10
0
    def get_bounding_rect(self, min_alpha=1):
        """ get_bounding_rect(min_alpha = 1) -> Rect
        find the smallest rect containing data
        """
        self.check_surface()

        min_alpha = int(min_alpha)
        if min_alpha > 255:
            min_alpha = 255
        elif min_alpha < 0:
            min_alpha = 0

        r, g, b, a = (ffi.new('uint8_t *'), ffi.new('uint8_t *'),
                      ffi.new('uint8_t *'), ffi.new('uint8_t *'))
        format = self._c_surface.format

        if self._c_surface.flags & sdl.SDL_SRCCOLORKEY:
            keyr = ffi.new('uint8_t *')
            keyg = ffi.new('uint8_t *')
            keyb = ffi.new('uint8_t *')
            sdl.SDL_GetRGBA(self._c_surface.format.colorkey,
                            format, keyr, keyg, keyb, a)
            keyr, keyg, keyb = keyr[0], keyg[0], keyb[0]
        else:
            keyr = keyg = keyb = None

        min_x, min_y, max_x, max_y = 0, 0, self._w, self._h

        def check_alpha(x, y):
            value = self._get_at(x, y)
            sdl.SDL_GetRGBA(value, format, r, g, b, a)
            if (keyr is None and a[0] >= min_alpha) or \
               (keyr is not None and (r[0] != keyr or
                                      g[0] != keyg or
                                      b[0] != keyb)):
               return True
            return False

        with locked(self._c_surface):
            found_alpha = False
            for y in range(max_y - 1, -1, -1):
                for x in range(min_x, max_x):
                    found_alpha = check_alpha(x, y)
                    if found_alpha:
                        break
                if found_alpha:
                    break
                max_y = y

            found_alpha = False
            for x in range(max_x - 1, -1, -1):
                for y in range(min_y, max_y):
                    found_alpha = check_alpha(x, y)
                    if found_alpha:
                        break
                if found_alpha:
                    break
                max_x = x

            found_alpha = False
            for y in range(min_y, max_y):
                min_y = y
                for x in range(min_x, max_x):
                    found_alpha = check_alpha(x, y)
                    if found_alpha:
                        break
                if found_alpha:
                    break

            found_alpha = False
            for x in range(min_x, max_x):
                min_x = x
                for y in range(min_y, max_y):
                    found_alpha = check_alpha(x, y)
                    if found_alpha:
                        break
                if found_alpha:
                    break

        return Rect._from4(min_x, min_y, max_x - min_x, max_y - min_y)
Exemplo n.º 11
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)