Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/usr/bin/env python
- # -*- coding: utf-8 -*-
- #
- # pixelfont.py
- #
- # Copyright 2012 Maximilian Timmerkamp
- #
- # This program is free software; you can redistribute it and/or modify
- # it under the terms of the GNU General Public License as published by
- # the Free Software Foundation; either version 2 of the License, or
- # (at your option) any later version.
- #
- # This program is distributed in the hope that it will be useful,
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- # GNU General Public License for more details.
- #
- # You should have received a copy of the GNU General Public License
- # along with this program; if not, write to the Free Software
- # Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
- # MA 02110-1301, USA.
- """
- Contains a small and nice class to print scaled bitmap fonts
- on a surface (if you like grainy fonts).
- """
- import pygame
- from pygame.locals import SRCALPHA, RLEACCEL
- #from utils import load_image
- def load_image(path, colorkey=None, return_rect=True):
- """Loads an image from path and returns a
- (transparent/alpha-converted) Surface containing it.
- path (str) - path of the image to load
- colorkey (pygame.Color or RBG-tuple) - color to use as colorkey of
- the surface (default: None)
- return_rect (boolean) - additionally return the image's rect?
- (default: True)
- """
- try:
- image = pygame.image.load(path)
- except pygame.error, message:
- print('Cannot load image:', path)
- raise SystemExit, message
- image = image.convert_alpha()
- if colorkey is not None:
- if colorkey == -1:
- colorkey = image.get_at((0, 0))
- image.set_colorkey(colorkey, RLEACCEL)
- if return_rect:
- return (image, image.get_rect())
- else:
- return image
- CHARORDER_ASCII = (' !"#$%&\'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTU'+
- 'VWXYZ[\\]^_`abcdefghijklmnopqrstuvwxyz{|}~ ')
- class PixelFont(object):
- """A PixelFont is a bitmap font which is scaled up to see the
- pixels of the bitmap.
- fontimage (str or pygame.Surface) - image to extract the chars
- from
- size (tuple) - size (width, height) of a single char
- foreground_color (pygame.Color or RGB-tuple) - color of the
- chars on the fontimage (necessary to change the foreground
- color) (default: black)
- background_color (pygame.Color or RGB-tuple) - color the
- the background in output should have
- scale (float) - the scale of the chars
- charorder (str) - order of the chars on fontimage from left to
- right, up to down
- """
- def __init__(self, fontimage, size, foreground_color=(0, 0, 0),
- background_color=None, scale=1, charorder=CHARORDER_ASCII):
- if isinstance(fontimage, str):
- # using my own load_image():
- fontimage = load_image(fontimage, return_rect=False)
- # using a more or less standard load_image():
- #fontimage = load_image(fontimage)[0].convert_alpha()
- self.fontdict = {}
- width, height = size
- scaled_width = width * scale
- scaled_height = height * scale
- self.scaled_size = (scaled_width, scaled_height)
- self._font_foreground = foreground_color
- self.foreground_color = foreground_color
- self.background_color = background_color
- self._render_font(fontimage, size, charorder)
- self._scale_font()
- def _render_font(self, fontimage, size, charorder):
- """Cuts self.fontimage into small character images.
- fontimage (pygame.Surface) - the surface to extract the chars
- from
- size (tuple) - size of a char on fontimage
- charorder (str) - order of the chars on fontimage from left to
- right, top to bottom
- """
- width, height = size
- fontimage_rect = fontimage.get_rect()
- rect = pygame.Rect((0, 0), size)
- char_index = 0
- for top_coord in xrange(0, fontimage_rect.height, height):
- for left_coord in xrange(0, fontimage_rect.width, width):
- char_image = pygame.surface.Surface(size,
- flags=SRCALPHA)
- rect.top = top_coord
- rect.left = left_coord
- char_image.blit(fontimage, (0, 0), rect)
- self.fontdict[charorder[char_index]] = char_image
- char_index += 1
- def _scale_font(self):
- """Scales all characters using PixelFont.scaled_size to resize
- the characters.
- """
- scaled_width, scaled_height = self.scaled_size
- rect = pygame.Rect(0, 0, scaled_width, scaled_height)
- for char in self.fontdict:
- char_image = self.fontdict[char]
- char_image = pygame.transform.scale(char_image, rect.size)
- self.fontdict[char] = char_image
- def write(self, surface, text, position=(0, 0)):
- """Writes a string at the given position on the given surface.
- PixelFont.foreground_color and background_color are used to
- color the text.
- surface (pygame.Surface) - the surface to write the text on
- text (str) - string to be written on the surface
- position (tuple) - tuple with the destination position (x, y)
- (default: (0, 0))
- """
- self.write_color(surface, text, position=position,
- foreground=self.foreground_color,
- background=self.background_color)
- def write_args(self, surface, position, *args):
- """Writes strings at the given position on the given surface.
- Each argument from *args is seperated by a space.
- surface (pygame.Surface) - the surface to write the text on
- position (tuple) - tuple with the destination position (x, y)
- *args (object) - objects which are converted to strings using
- str()
- """
- string = ' '.join(map(str, args))
- self.write_color(surface, string, position=position,
- foreground=self.foreground_color,
- background=self.background_color)
- def write_color(self, surface, text, position=(0, 0), foreground=None,
- background=None):
- """Writes a string at the given position on the given surface.
- If foreground is None, the color of the chars will not be
- changed. If background is None, the background will be
- transparent.
- surface (pygame.Surface) - the surface to write the text on
- text (str) - string to be written on the surface
- position (tuple) - tuple with the destination position (x, y)
- (default: (0, 0))
- foreground (pygame.Color or RGB-tuple) - color of the characters
- (default: standard color from fontimage)
- background (pygame.Coloror RGB-tuple) - background color
- (default: None)
- """
- scaled_width, scaled_height = self.scaled_size
- rect = pygame.Rect(position, (scaled_width, scaled_height))
- for row in text.splitlines():
- rect.left = position[0]
- for char in row:
- try:
- char_image = self.fontdict[char]
- except KeyError:
- # TODO: Macht das Sinn: Erst abfangen und dann neu werfen?
- raise KeyError('font does not contain char: ' + char)
- if (foreground is not None and
- foreground != self._font_foreground):
- array = pygame.PixelArray(char_image)
- array.replace(self._font_foreground, foreground)
- char_image = array.make_surface()
- if background is not None:
- surface.fill(background, rect)
- surface.blit(char_image, rect)
- rect.left += scaled_width
- rect.top += scaled_height
- def get_textarea_size(self, *args):
- """Returns a tuple with the size (width, height) of the area
- which might be affected by a call of PixelFont.write().
- """
- text = ' '.join(map(str, args))
- scaled_width, scaled_height = self.scaled_size
- rows = text.splitlines()
- row_count = len(rows)
- max_line_length = max(map(len, rows))
- width = max_line_length * scaled_width
- height = row_count * scaled_height
- return (width, height)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement