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)
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
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)
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)
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)
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)
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)