def __init__(self, font, size=(256,256)): self.font = font self.packingY = 0 self.packingX = 0 self.lineHeight = 0 self.size = size self.surface = pygame.Surface(size) self.texture = Texture() self.textureDirty = True # To avoid mipmaps blending glyhps together, we have to # leave a gap between glyphs equal to the number of mipmap levels we have. self.gap = (int(math.log(size[0]) / math.log(2)), int(math.log(size[1]) / math.log(2)))
class FontPage: """A collection of glyphs rendered to one texture""" def __init__(self, font, size=(256,256)): self.font = font self.packingY = 0 self.packingX = 0 self.lineHeight = 0 self.size = size self.surface = pygame.Surface(size) self.texture = Texture() self.textureDirty = True # To avoid mipmaps blending glyhps together, we have to # leave a gap between glyphs equal to the number of mipmap levels we have. self.gap = (int(math.log(size[0]) / math.log(2)), int(math.log(size[1]) / math.log(2))) def updateTexture(self): """If necessary, update the texture from the surface""" if not self.textureDirty: return self.texture.loadSurface(self.surface, monochrome=True) self.textureDirty = False def allocRect(self, size): """Allocate space for a rectangle of the given size on the texture. Return a point indicating the top-left corner of the allocated rectangle, or None if there is no room. This implementation simply packs top-down left-to-right in rows. """ if size[0] > self.size[0]: return None if self.packingX + size[0] + self.gap[0] > self.size[0]: # Next line self.packingX = 0 self.packingY += self.lineHeight self.lineHeight = 0 if self.packingY + size[1] > self.size[1]: return None if size[1] + self.gap[1] > self.lineHeight: self.lineHeight = size[1] + self.gap[1] allocated = (self.packingX, self.packingY) self.packingX += size[0] + self.gap[0] return allocated def pack(self, char): """Pack the glyph for the given character into our texture, return a Glyph. If there isn't enough room, return None. """ # Size the glyph and allocate space for it glyphSize = self.font.size(char) allocated = self.allocRect(glyphSize) if not allocated: return None # Render the character and create a Glyph self.surface.blit(self.font.render(char, True, (255,255,255), (0,0,0)), allocated) self.textureDirty = True return Glyph((allocated[0], allocated[1], glyphSize[0], glyphSize[1]), self)