changeset 544:b895ed2de71f

Implement text rendering for the SDL backend.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Thu, 15 May 2014 02:56:08 +0200
parents fb837b32c3dd
children bcff39c920ab
files pytouhou/game/text.pxd pytouhou/ui/sdl/gamerenderer.pxd pytouhou/ui/sdl/gamerenderer.py pytouhou/ui/sdl/texture.pxd pytouhou/ui/sdl/texture.pyx
diffstat 5 files changed, 79 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/pytouhou/game/text.pxd
+++ b/pytouhou/game/text.pxd
@@ -60,16 +60,18 @@ cdef class NativeText(Element):
     cdef public object update
 
     cdef unicode text
-    cdef long width, height
-    cdef unsigned char alpha
-    cdef bint shadow
     cdef bytes align #TODO: use a proper enum.
     cdef unsigned long frame, timeout, duration, start
     cdef double to[2]
     cdef double end[2]
     cdef list gradient
     cdef Interpolator fade_interpolator, offset_interpolator
-    cdef object texture
+
+    #XXX
+    cdef public bint shadow
+    cdef public long width, height
+    cdef public unsigned char alpha
+    cdef public object texture
 
     #def normal_update(self)
     #def timeout_update(self)
--- a/pytouhou/ui/sdl/gamerenderer.pxd
+++ b/pytouhou/ui/sdl/gamerenderer.pxd
@@ -1,12 +1,12 @@
 from pytouhou.game.game cimport Game
-from .texture cimport TextureManager
+from .texture cimport TextureManager, FontManager
 from .sprite cimport get_sprite_rendering_data
 from pytouhou.ui.window cimport Window
 
 cdef class GameRenderer:
     cdef Window window
     cdef TextureManager texture_manager
-    #cdef FontManager font_manager
+    cdef FontManager font_manager
     cdef long x, y, width, height
 
     cdef public size #XXX
--- a/pytouhou/ui/sdl/gamerenderer.py
+++ b/pytouhou/ui/sdl/gamerenderer.py
@@ -13,8 +13,9 @@
 ##
 
 from itertools import chain
+from os.path import join
 
-from pytouhou.lib.sdl import Rect
+from pytouhou.lib.sdl import Rect, SDLError
 
 from pytouhou.utils.helpers import get_logger
 logger = get_logger(__name__)
@@ -24,6 +25,12 @@ class GameRenderer(object):
     def __init__(self, resource_loader, window):
         self.window = window
         self.texture_manager = TextureManager(resource_loader, self.window.win)
+        font_name = join(resource_loader.game_dir, 'font.ttf')
+        try:
+            self.font_manager = FontManager(font_name, 16, self.window.win)
+        except SDLError:
+            self.font_manager = None
+            logger.error('Font file ā€œ%sā€ not found, disabling text rendering altogether.', font_name)
 
 
     def load_textures(self, anms):
@@ -131,4 +138,25 @@ class GameRenderer(object):
 
 
     def render_text(self, texts):
-        pass
+        if self.font_manager is None:
+            return
+
+        self.font_manager.load(texts)
+
+        for label in texts.itervalues():
+            texture = label.texture
+
+            source = Rect(0, 0, label.width, label.height)
+            rect = Rect(label.x, label.y, label.width, label.height)
+
+            texture.set_alpha_mod(label.alpha)
+
+            if label.shadow:
+                shadow_rect = Rect(label.x + 1, label.y + 1, label.width, label.height)
+                texture.set_color_mod(0, 0, 0)
+                self.window.win.render_copy(label.texture, source, shadow_rect)
+                texture.set_color_mod(192, 192, 255)
+                self.window.win.render_copy(label.texture, source, rect)
+            else:
+                texture.set_color_mod(192, 192, 255)
+                self.window.win.render_copy(label.texture, source, rect)
--- a/pytouhou/ui/sdl/texture.pxd
+++ b/pytouhou/ui/sdl/texture.pxd
@@ -1,4 +1,4 @@
-#from pytouhou.lib.sdl cimport Font
+from pytouhou.lib.sdl cimport Font
 from pytouhou.lib.sdl cimport Surface, Window
 
 cdef class TextureManager:
@@ -8,8 +8,8 @@ cdef class TextureManager:
     cdef void load(self, dict anms) except *
     cdef load_texture(self, Surface texture)
 
-#cdef class FontManager:
-#    cdef Font font
-#    cdef object renderer, texture_class
-#
-#    cdef load(self, list labels)
+cdef class FontManager:
+    cdef Font font
+    cdef Window window
+
+    cdef void load(self, dict labels) except *
--- a/pytouhou/ui/sdl/texture.pyx
+++ b/pytouhou/ui/sdl/texture.pyx
@@ -13,9 +13,14 @@
 ##
 
 from pytouhou.lib.sdl cimport load_png, create_rgb_surface
+from pytouhou.lib.sdl import SDLError
+from pytouhou.game.text cimport NativeText
 
 import os
 
+from pytouhou.utils.helpers import get_logger
+logger = get_logger(__name__)
+
 
 cdef class TextureManager:
     def __init__(self, loader, window):
@@ -42,6 +47,36 @@ def is_ascii(anm):
     return anm[0].first_name.endswith('ascii.png')
 
 
+cdef class FontManager:
+    def __init__(self, fontname, fontsize=16, window=None):
+        self.font = Font(fontname, fontsize)
+        self.window = window
+
+
+    cdef void load(self, dict labels):
+        cdef NativeText label
+
+        for i, label in labels.items():
+            if label.texture is None:
+                try:
+                    surface = self.font.render(label.text)
+                except SDLError as e:
+                    logger.error(u'Rendering of label ā€œ%sā€ failed: %s', label.text, e)
+                    del labels[i]  # Prevents it from retrying to render.
+                    continue
+
+                label.width, label.height = surface.surface.w, surface.surface.h
+
+                if label.align == 'center':
+                    label.x -= label.width // 2
+                elif label.align == 'right':
+                    label.x -= label.width
+                else:
+                    assert label.align == 'left'
+
+                label.texture = self.window.create_texture_from_surface(surface)
+
+
 cdef Surface decode_png(loader, first_name, secondary_name):
     image_file = load_png(loader.get_file(os.path.basename(first_name)))
     width, height = image_file.surface.w, image_file.surface.h