Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/usmpgames/txtlib.py
diff options
context:
space:
mode:
authorMateu 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)
commit0018a9e211ebbe74d371339a70edc0d36c4fc99f (patch)
treeddfd93d0713c615ed70dbf869747b55b94791af8 /usmpgames/txtlib.py
Initial import of game1 and game2 in math quwy
Diffstat (limited to 'usmpgames/txtlib.py')
-rwxr-xr-xusmpgames/txtlib.py291
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