--- a/tuikit/driver_pygame.py Wed Oct 12 00:58:46 2011 +0200
+++ b/tuikit/driver_pygame.py Wed Oct 12 10:11:27 2011 +0200
@@ -8,11 +8,11 @@
from tuikit.common import Coords, Size, MouseEvent
-class CharCache:
+class TerminalScreen:
- '''CharCache should implement character cache, as the name suggests.
+ '''Provide character-level output to screen SDL surface.
- Currently it does not, characters ale rendered directly from TTF.
+ This is performance bottleneck and should be optimized as much as possible.
'''
@@ -32,7 +32,7 @@
else:
self.render = self.render_noglyph
- def render_glyph(self, screen, x, y, c, fgcolor, bgcolor, attr):
+ def render_glyph(self, screen, x, y, c, fgcolor, bgcolor, defcolor, attr):
'''Render using render_glyph and metrics.
This is the correct way, but the output seems same as of render_noglyph
@@ -40,12 +40,21 @@
This implements render() method. See render_noglyph for other implementation.
- '''
+ '''
+ # draw background
+ dest = Coords(x * self.charsize.w, y * self.charsize.h)
+ if bgcolor != defcolor:
+ screen.fill(bgcolor, pygame.Rect(dest.x, dest.y, self.charsize.w, self.charsize.h))
+
+ if not c:
+ return
+
+ # choose font
if attr == 'bold':
font = self.font_bold
else:
font = self.font
-
+
# render character, get metrics
surface = font.render_glyph(c, True, fgcolor, bgcolor)
metrics = font.metrics(c)[0]
@@ -65,10 +74,6 @@
if maxx > advance:
maxx = advance
- # draw background
- dest = Coords(x * self.charsize.w, y * self.charsize.h)
- screen.fill(bgcolor, pygame.Rect(dest.x, dest.y, self.charsize.w, self.charsize.h))
-
# draw character
dest.x += minx
dest.y += ascent - maxy
@@ -164,7 +169,7 @@
self.log = logging.getLogger('tuikit')
self.screen = None
self.size.w, self.size.h = 120, 40 # screen size in characters
- self.charcache = None
+ self.term = None
self.charsize = Size(16, 8) # character size in pixels
self.last_keypress = None
self.last_key = None
@@ -175,12 +180,17 @@
def start(self, mainfunc):
pygame.init()
- self.charcache = CharCache()
- self.charsize = self.charcache.charsize
+ self.term = TerminalScreen()
+ self.charsize = self.term.charsize
+ self.resize_screen()
+ mainfunc()
+
+ def resize_screen(self):
mode = self.size.w * self.charsize.w, self.size.h * self.charsize.h
self.screen = pygame.display.set_mode(mode, pygame.RESIZABLE)
- mainfunc()
-
+ numchars = self.size.w * self.size.h
+ self.screenchars = [' '] * numchars
+ self.screencolors = [self.default_color] * numchars
## input ##
@@ -218,8 +228,7 @@
neww, newh = ev.w // self.charsize.w, ev.h // self.charsize.h
if neww != self.size.w or newh != self.size.h:
self.size.w, self.size.h = neww, newh
- mode = self.size.w * self.charsize.w, self.size.h * self.charsize.h
- self.screen = pygame.display.set_mode(mode, pygame.RESIZABLE)
+ self.resize_screen()
events.append(('resize',))
elif ev.type == pygame.QUIT:
events.append(('quit',))
@@ -242,16 +251,31 @@
def erase(self):
'''Clear screen.'''
- self.screen.fill(self.colormap['black'])
+ numchars = self.size.w * self.size.h
+ for pos in range(numchars):
+ self.screenchars[pos] = ' '
+ self.screencolors[pos] = self.default_color
+ self.screen.fill(self.default_color[1])
def putch(self, x, y, c):
if not self.clipstack.test(x, y):
return
- fgcolor, bgcolor, attr = self.current_color
- self.charcache.render(self.screen, x, y, c, fgcolor, bgcolor, attr)
+ pos = y*self.size.w+x
+ self.screencolors[pos] = self.current_color
+ self.screenchars[pos] = c
def commit(self):
'''Commit changes to the screen.'''
+ pos = 0
+ for y in range(self.size.h):
+ for x in range(self.size.w):
+ fgcolor, bgcolor, attr = self.screencolors[pos]
+ c = self.screenchars[pos]
+ if c == ' ':
+ c = None
+ self.term.render(self.screen, x, y, c,
+ fgcolor, bgcolor, self.default_color[1], attr)
+ pos += 1
pygame.display.flip()