diff options
author | Mateu Batle <mateu.batle@collabora.co.uk> | 2010-10-27 17:40:28 (GMT) |
---|---|---|
committer | Mateu Batle <mateu.batle@collabora.co.uk> | 2010-10-27 17:40:28 (GMT) |
commit | 0018a9e211ebbe74d371339a70edc0d36c4fc99f (patch) | |
tree | ddfd93d0713c615ed70dbf869747b55b94791af8 /usmpgames/txtlib.py |
Initial import of game1 and game2 in math quwy
Diffstat (limited to 'usmpgames/txtlib.py')
-rwxr-xr-x | usmpgames/txtlib.py | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/usmpgames/txtlib.py b/usmpgames/txtlib.py new file mode 100755 index 0000000..ffacb45 --- /dev/null +++ b/usmpgames/txtlib.py @@ -0,0 +1,291 @@ +#!/usr/bin/env python +#-*- coding:utf-8 -*- + +import pygame + +BOLD = 'bold' +ITALIC = 'italic' +UNDERLINE = 'underline' +SIZE = 'size' +FONT = 'font' +COLOR = 'color' + +BEGIN = 'begin' +END = 'end' + +class Point: + + def __init__(self, classe, pos, type, attr=None): + self.pos = pos + self.classe = classe + self.type = type + self.attr = attr + + +class Text: + + def __init__(self, size, font, font_size=16, text=''): + self.rect = pygame.Rect((0, 0), size) + self.area = pygame.Surface(size, pygame.SRCALPHA | pygame.HWSURFACE) + self.background_color = (255, 255, 255) + + self.text = text + self.points = [] + + self.text_start = 0 + self.line_numbers = False # XXX doesn't work yet + self.antialias = True + self.border = 5 + + self.default_size = font_size + self.default_font = font + self.default_color = (0, 0, 0) + self.fonts = {} + self.load_font(font, font_size) + + def clear(self): + self.text = '' + + # this transform markup text in html style in txtlib style + def html(self, code): + code = str(code) + processing = False + if code.find('<'): + text = '' + txt_id = 0 + for id in range(len(code)): + if code[id] not in ('<', '>') and not processing: + text += code[id] + txt_id += 1 + elif code[id] == '>': + processing = False + elif code[id] == '<': + processing = True + if code[id+1] != '/': + if code[id+1].lower() == 'b': + self.points.append(Point(BEGIN, len(self.text)+txt_id, BOLD)) + elif code[id+1].lower() == 'i': + self.points.append(Point(BEGIN, len(self.text)+txt_id, ITALIC)) + elif code[id+1].lower() == 'u': + self.points.append(Point(BEGIN, len(self.text)+txt_id, UNDERLINE)) + else: + end = code[id:].lower().find('>') + id + if code[id:end].find('color') != -1: + print code[id+8:end-1] + rgb = code[id+8:end-1].replace(' ', '') + r, g, b = rgb.split(',') + self.points.append(Point(BEGIN, len(self.text)+txt_id, COLOR, (int(r), int(g), int(b)))) + elif code[id:end].lower().find('size') != -1: + size = int(code[id+7:end-1]) + self.points.append(Point(BEGIN, len(self.text)+txt_id, SIZE, size)) + elif code[id:end].lower().find('font') != -1: + font = code[id+7:end-1] + self.points.append(Point(BEGIN, len(self.text)+txt_id, FONT, font)) + else: + if code[id+2].lower() == 'b': + self.points.append(Point(END, len(self.text)+txt_id, BOLD)) + elif code[id+2].lower() == 'i': + self.points.append(Point(END, len(self.text)+txt_id, ITALIC)) + elif code[id+2].lower() == 'u': + self.points.append(Point(END, len(self.text)+txt_id, UNDERLINE)) + elif code[id+2].lower() == 'c': + self.points.append(Point(END, len(self.text)+txt_id, COLOR, None)) + elif code[id+2].lower() == 's': + self.points.append(Point(END, len(self.text)+txt_id, SIZE, None)) + elif code[id+2].lower() == 'f': + self.points.append(Point(END, len(self.text)+txt_id, FONT, None)) + + self.text += text + else: + self.text += code + + # add a style + def add_style(self, start, end, type, attr=None): + self.points.append(Point(BEGIN, start, type, attr)) + self.points.append(Point(END, end, type, attr)) + + self.points.sort(key=lambda x: x.pos) + + def load_font(self, font, size): + if font in pygame.font.get_fonts(): + f = pygame.font.SysFont(font, size) + if self.fonts.has_key(font): + self.fonts[font][size] = f + else: + self.fonts[font] = {size:f} + else: + try: + f = pygame.font.Font(font, size) + except: + f = pygame.font.Font(None, size) + + if self.fonts.has_key(font): + self.fonts[font][size] = f + else: + self.fonts[font] = {size:f} + + def check_fonts(self): + font = [self.default_font] + size = [self.default_size] + for point in self.points: + if point.classe == BEGIN: + if point.type == FONT: + font.append(point.attr) + elif point.type == SIZE: + size.append(point.attr) + else: + if point.type == FONT: + font.pop() + elif point.type == SIZE: + size.pop() + + if not self.fonts.has_key(font[len(font)-1]): + self.load_font(font[len(font)-1], size[len(size)-1]) + + if not self.fonts[font[len(font)-1]].has_key(size[len(size)-1]): + self.load_font(font[len(font)-1], size[len(size)-1]) + + # check the line height + def line_height(self, font, char, line): + line_height = font + size = [self.default_size] + font = [self.default_font] + for point in self.points: + if point.classe == BEGIN: + if point.type == FONT: + font.append(point.attr) + elif point.type == SIZE: + size.append(point.attr) + else: + if point.type == FONT: + font.pop() + elif point.type == SIZE: + size.pop() + + if char <= point.pos <= char+len(line) and point.type in (FONT, SIZE): + f = self.fonts[font[len(font)-1]][size[len(size)-1]].get_height() + if f > line_height: + line_height = f + + return line_height + + # replace some characters like tabs + def replace(self, text): + text = text.replace('\t', ' ') + + return text + + # redraw the text + def update(self): + # control if the needed fonts are loaded + self.check_fonts() + + self.area.fill(self.background_color) + + l = 0 # line number + dist_from_top = 0 + char = 0 # char num from the beginning + bottom_border = -self.text_start + self.rect.height + + bold = False + italic = False + underline = False + color = [self.default_color] + size = [self.default_size] + font = [self.default_font] + for line in self.text.split('\n'): + # check for line_height + h = self.fonts[font[len(font)-1]][size[len(size)-1]].get_height() + line_height = self.line_height(h, char, line) + + id = 0 + l_id = 0 + x = self.border # need changes to support line numers + printed = False + for point in self.points: + if char <= point.pos <= char+len(line): + # don't draw text if it's over the top border + if -self.text_start <= dist_from_top <= bottom_border and l_id == 0: + f = self.fonts[font[len(font)-1]][size[len(size)-1]] + f.set_bold(bold) + f.set_italic(italic) + f.set_underline(underline) + + text = self.replace(line[:point.pos-char]) + + render = f.render(text, self.antialias, color[len(color)-1]) + line_pos = (line_height-f.get_height())/2 + self.area.blit(render, (x, dist_from_top+self.text_start+line_pos+self.border)) + + x += render.get_width() + printed = True + + if point.classe == BEGIN: + if point.type == BOLD: + bold = True + elif point.type == ITALIC: + italic = True + elif point.type == UNDERLINE: + underline = True + elif point.type == COLOR: + color.append(point.attr) + elif point.type == SIZE: + size.append(point.attr) + elif point.type == FONT: + font.append(point.attr) + elif point.classe == END: + if point.type == BOLD: + bold = False + elif point.type == ITALIC: + italic = False + elif point.type == UNDERLINE: + underline = False + elif point.type == COLOR: + color.pop() + elif point.type == SIZE: + size.pop() + elif point.type == FONT: + font.pop() + + # don't draw text if it's over the top border + if -self.text_start <= dist_from_top <= bottom_border: + f = self.fonts[font[len(font)-1]][size[len(size)-1]] + f.set_bold(bold) + f.set_italic(italic) + f.set_underline(underline) + + try: + text = self.replace(line[point.pos-char:self.points[id+1].pos-char]) + except: + text = self.replace(line[point.pos-char:]) + + render = f.render(text, self.antialias, color[len(color)-1]) + line_pos = (line_height-f.get_height())/2 + self.area.blit(render, (x, dist_from_top+self.text_start+line_pos+self.border)) + + x += render.get_width() + printed = True + + l_id += 1 + + id += 1 + + if not printed and -self.text_start <= dist_from_top <= bottom_border: + f = self.fonts[font[len(font)-1]][size[len(size)-1]] + f.set_bold(bold) + f.set_italic(italic) + f.set_underline(underline) + + text = self.replace(line) + + render = f.render(text, self.antialias, color[len(color)-1]) + line_pos = (line_height-f.get_height())/2 + self.area.blit(render, (x, dist_from_top+self.text_start+line_pos+self.border)) + + x += render.get_width() + printed = True + + + l += 1 + char += len(line) + 1 + dist_from_top += line_height |