26 self.charsize = Size(advance, height) |
26 self.charsize = Size(advance, height) |
27 self.ascent = self.font.get_ascent() |
27 self.ascent = self.font.get_ascent() |
28 |
28 |
29 # choose self.render() implementation |
29 # choose self.render() implementation |
30 if hasattr(self.font, 'render_glyph'): |
30 if hasattr(self.font, 'render_glyph'): |
31 self.render = self.render_glyph |
31 self.render_char = self.render_glyph |
32 else: |
32 else: |
33 self.render = self.render_noglyph |
33 self.render_char = self.render_noglyph |
34 |
34 |
35 def render_glyph(self, screen, x, y, c, fgcolor, bgcolor, defcolor, attr): |
35 self.chars = None |
|
36 self.attrs = None |
|
37 self.default_attr = None |
|
38 self.current_attr = None |
|
39 |
|
40 def set_default_attr(self, fg, bg, flags): |
|
41 self.default_attr = (fg, bg, flags) |
|
42 |
|
43 def set_attr(self, fg, bg, flags): |
|
44 self.current_attr = (fg, bg, flags) |
|
45 |
|
46 def reset_attr(self): |
|
47 self.current_attr = self.default_attr |
|
48 |
|
49 def reset(self, w, h): |
|
50 self.w, self.h = w, h |
|
51 numchars = w * h |
|
52 self.chars = [' '] * numchars |
|
53 self.attrs = [self.default_attr] * numchars |
|
54 |
|
55 def clear(self): |
|
56 numchars = self.w * self.h |
|
57 for pos in range(numchars): |
|
58 self.chars[pos] = ' ' |
|
59 self.attrs[pos] = self.default_attr |
|
60 |
|
61 def putch(self, x, y, c): |
|
62 pos = y * self.w + x |
|
63 self.chars[pos] = c |
|
64 self.attrs[pos] = self.current_attr |
|
65 |
|
66 def update(self, surface): |
|
67 pos = 0 |
|
68 for y in range(self.h): |
|
69 for x in range(self.w): |
|
70 fgcolor, bgcolor, flags = self.attrs[pos] |
|
71 c = self.chars[pos] |
|
72 if c == ' ': |
|
73 c = None |
|
74 self.render_char(surface, x, y, c, |
|
75 fgcolor, bgcolor, flags) |
|
76 pos += 1 |
|
77 |
|
78 def render_glyph(self, screen, x, y, c, fgcolor, bgcolor, flags): |
36 '''Render using render_glyph and metrics. |
79 '''Render using render_glyph and metrics. |
37 |
80 |
38 This is the correct way, but the output seems same as of render_noglyph |
81 This is the correct way, but the output seems same as of render_noglyph |
39 and this implementation requires patching PyGame to work. |
82 and this implementation requires patching PyGame to work. |
40 |
83 |
41 This implements render() method. See render_noglyph for other implementation. |
84 This implements render() method. See render_noglyph for other implementation. |
42 |
85 |
43 ''' |
86 ''' |
44 # draw background |
87 # draw background |
45 dest = Coords(x * self.charsize.w, y * self.charsize.h) |
88 dest = Coords(x * self.charsize.w, y * self.charsize.h) |
46 if bgcolor != defcolor: |
89 if bgcolor != self.default_attr[1]: |
47 screen.fill(bgcolor, pygame.Rect(dest.x, dest.y, self.charsize.w, self.charsize.h)) |
90 screen.fill(bgcolor, pygame.Rect(dest.x, dest.y, self.charsize.w, self.charsize.h)) |
48 |
91 |
49 if not c: |
92 if not c: |
50 return |
93 return |
51 |
94 |
52 # choose font |
95 # choose font |
53 if attr == 'bold': |
96 if flags == 1: |
54 font = self.font_bold |
97 font = self.font_bold |
55 else: |
98 else: |
56 font = self.font |
99 font = self.font |
57 |
100 |
58 # render character, get metrics |
101 # render character, get metrics |
173 self.charsize = Size(16, 8) # character size in pixels |
216 self.charsize = Size(16, 8) # character size in pixels |
174 self.last_keypress = None |
217 self.last_keypress = None |
175 self.last_key = None |
218 self.last_key = None |
176 self.colors = {} # maps names to curses attributes |
219 self.colors = {} # maps names to curses attributes |
177 self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this |
220 self.colorstack = [] # pushcolor/popcolor puts or gets attributes from this |
178 self.default_color = (self.colormap['white'], self.colormap['black'], 0) |
|
179 self.current_color = self.default_color |
|
180 |
221 |
181 def start(self, mainfunc): |
222 def start(self, mainfunc): |
182 pygame.init() |
223 pygame.init() |
183 self.term = TerminalScreen() |
224 self.term = TerminalScreen() |
184 self.charsize = self.term.charsize |
225 self.charsize = self.term.charsize |
185 self.resize_screen() |
226 self.resize_screen() |
|
227 self.term.set_default_attr(self.colormap['white'], self.colormap['black'], 0) |
|
228 self.term.reset_attr() |
186 mainfunc() |
229 mainfunc() |
187 |
230 |
188 def resize_screen(self): |
231 def resize_screen(self): |
189 mode = self.size.w * self.charsize.w, self.size.h * self.charsize.h |
232 mode = self.size.w * self.charsize.w, self.size.h * self.charsize.h |
190 self.screen = pygame.display.set_mode(mode, pygame.RESIZABLE) |
233 self.screen = pygame.display.set_mode(mode, pygame.RESIZABLE) |
191 numchars = self.size.w * self.size.h |
234 self.term.reset(self.size.w, self.size.h) |
192 self.screenchars = [' '] * numchars |
|
193 self.screencolors = [self.default_color] * numchars |
|
194 |
235 |
195 ## input ## |
236 ## input ## |
196 |
237 |
197 def getevents(self, timeout=None): |
238 def getevents(self, timeout=None): |
198 '''Process input, return list of events.''' |
239 '''Process input, return list of events.''' |
249 |
290 |
250 ## drawing ## |
291 ## drawing ## |
251 |
292 |
252 def erase(self): |
293 def erase(self): |
253 '''Clear screen.''' |
294 '''Clear screen.''' |
254 numchars = self.size.w * self.size.h |
295 self.term.clear() |
255 for pos in range(numchars): |
296 self.screen.fill(self.term.default_attr[1]) |
256 self.screenchars[pos] = ' ' |
|
257 self.screencolors[pos] = self.default_color |
|
258 self.screen.fill(self.default_color[1]) |
|
259 |
297 |
260 def putch(self, x, y, c): |
298 def putch(self, x, y, c): |
261 if not self.clipstack.test(x, y): |
299 if not self.clipstack.test(x, y): |
262 return |
300 return |
263 pos = y*self.size.w+x |
301 self.term.putch(x, y, c) |
264 self.screencolors[pos] = self.current_color |
|
265 self.screenchars[pos] = c |
|
266 |
302 |
267 def commit(self): |
303 def commit(self): |
268 '''Commit changes to the screen.''' |
304 '''Commit changes to the screen.''' |
269 pos = 0 |
305 self.term.update(self.screen) |
270 for y in range(self.size.h): |
|
271 for x in range(self.size.w): |
|
272 fgcolor, bgcolor, attr = self.screencolors[pos] |
|
273 c = self.screenchars[pos] |
|
274 if c == ' ': |
|
275 c = None |
|
276 self.term.render(self.screen, x, y, c, |
|
277 fgcolor, bgcolor, self.default_color[1], attr) |
|
278 pos += 1 |
|
279 pygame.display.flip() |
306 pygame.display.flip() |
280 |
307 |
281 |
308 |
282 ## colors ## |
309 ## colors ## |
283 |
310 |
324 def popcolor(self): |
351 def popcolor(self): |
325 '''Remove color from top of stack and use new top color for following output.''' |
352 '''Remove color from top of stack and use new top color for following output.''' |
326 self.colorstack.pop() |
353 self.colorstack.pop() |
327 if len(self.colorstack): |
354 if len(self.colorstack): |
328 col = self.colorstack[-1] |
355 col = self.colorstack[-1] |
329 else: |
356 self.term.set_attr(col[0], col[1], col[2]) |
330 col = self.default_color |
357 else: |
331 self.current_color = col |
358 self.term.reset_attr() |
332 |
359 |
333 |
360 |
334 ## cursor ## |
361 ## cursor ## |
335 |
362 |
336 def showcursor(self, x, y): |
363 def showcursor(self, x, y): |