def __init__(self, bitmap, grid=None, border=0, imgkey=None): if grid is None: w = _getdim(bitmap.width+border*2) h = _getdim(bitmap.height+border*2) grid = (w,h) self._grid = grid self._border = border self._images = [] self._key = imgkey self._textures = TextureManager() self._cObj = _c.GridImage(*grid) self._split(bitmap)
def __init__(self, fontfile, pngfile=None, spacing=0, linespacing=0): """Open a previously created bitmap font""" if pngfile is None: pngfile = splitext(fontfile)[0] + ".png" f = open(fontfile, "rb") data = f.read() f.close() data = pickle.loads(data) f.close() self.chardict = {} self.bmpdict = {} self.texmgr = TextureManager() s = Bitmap.Load(open(pngfile, "rb")) for k, (x, y, w, h) in data.char_rects.iteritems(): bmp = s.get_subbitmap(x, y, w, h) img = self.texmgr.add_image(bmp) img.hotspot.set(0, 1) self.chardict[k] = ImageInstance(img) self.bmpdict[k] = bmp self.linesize = data.linesize self.padding = data.padding self.spacing = spacing self.linespacing = linespacing
class GridImage(ImageInstance): def __init__(self, bitmap, grid=None, border=0, imgkey=None): if grid is None: w = _getdim(bitmap.width+border*2) h = _getdim(bitmap.height+border*2) grid = (w,h) self._grid = grid self._border = border self._images = [] self._key = imgkey self._textures = TextureManager() self._cObj = _c.GridImage(*grid) self._split(bitmap) def _split(self, bitmap): gx,gy = self._grid bmpw = bitmap.width bmph = bitmap.height self._size = bmpw,bmph self._cObj.SetSize(bmpw, bmph) xs,xr = divmod(bmpw, gx) ys,yr = divmod(bmph, gy) assert xs < 512-self._border*2 and ys < 512-self._border*2 scry = 0 for y in range(gy): scrx = 0 height = ys if y < yr: height += 1 row = [] for x in range(gx): width = xs if x < xr: width += 1 bmp = bitmap.get_subbitmap(scrx, scry, width, height) #bmp.thisown = 1 if self._border: bmp = bmp.transform(transform.make_bordered, self._border) #bmp.thisown = 1 img = self._textures.add_image(bmp, border=self._border) row.append(img) self._cObj.AppendImage(img) scrx += width scry += height self._images.append(row)
def __init__(self, fontfile, pngfile=None, spacing=0, linespacing=0): """Open a previously created bitmap font""" if pngfile is None: pngfile = splitext(fontfile)[0]+".png" f = open(fontfile, "rb") data = f.read() f.close() data = pickle.loads(data) f.close() self.chardict = {} self.bmpdict = {} self.texmgr = TextureManager() s = Bitmap.Load(open(pngfile,"rb")) for k, (x, y, w, h) in data.char_rects.iteritems(): bmp = s.get_subbitmap(x, y, w, h) img = self.texmgr.add_image(bmp) img.hotspot.set(0, 1) self.chardict[k] = ImageInstance(img) self.bmpdict[k] = bmp self.linesize = data.linesize self.padding = data.padding self.spacing = spacing self.linespacing = linespacing
def __init__(self): self.images = {} self.patterns = {} self._texmgr = TextureManager() self.path = None
class ResourceManager(object): """ResourceManager singleton """ def __init__(self): self.images = {} self.patterns = {} self._texmgr = TextureManager() self.path = None def set_source(self, path): """Set the source path for resource loading (defaults to current dir)""" self.path = path def open_resource(self, name): if self.path is not None: if zipfile.is_zipfile(self.path): z = zipfile.ZipFile(self.path) s = z.read(name.replace("\\", "/")) z.close() sio = StringIO.StringIO(s) sio.name = name return sio return open(os.path.join(self.path, name), "rb") return open(name, "rb") def find_resources(self, pattern): if self.path is not None: if zipfile.is_zipfile(self.path): z = zipfile.ZipFile(self.path) names = z.namelist() r = _globre(pattern) return [name for name in names if r.match(name)] return glob(os.path.join(self.path, pattern)) return glob(pattern) def preload_images(self, pattern): files = self.find_resources(pattern) for fn in files: fn = fn.replace(os.path.sep, "/") for img in ImageMeta.subclasses: if img.filename == fn: self.get_image(img) break else: self.get_image(fn) def clear_cache(self): """Removes everything from cache""" self.images = {} self.patterns = {} def get_image(self, image, hotspot=None, mode=None, border=None): """Load an image from the given path The image is cached and the same Image instance is returned on subsequent calls. """ if isinstance(image, type) and issubclass(image, Image): image = image() elif not isinstance(image, Image): filename = image image = Image() image.filename = filename if mode or hotspot or border: image = image.copy() if hotspot is not None: image.hotspot = hotspot if mode is not None: image.mode = mode if border is not None: image.border = border if isinstance(image.mode, basestring): image.mode = [image.mode] try: return self.images[image] except KeyError: if not image.filename: raise ValueError( "no filename specified in Image definition for %s" % image.__class__.__name__) bmp = self._load_bitmap(image.filename) for mod in image.mode: try: func = getattr(transform, "make_" + mod) except AttributeError: raise ValueError("invalid Image mode: %r" % mod) bmp = bmp.transform(func) img = self._set_image(image, bmp, hotspot=image.hotspot, border=image.border) img._cObj.hotspot.set(*image.hotspot) for c in image.collision: img.add_collision_node(*c) return img def get_strip(self, image, width): """Load an image strip and return a list of images """ pass def get_grid(self, image, width, height, hotspot=None): """Load an image grid and return a list of images """ bmp = self._load_bitmap(image) cols = bmp.width // width rows = bmp.height // height result = [] for r in range(rows): for c in range(cols): sb = bmp.get_subbitmap(c * width, r * height, width, height) result.append(self._create_image(sb, hotspot)) return result def get_pattern(self, pattern=None, hotspot=None, mode=None, border=None): """Load images using a glob pattern""" if pattern in self.patterns: return self.patterns[pattern] files = self.find_resources(pattern) files.sort() images = [] for fn in files: images.append( self.get_image(fn, hotspot=hotspot, mode=mode, border=border)) self.patterns[pattern] = images return images def _set_image(self, key, bmp, hotspot=None, border=1): img = self._create_image(bmp, hotspot, border) img._key = key self.images[key] = img return img def _create_image(self, bmp, hotspot=None, border=1): if bmp.width + border * 2 > 512 or bmp.height + border * 2 > 512: img = GridImage(bmp, border=border) else: if border: bmp = bmp.transform(transform.make_bordered, border) img = self._texmgr.add_image(bmp, border) img = ImageInstance(img) if hotspot: img._cObj.hotspot.set(*hotspot) return img def _load_bitmap(self, src): if not hasattr(src, "read"): src = self.open_resource(src) # read from file-like object bmp = Bitmap.Load(src) return bmp
class ResourceManager(object): """ResourceManager singleton """ def __init__(self): self.images = {} self.patterns = {} self._texmgr = TextureManager() self.path = None def set_source(self, path): """Set the source path for resource loading (defaults to current dir)""" self.path = path def open_resource(self, name): if self.path is not None: if zipfile.is_zipfile(self.path): z = zipfile.ZipFile(self.path) s = z.read(name.replace("\\", "/")) z.close() sio = StringIO.StringIO(s) sio.name = name return sio return open(os.path.join(self.path, name), "rb") return open(name, "rb") def find_resources(self, pattern): if self.path is not None: if zipfile.is_zipfile(self.path): z = zipfile.ZipFile(self.path) names = z.namelist() r = _globre(pattern) return [name for name in names if r.match(name)] return glob(os.path.join(self.path, pattern)) return glob(pattern) def preload_images(self, pattern): files = self.find_resources(pattern) for fn in files: fn = fn.replace(os.path.sep, "/") for img in ImageMeta.subclasses: if img.filename == fn: self.get_image(img) break else: self.get_image(fn) def clear_cache(self): """Removes everything from cache""" self.images = {} self.patterns = {} def get_image(self, image, hotspot=None, mode=None, border=None): """Load an image from the given path The image is cached and the same Image instance is returned on subsequent calls. """ if isinstance(image, type) and issubclass(image, Image): image = image() elif not isinstance(image, Image): filename = image image = Image() image.filename = filename if mode or hotspot or border: image = image.copy() if hotspot is not None: image.hotspot = hotspot if mode is not None: image.mode = mode if border is not None: image.border = border if isinstance(image.mode, basestring): image.mode = [image.mode] try: return self.images[image] except KeyError: if not image.filename: raise ValueError("no filename specified in Image definition for %s" % image.__class__.__name__) bmp = self._load_bitmap(image.filename) for mod in image.mode: try: func = getattr(transform, "make_"+mod) except AttributeError: raise ValueError("invalid Image mode: %r" % mod) bmp = bmp.transform(func) img = self._set_image(image, bmp, hotspot=image.hotspot, border=image.border) img._cObj.hotspot.set(*image.hotspot) for c in image.collision: img.add_collision_node(*c) return img def get_strip(self, image, width): """Load an image strip and return a list of images """ pass def get_grid(self, image, width, height, hotspot=None): """Load an image grid and return a list of images """ bmp = self._load_bitmap(image) cols = bmp.width // width rows = bmp.height // height result = [] for r in range(rows): for c in range(cols): sb = bmp.get_subbitmap(c*width,r*height,width,height) result.append(self._create_image(sb,hotspot)) return result def get_pattern(self, pattern=None, hotspot=None, mode=None, border=None): """Load images using a glob pattern""" if pattern in self.patterns: return self.patterns[pattern] files = self.find_resources(pattern) files.sort() images = [] for fn in files: images.append(self.get_image(fn, hotspot=hotspot, mode=mode, border=border)) self.patterns[pattern] = images return images def _set_image(self, key, bmp, hotspot=None, border=1): img = self._create_image(bmp, hotspot, border) img._key = key self.images[key] = img return img def _create_image(self, bmp, hotspot=None, border=1): if bmp.width+border*2 > 512 or bmp.height+border*2 > 512: img = GridImage(bmp, border=border) else: if border: bmp = bmp.transform(transform.make_bordered, border) img = self._texmgr.add_image(bmp, border) img = ImageInstance(img) if hotspot: img._cObj.hotspot.set(*hotspot) return img def _load_bitmap(self, src): if not hasattr(src, "read"): src = self.open_resource(src) # read from file-like object bmp = Bitmap.Load(src) return bmp
class BitmapFont(object): def __init__(self, fontfile, pngfile=None, spacing=0, linespacing=0): """Open a previously created bitmap font""" if pngfile is None: pngfile = splitext(fontfile)[0]+".png" f = open(fontfile, "rb") data = f.read() f.close() data = pickle.loads(data) f.close() self.chardict = {} self.bmpdict = {} self.texmgr = TextureManager() s = Bitmap.Load(open(pngfile,"rb")) for k, (x, y, w, h) in data.char_rects.iteritems(): bmp = s.get_subbitmap(x, y, w, h) img = self.texmgr.add_image(bmp) img.hotspot.set(0, 1) self.chardict[k] = ImageInstance(img) self.bmpdict[k] = bmp self.linesize = data.linesize self.padding = data.padding self.spacing = spacing self.linespacing = linespacing def create(self, s, single=False): if single: return self.create_single(s) n = Sprite() xpos = 0 ypos = 0 xmax = 0 nx = 0 ny = 0 height = self.linesize padleft, padright, padtop, padbottom = self.padding nx -= padleft ny += height-padtop n.letters = [] n.font = self for c in s: if c == '\n': xmax = max(xpos, xmax) ypos += height + self.linespacing nx -= xpos ny += height + self.linespacing xpos = 0 img = self.chardict.get(c, None) if img is None: continue s = Sprite(img) img = img._cObj s.attach_to(n) s.position = nx, ny n.letters.append(s) nx += img.w - padleft - padright + self.spacing xpos += img.w - padleft - padright + self.spacing #n.rect = (0, 0, xmax, ypos+height) return n def create_surface(self, s): xpos = 0 ypos = 0 xmax = 0 ymax = 0 nx = 0 ny = 0 height = self.linesize padleft, padright, padtop, padbottom = self.padding xpos += padleft #ny += height-padtop blits = [] for c in s: if c == '\n': xmax = max(xpos, xmax) ymax = 0 ypos += height + self.linespacing nx -= xpos ny += height + self.linespacing xpos = 0 bmp = self.bmpdict.get(c, None) if bmp is None: continue blits.append((bmp,nx,ny)) ymax = max(ymax, bmp.height) nx += bmp.width - padleft - padright + self.spacing xpos += bmp.width - padleft - padright + self.spacing xmax = max(xmax,xpos) size = xmax,ypos+ymax s = pygame.Surface(size, pygame.SRCALPHA, 32) #s.fill((255,255,255,255)) s.fill((0,0,0,0)) for bmp,x,y in blits: s.blit(bmp.surface, (x, y)) return s def create_single(self, s): surf = self.create_surface(s) img = ResourceManager._create_image(Bitmap(surf)) return Sprite(img)
class BitmapFont(object): def __init__(self, fontfile, pngfile=None, spacing=0, linespacing=0): """Open a previously created bitmap font""" if pngfile is None: pngfile = splitext(fontfile)[0] + ".png" f = open(fontfile, "rb") data = f.read() f.close() data = pickle.loads(data) f.close() self.chardict = {} self.bmpdict = {} self.texmgr = TextureManager() s = Bitmap.Load(open(pngfile, "rb")) for k, (x, y, w, h) in data.char_rects.iteritems(): bmp = s.get_subbitmap(x, y, w, h) img = self.texmgr.add_image(bmp) img.hotspot.set(0, 1) self.chardict[k] = ImageInstance(img) self.bmpdict[k] = bmp self.linesize = data.linesize self.padding = data.padding self.spacing = spacing self.linespacing = linespacing def create(self, s, single=False): if single: return self.create_single(s) n = Sprite() xpos = 0 ypos = 0 xmax = 0 nx = 0 ny = 0 height = self.linesize padleft, padright, padtop, padbottom = self.padding nx -= padleft ny += height - padtop n.letters = [] n.font = self for c in s: if c == '\n': xmax = max(xpos, xmax) ypos += height + self.linespacing nx -= xpos ny += height + self.linespacing xpos = 0 img = self.chardict.get(c, None) if img is None: continue s = Sprite(img) img = img._cObj s.attach_to(n) s.position = nx, ny n.letters.append(s) nx += img.w - padleft - padright + self.spacing xpos += img.w - padleft - padright + self.spacing #n.rect = (0, 0, xmax, ypos+height) return n def create_surface(self, s): xpos = 0 ypos = 0 xmax = 0 ymax = 0 nx = 0 ny = 0 height = self.linesize padleft, padright, padtop, padbottom = self.padding xpos += padleft #ny += height-padtop blits = [] for c in s: if c == '\n': xmax = max(xpos, xmax) ymax = 0 ypos += height + self.linespacing nx -= xpos ny += height + self.linespacing xpos = 0 bmp = self.bmpdict.get(c, None) if bmp is None: continue blits.append((bmp, nx, ny)) ymax = max(ymax, bmp.height) nx += bmp.width - padleft - padright + self.spacing xpos += bmp.width - padleft - padright + self.spacing xmax = max(xmax, xpos) size = xmax, ypos + ymax s = pygame.Surface(size, pygame.SRCALPHA, 32) #s.fill((255,255,255,255)) s.fill((0, 0, 0, 0)) for bmp, x, y in blits: s.blit(bmp.surface, (x, y)) return s def create_single(self, s): surf = self.create_surface(s) img = ResourceManager._create_image(Bitmap(surf)) return Sprite(img)