def load(self, filename): """Loads the font from a ``.dmd`` file (see :meth:`Animation.load`). Fonts are stored in .dmd files with frame 0 containing the bitmap data and frame 1 containing the character widths. 96 characters (32..127, ASCII printables) are stored in a 10x10 grid, starting with space (``' '``) in the upper left at 0, 0. The character widths are stored in the second frame within the 'raw' bitmap data in bytes 0-95. """ self.__anim.load(filename) if self.__anim.width != self.__anim.height: raise ValueError, "Width != height!" root, ext = os.path.splitext(filename) metrics_filename = root + ".metrics.json" self.metrics = None left = 0 if os.path.exists(metrics_filename): with open(metrics_filename) as fp: self.metrics = json.load(fp) left = self.metrics.get("left", 0) self.top = self.metrics.get("top", 0) self.margin_top = self.metrics.get("margin_top", 0) self.bottom = self.metrics.get("bottom", 0) elif len(self.__anim.frames) == 1: # We allow 1 frame for handmade fonts. # This is so that they can be loaded as a basic bitmap, have their char widths modified, and then be saved. print "Font animation file %s has 1 frame; adding one" % (filename) self.__anim.frames += [Frame(self.__anim.width, self.__anim.height)] elif len(self.__anim.frames) != 2: raise ValueError, "Expected 2 frames: %d" % (len(self.__anim.frames)) self.char_size = self.__anim.width / 10 self.bitmap = self.__anim.frames[0] # FIXME: Create a separate bitmap for each possible color. This makes # rendering fast, but could be improved self.bitmaps = {} self.bitmaps[0xf] = self.bitmap for color in xrange(1, 0xf): #print color width = self.bitmap.width height = self.bitmap.height self.bitmaps[color] = Frame(width, height) bitmap = self.bitmaps[color] fill = Frame(width, height) sub_color = 0xf - color fill.fill_rect(0, 0, width, height, sub_color) Frame.copy_rect(bitmap, 0, 0, self.bitmap, 0, 0, width, height) Frame.copy_rect(bitmap, 0, 0, fill, 0, 0, width, height, "sub") """ for x in xrange(self.bitmap.width): for y in xrange(self.bitmap.height): dot = self.bitmap.get_dot(x, y) - (0xf - color) if dot > 0: self.bitmaps[color].set_dot(x, y, dot) """ self.char_widths = [] self.left = [] if not self.metrics: for i in xrange(95): self.char_widths += [self.__anim.frames[1].get_dot(i%self.__anim.width, i/self.__anim.width)] self.left += [0] else: overrides = self.metrics.get("left_override", {}) for i in xrange(95): self.char_widths += [self.metrics["widths"][i][1]] ch = chr(ord(' ') + i) self.left += [overrides.get(ch, left)] return self