def scale(surface, size, dest_surface=None): """ scale(Surface, (width, height), DestSurface = None) -> Surface resize to new resolution """ width, height = size if width < 0 or height < 0: raise ValueError("Cannot scale to negative size") c_surf = surface._c_surface if dest_surface is None: new_surf = new_surface_from_surface(c_surf, width, height) else: new_surf = dest_surface._c_surface if new_surf.w != width or new_surf.h != height: raise ValueError("Destination surface not the given width or height.") if c_surf.format.BytesPerPixel != new_surf.format.BytesPerPixel: raise ValueError( "Source and destination surfaces need the same format.") if width and height: with locked(new_surf): with locked(c_surf): sdl.stretch(c_surf, new_surf) return Surface._from_sdl_surface(new_surf)
def from_threshold(surf, color, threshold=(0, 0, 0, 255), othersurface=None, palette_colors=1): """from_threshold(surf, color, threshold = (0,0,0,255), othersurface = None, palette_colors = 1) -> Mask Creates a mask by thresholding Surfaces""" c_surf = surf._c_surface color = create_color(color, surf._c_surface.format) if threshold: threshold = create_color(threshold, c_surf.format) output_mask = Mask((surf._w, surf._h)) with locked(c_surf): if othersurface: surf2 = othersurface._c_surface with locked(surf2): sdl.bitmask_threshold(output_mask._mask, c_surf, surf2, color, threshold, palette_colors) else: sdl.bitmask_threshold(output_mask._mask, c_surf, ffi.NULL, color, threshold, palette_colors) return output_mask
def test_conformance(test_func, verbose=False): """Run the test case and compare the resulting surface to the existing test case.""" test_name = test_func._filename passed = True for depth in DEPTHS: if depth not in test_func._supported_depths: continue test_surf = create_surface(depth) try: test_func(test_surf) except NotImplementedError: # Don't fail completely on not implemented functions pass except Exception as e: # Fail on other exceptions print('%s at depth %d Failed with exception %s' % (test_name, depth, e)) passed = False continue orig_name = 'results/gen_%d_%s.png' % (depth, test_name) try: orig_surf = image.load(orig_name) except Exception as e: # complain, fail and skip print("Unable to load %s (%s)" % (orig_name, e)) passed = False continue imgname = 'results/test_%d_%s.png' % (depth, test_name) image.save(test_surf, imgname) diffname = 'results/diff_%d_%s.png' % (depth, test_name) # sanity check assert orig_surf.get_size() == test_surf.get_size() differences = False diff_surf = create_surface(depth) # Pixel by pixel comparison. # This is slow, but avoids extra dependancies from pygame.surflock import locked orig_surf = orig_surf.convert(test_surf) with locked(orig_surf._c_surface): with locked(test_surf._c_surface): for x in range(800): for y in range(600): point = (x, y) if orig_surf._get_at(x, y) != test_surf._get_at(x, y): differences = True # Flag as pure white for easier visual inspection diff_surf.set_at(point, (255, 255, 255, 255)) if differences: print("conformance test %s FAILED for depth %d.\n" " Difference saved to %s" % (test_name, depth, diffname)) image.save(diff_surf, diffname) passed = False else: if verbose: print("conformance test %s passed for depth %d" % (test_name, depth)) return passed
def flip(surface, xaxis, yaxis): c_surf = surface._c_surface w, h = c_surf.w, c_surf.h new_surf = new_surface_from_surface(c_surf, w, h) bpp = c_surf.format.BytesPerPixel pitch = c_surf.pitch with locked(new_surf): with locked(surface._c_surface): # only have to deal with rows if not xaxis: srcpixels = ffi.cast('uint8_t*', c_surf.pixels) destpixels = ffi.cast('uint8_t*', new_surf.pixels) if not yaxis: # no changes - just copy pixels destpixels[0:h * pitch] = srcpixels[0:h * pitch] else: for y in range(h): dest_start = (h - y - 1) * pitch src_start = y * pitch destpixels[dest_start:dest_start + pitch] = \ srcpixels[src_start:src_start + pitch] # have to calculate position for individual pixels else: if not yaxis: def get_y(y): return y else: def get_y(y): return h - y - 1 if bpp in (1, 2, 4): ptr_type = 'uint%s_t*' % c_surf.format.BitsPerPixel srcpixels = ffi.cast(ptr_type, c_surf.pixels) destpixels = ffi.cast(ptr_type, new_surf.pixels) for y in range(h): dest_row_start = get_y(y) * w src_row_start = y * w for x in range(w): destpixels[dest_row_start + (w - x - 1)] = \ srcpixels[src_row_start + x] else: srcpixels = ffi.cast('uint8_t*', c_surf.pixels) destpixels = ffi.cast('uint8_t*', new_surf.pixels) for y in range(h): dest_row_start = get_y(y) * pitch src_row_start = y * pitch for x in range(0, pitch, 3): dest_pix_start = dest_row_start + (pitch - x - 3) src_pix_start = src_row_start + x destpixels[dest_pix_start:dest_pix_start + 3] = \ srcpixels[src_pix_start:src_pix_start + 3] return Surface._from_sdl_surface(new_surf)
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 copy(self): self.check_opengl() with locked(self._c_surface): # TODO: prep/unprep newsurf = sdl.SDL_ConvertSurface(self._c_surface, self._format, self._c_surface.flags) return Surface._from_sdl_surface(newsurf)
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 smoothscale(surface, size, dest_surface=None): """ smoothscale(Surface, (width, height), DestSurface = None) -> Surface scale a surface to an arbitrary size smoothly """ width, height = size if width < 0 or height < 0: raise ValueError("Cannot scale to negative size") c_surf = surface._c_surface bpp = c_surf.format.BytesPerPixel if bpp < 3 or bpp > 4: raise ValueError("Only 24-bit or 32-bit surfaces can be" " smoothly scaled") if dest_surface is None: new_surf = new_surface_from_surface(c_surf, width, height) else: new_surf = dest_surface._c_surface if new_surf.w != width or new_surf.h != height: raise ValueError("Destination surface not the given width or height.") if (width * bpp + 3) // 4 > new_surf.pitch: raise ValueError("SDL Error: destination surface pitch not" " 4-byte aligned.") if width and height: with locked(new_surf): with locked(c_surf): if c_surf.w == width and c_surf.h == height: # Non-scaling case, so just copy the correct pixels c_pitch = c_surf.pitch n_pitch = new_surf.pitch srcpixels = ffi.cast('uint8_t*', c_surf.pixels) destpixels = ffi.cast('uint8_t*', new_surf.pixels) step = width * bpp for y in range(0, height): offset_n = y * n_pitch offset_c = y * c_pitch destpixels[offset_n:offset_n + step] = srcpixels[offset_c:offset_c + step] else: sdl.scalesmooth(c_surf, new_surf) if dest_surface: return dest_surface return Surface._from_sdl_surface(new_surf)
def get_at(self, pos): self.check_opengl() x, y = pos if x < 0 or y < 0 or x >= self._w or y >= self._h: raise IndexError("index out of bounds") with locked(self._c_surface): c_color = self._get_at(x, y) return self.unmap_rgb(c_color)
def set_at(self, pos, color): self.check_opengl() x, y = pos if x < 0 or y < 0 or x >= self._w or y >= self._h: raise IndexError("index out of bounds") c_color = create_color(color, self._format) with locked(self._c_surface): self._set_at(x, y, c_color)
def rotate(surface, angle): c_surf = surface._c_surface # special treatment if rotating by 90 degrees if abs(angle) == 90.0: numturns = (angle / 90) % 4 if numturns < 0: numturns = 4 + numturns if numturns % 2 == 0: width = c_surf.w height = c_surf.h else: width = c_surf.h height = c_surf.w new_surf = new_surface_from_surface(c_surf, width, height) with locked(new_surf): with locked(c_surf): sdl.rotate90(c_surf, new_surf, int(angle)) else: radangle = angle * 0.01745329251994329 sangle = math.sin(radangle) cangle = math.cos(radangle) x, y = c_surf.w, c_surf.h cx, cy = cangle * x, cangle * y sx, sy = sangle * x, sangle * y nxmax = int( max(max(max(abs(cx + sy), abs(cx - sy)), abs(-cx + sy)), abs(-cx - sy))) nymax = int( max(max(max(abs(sx + cy), abs(sx - cy)), abs(-sx + cy)), abs(-sx - cy))) new_surf = new_surface_from_surface(c_surf, nxmax, nymax) if c_surf.flags & sdl.SDL_SRCCOLORKEY: bgcolor = c_surf.format.colorkey else: bgcolor = surface.get_at_mapped((0, 0)) bgcolor &= ~(c_surf.format.Amask) with locked(new_surf): with locked(c_surf): sdl.rotate(c_surf, new_surf, bgcolor, sangle, cangle) return Surface._from_sdl_surface(new_surf)
def set_colorkey(self, color=None, flags=0): self.check_opengl() c_color = 0 if color is not None: c_color = create_color(color, self._format) flags |= sdl.SDL_SRCCOLORKEY with locked(self._c_surface): if sdl.SDL_SetColorKey(self._c_surface, flags, c_color) == -1: raise SDLError.from_sdl_error()
def scale2x(surface, dest_surface=None): """ scale2x(Surface, DestSurface = None) -> Surface specialized image doubler """ c_surf = surface._c_surface if dest_surface: new_surf = dest_surface._c_surface if (new_surf.w != 2 * c_surf.w) or (new_surf.h != 2 * c_surf.h): raise ValueError("Destination surface not 2x bigger") else: new_surf = new_surface_from_surface(c_surf, c_surf.w * 2, c_surf.h * 2) with locked(new_surf): with locked(c_surf): sdl.scale2x(c_surf, new_surf) if dest_surface: return dest_surface return Surface._from_sdl_surface(new_surf)
def rotate(surface, angle): c_surf = surface._c_surface # special treatment if rotating by 90 degrees if abs(angle) == 90.0 or abs(angle) == 180.0 or abs(angle) == 0.0: numturns = (angle / 90) % 4 if numturns < 0: numturns = 4 + numturns if numturns % 2 == 0: width = c_surf.w height = c_surf.h else: width = c_surf.h height = c_surf.w new_surf = new_surface_from_surface(c_surf, width, height) with locked(new_surf): with locked(c_surf): sdl.rotate90(c_surf, new_surf, int(angle)) else: radangle = angle * 0.01745329251994329 sangle = math.sin(radangle) cangle = math.cos(radangle) x, y = c_surf.w, c_surf.h cx, cy = cangle * x, cangle * y sx, sy = sangle * x, sangle * y nxmax = int(max(max(max(abs(cx + sy), abs(cx - sy)), abs(-cx + sy)), abs(-cx - sy))) nymax = int(max(max(max(abs(sx + cy), abs(sx - cy)), abs(-sx + cy)), abs(-sx - cy))) new_surf = new_surface_from_surface(c_surf, nxmax, nymax) if c_surf.flags & sdl.SDL_SRCCOLORKEY: bgcolor = c_surf.format.colorkey else: bgcolor = surface.get_at_mapped((0, 0)) bgcolor &= ~(c_surf.format.Amask) with locked(new_surf): with locked(c_surf): sdl.rotate(c_surf, new_surf, bgcolor, sangle, cangle) return Surface._from_sdl_surface(new_surf)
def scroll(self, dx=0, dy=0): """ scroll(dx=0, dy=0) -> None Shift the surface image in place """ self.check_surface() if self.is_pure_opengl(): raise SDLError( "Cannot scroll an OPENGL Surfaces (OPENGLBLIT is ok)") if not (dx or dy): return None clip_rect = self._c_surface.clip_rect w = clip_rect.w h = clip_rect.h if dx >= w or dx <= -w or dy >= h or dy <= -h: return None with locked(self._c_surface): bpp = self._c_surface.format.BytesPerPixel pitch = self._c_surface.pitch pixels = ffi.cast("uint8_t*", self._c_surface.pixels) src = dst = pixels + clip_rect.y * pitch + clip_rect.x * bpp if dx >= 0: w -= dx if dy > 0: h -= dy dst += dy * pitch + dx * bpp else: h += dy src -= dy * pitch dst += dx * bpp else: w += dx if dy > 0: h -= dy src -= dx * bpp dst += dy * pitch else: h += dy src -= dy * pitch + dx * bpp if src < dst: src += (h - 1) * pitch dst += (h - 1) * pitch pitch = -pitch span = w * bpp for _ in range(h): sdl.memmove(dst, src, span) src += pitch dst += pitch return None
def get_at_mapped(self, pos): """ get_at_mapped((x, y)) -> Color get the mapped color value at a single pixel """ self.check_opengl() x, y = pos if x < 0 or y < 0 or x >= self._w or y >= self._h: raise IndexError("index out of bounds") with locked(self._c_surface): c_color = self._get_at(x, y) return c_color
def scroll(self, dx=0, dy=0): """ scroll(dx=0, dy=0) -> None Shift the surface image in place """ self.check_surface() if self.is_pure_opengl(): raise SDLError("Cannot scroll an OPENGL Surfaces (OPENGLBLIT is ok)") if not (dx or dy): return None clip_rect = self._c_surface.clip_rect w = clip_rect.w h = clip_rect.h if dx >= w or dx <= -w or dy >= h or dy <= -h: return None with locked(self._c_surface): bpp = self._c_surface.format.BytesPerPixel pitch = self._c_surface.pitch pixels = ffi.cast("uint8_t*", self._c_surface.pixels) src = dst = pixels + clip_rect.y * pitch + clip_rect.x * bpp if dx >= 0: w -= dx if dy > 0: h -= dy dst += dy * pitch + dx * bpp else: h += dy src -= dy * pitch dst += dx * bpp else: w += dx if dy > 0: h -= dy src -= dx * bpp dst += dy * pitch else: h += dy src -= dy * pitch + dx * bpp if src < dst: src += (h - 1) * pitch dst += (h - 1) * pitch pitch = -pitch span = w * bpp for _ in range(h): sdl.memmove(dst, src, span) src += pitch dst += pitch return None
def smoothscale(surface, size, dest_surface=None): """ smoothscale(Surface, (width, height), DestSurface = None) -> Surface scale a surface to an arbitrary size smoothly """ width, height = size if width < 0 or height < 0: raise ValueError("Cannot scale to negative size") c_surf = surface._c_surface bpp = c_surf.format.BytesPerPixel if bpp < 3 or bpp > 4: raise ValueError("Only 24-bit or 32-bit surfaces can be" " smoothly scaled") if dest_surface is None: new_surf = new_surface_from_surface(c_surf, width, height) else: new_surf = dest_surface._c_surface if new_surf.w != width or new_surf.h != height: raise ValueError("Destination surface not the given width or height.") if (width * bpp + 3) // 4 > new_surf.pitch: raise ValueError("SDL Error: destination surface pitch not" " 4-byte aligned.") if width and height: with locked(new_surf): with locked(c_surf): if c_surf.w == width and c_surf.h == height: pitch = c_surf.pitch # Trivial case srcpixels = ffi.cast('uint8_t*', c_surf.pixels) destpixels = ffi.cast('uint8_t*', new_surf.pixels) destpixels[0:height * pitch] = srcpixels[0:height * pitch] else: sdl.scalesmooth(c_surf, new_surf) if dest_surface: return dest_surface return Surface._from_sdl_surface(new_surf)
def test_conformance(test_name, test_func): """Run the test case and compare the resulting surface to the existing test case.""" test_surf = create_surface() try: test_func(test_surf) except NotImplementedError: # Don't fail completely on not implemented functions pass imgname = 'results/test_%s.png' % test_name image.save(test_surf, imgname) diffname = 'results/diff_%s.png' % test_name orig_name = 'results/gen_%s.png' % test_name orig_surf = image.load(orig_name) # sanity check assert orig_surf.get_size() == test_surf.get_size() differences = False diff_surf = create_surface() # Pixel by pixel comparison. # This is slow, but avoids extra dependancies from pygame.surflock import locked orig_surf = orig_surf.convert(test_surf) with locked(orig_surf._c_surface): with locked(test_surf._c_surface): for x in range(800): for y in range(600): point = (x, y) if orig_surf._get_at(x, y) != test_surf._get_at(x, y): differences = True # Flag as pure white for easier visual inspection diff_surf.set_at(point, (255, 255, 255, 255)) if differences: print("conformance test %s FAILED.\n" " Difference saved to %s" % (test_name, diffname)) image.save(diff_surf, diffname) else: print("conformance test %s passed" % test_name)
def set_alpha(self, value=None, flags=0): """ set_alpha(value, flags=0) -> None set the alpha value for the full Surface image """ if value is not None: value = int(value) if value > 255: value = 255 if value < 0: value = 0 flags |= sdl.SDL_SRCALPHA else: value = 255 with locked(self._c_surface): if sdl.SDL_SetAlpha(self._c_surface, flags, value) == -1: raise SDLError.from_sdl_error()
def convert(self, arg=None, flags=0): with locked(self._c_surface): if isinstance(arg, Surface): flags = arg._c_surface.flags | (self._c_surface.flags & (sdl.SDL_SRCCOLORKEY | sdl.SDL_SRCALPHA)) newsurf = sdl.SDL_ConvertSurface(self._c_surface, arg._format, flags) elif arg is None: if sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO): newsurf = sdl.SDL_DisplayFormat(self._c_surface) else: newsurf = sdl.SDL_ConvertSurface(self._c_surface, self._format, self._c_surface.flags) else: xxx return Surface._from_sdl_surface(newsurf)
def convert(self, arg=None, flags=0): with locked(self._c_surface): if isinstance(arg, Surface): flags = arg._c_surface.flags | ( self._c_surface.flags & (sdl.SDL_SRCCOLORKEY | sdl.SDL_SRCALPHA)) newsurf = sdl.SDL_ConvertSurface(self._c_surface, arg._format, flags) elif arg is None: if sdl.SDL_WasInit(sdl.SDL_INIT_VIDEO): newsurf = sdl.SDL_DisplayFormat(self._c_surface) else: newsurf = sdl.SDL_ConvertSurface(self._c_surface, self._format, self._c_surface.flags) else: xxx return Surface._from_sdl_surface(newsurf)
def subsurface(self, *rect): self.check_opengl() try: if hasattr(rect[0], '__iter__'): rect = game_rect_from_obj(rect[0]) else: rect = game_rect_from_obj(rect) except TypeError: raise ValueError("not a valid rect style object") if (rect.x < 0 or rect.x + rect.w > self._c_surface.w or rect.y < 0 or rect.y + rect.h > self._c_surface.h): raise ValueError("subsurface rectangle outside surface area") with locked(self._c_surface): format = self._format pixeloffset = (rect.x * format.BytesPerPixel + rect.y * self._c_surface.pitch) startpixel = ffi.cast("char*", self._c_surface.pixels) + pixeloffset surf = self._c_surface sub = sdl.SDL_CreateRGBSurfaceFrom(startpixel, rect.w, rect.h, format.BitsPerPixel, surf.pitch, format.Rmask, format.Gmask, format.Bmask, format.Amask) if not sub: raise SDLError.from_sdl_error() if format.BytesPerPixel == 1 and format.palette: sdl.SDL_SetPalette(sub, sdl.SDL_LOGPAL, format.palette.colors, 0, format.palette.ncolors); if surf.flags & sdl.SDL_SRCALPHA: sdl.SDL_SetAlpha(sub, surf.flags & sdl.SDL_SRCALPHA, format.alpha); if surf.flags & sdl.SDL_SRCCOLORKEY: sdl.SDL_SetColorKey(sub, surf.flags & (sdl.SDL_SRCCOLORKEY | sdl.SDL_RLEACCEL), format.colorkey) subsurface = Surface._from_sdl_surface(sub) data = SubSurfaceData(self, pixeloffset, rect.x, rect.y) subsurface.subsurfacedata = data return subsurface
def from_surface(surf, threshold=127): """from_surface(surf, threshold = 127) -> Mask Returns a Mask from the given surface""" c_surf = surf._c_surface output_mask = Mask((surf._w, surf._h)) # colorkey will be None if we're not using a colorkey colorkey = surf.get_colorkey() format = surf._c_surface.format r, g, b, a = (ffi.new('uint8_t *'), ffi.new('uint8_t *'), ffi.new('uint8_t *'), ffi.new('uint8_t *')) with locked(c_surf): for y in range(surf._h): for x in range(surf._w): sdl.SDL_GetRGBA(surf._get_at(x, y), format, r, g, b, a) if colorkey is None: # check alpha if a[0] > threshold: sdl.bitmask_setbit(output_mask._mask, x, y) else: pixel = (r[0], g[0], b[0], a[0]) if pixel == colorkey: sdl.bitmask_setbit(output_mask._mask, x, y) return output_mask
c_surf = surface._c_surface if dest_surface is None: new_surf = new_surface_from_surface(c_surf, width, height) else: new_surf = dest_surface._c_surface if new_surf.w != width or new_surf.h != height: raise ValueError("Destination surface not the given width or height.") if c_surf.format.BytesPerPixel != new_surf.format.BytesPerPixel: raise ValueError( "Source and destination surfaces need the same format.") if width and height: with locked(new_surf): with locked(c_surf): sdl.stretch(c_surf, new_surf) return Surface._from_sdl_surface(new_surf) def rotozoom(surface, angle, scale): """ rotozoom(Surface, angle, scale) -> Surface filtered scale and rotation """ raise NotImplementedError def scale2x(surface, dest_surface=None): """ scale2x(Surface, DestSurface = None) -> Surface
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 chop(surface, rect): """ chop(Surface, rect) -> Surface gets a copy of an image with an interior area removed """ rect = Rect(rect) width = rect.width height = rect.width x = rect.x y = rect.y if rect.right > surface._w: width = surface._w - rect.x if rect.height > surface._h: height = surface._h - rect.y if rect.x < 0: width -= -x x = 0 if rect.y < 0: height -= -y y = 0 c_surf = surface._c_surface new_surf = new_surface_from_surface(c_surf, surface._w, surface._h) bpp = c_surf.format.BytesPerPixel pitch = c_surf.pitch w, h = c_surf.w, c_surf.h with locked(new_surf): with locked(c_surf): if bpp in (1, 2, 4): ptr_type = 'uint%s_t*' % c_surf.format.BitsPerPixel srcpixels = ffi.cast(ptr_type, c_surf.pixels) destpixels = ffi.cast(ptr_type, new_surf.pixels) else: srcpixels = ffi.cast('uint8_t*', c_surf.pixels) destpixels = ffi.cast('uint8_t*', new_surf.pixels) dy = 0 for sy in range(0, surface._h): if sy >= y and sy < y + height: continue dx = 0 if bpp in (1, 2, 4): dest_row_start = dy * w src_row_start = sy * w else: dest_row_start = dy * pitch src_row_start = sy * pitch for sx in range(0, surface._w): if sx >= x and sx < x + width: continue if bpp in (1, 2, 4): destpixels[dest_row_start + dx] = \ srcpixels[src_row_start + sx] else: dest_pix_start = dest_row_start + dx src_pix_start = src_row_start + sx destpixels[dest_pix_start:dest_pix_start + 3] = \ srcpixels[src_pix_start:src_pix_start + 3] dx += 1 dy += 1 return Surface._from_sdl_surface(new_surf)
def convert_alpha(self, srcsurf=None): with locked(self._c_surface): newsurf = sdl.SDL_DisplayFormatAlpha(self._c_surface) return Surface._from_sdl_surface(newsurf)
def chop(surface, rect): """ chop(Surface, rect) -> Surface gets a copy of an image with an interior area removed """ rect = Rect(rect) width = rect.width height = rect.width x = rect.x y = rect.y if rect.right > surface._w: width = surface._w - rect.x if rect.height > surface._h: height = surface._h - rect.y if rect.x < 0: width -= -x x = 0 if rect.y < 0: height -= -y y = 0 c_surf = surface._c_surface new_surf = new_surface_from_surface(c_surf, surface._w, surface._h) bpp = c_surf.format.BytesPerPixel src_pitch = c_surf.pitch dest_pitch = new_surf.pitch w, h = c_surf.w, c_surf.h with locked(new_surf): with locked(c_surf): if bpp in (1, 2, 4): ptr_type = 'uint%s_t*' % c_surf.format.BitsPerPixel srcpixels = ffi.cast(ptr_type, c_surf.pixels) destpixels = ffi.cast(ptr_type, new_surf.pixels) else: srcpixels = ffi.cast('uint8_t*', c_surf.pixels) destpixels = ffi.cast('uint8_t*', new_surf.pixels) dy = 0 if bpp in (1, 2, 4): dest_step = dest_pitch // bpp src_step = src_pitch // bpp for sy in range(0, surface._h): if sy >= y and sy < y + height: continue dx = 0 if bpp in (1, 2, 4): dest_row_start = dy * dest_step src_row_start = sy * src_step else: dest_row_start = dy * dest_pitch src_row_start = sy * src_pitch for sx in range(0, surface._w): if sx >= x and sx < x + width: continue if bpp in (1, 2, 4): destpixels[dest_row_start + dx] = \ srcpixels[src_row_start + sx] else: dest_pix_start = dest_row_start + dx src_pix_start = src_row_start + sx destpixels[dest_pix_start:dest_pix_start + 3] = \ srcpixels[src_pix_start:src_pix_start + 3] dx += 1 dy += 1 return Surface._from_sdl_surface(new_surf)