gamnit: extract general Font from TileSetFont
authorAlexis Laferrière <alexis.laf@xymus.net>
Mon, 22 May 2017 17:51:16 +0000 (10:51 -0700)
committerAlexis Laferrière <alexis.laf@xymus.net>
Tue, 23 May 2017 16:30:23 +0000 (09:30 -0700)
Signed-off-by: Alexis Laferrière <alexis.laf@xymus.net>

lib/gamnit/font.nit [new file with mode: 0644]
lib/gamnit/tileset.nit

diff --git a/lib/gamnit/font.nit b/lib/gamnit/font.nit
new file mode 100644 (file)
index 0000000..8a5defe
--- /dev/null
@@ -0,0 +1,82 @@
+# This file is part of NIT ( http://www.nitlanguage.org ).
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+#     http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+# Abstract font drawing services, implemented by `bmfont` and `tileset`
+module font
+
+import flat
+
+# Abstract font, drawn by a `TextSprites`
+abstract class Font
+
+       # Line spacing modifier for `pld` and `plu`
+       #
+       # This value acts as multiplier to the standard line height.
+       # Defaults to 0.4, so a `pld` moves chars down by about half a line.
+       var partial_line_mod: Numeric = 0.4 is writable
+
+       # Backend writing service, clients should use `TextSprites.text=`
+       protected fun write_into(text_sprites: TextSprites, text: Text) is abstract
+end
+
+# Manage a set of sprites to display some text
+class TextSprites
+
+       # Font used to draw text
+       var font: Font
+
+       # Top left of the first character in UI coordinates
+       var anchor: Point3d[Float]
+
+       # Last set of sprites generated to display `text=`
+       var sprites = new Array[Sprite]
+
+       # Sprite set where to put created sprites
+       #
+       # Defaults to `app::ui_sprites`, but it could also be set to a
+       # `app::sprites` or a custom collection.
+       var target_sprite_set: Set[Sprite] = app.ui_sprites is lazy, writable
+
+       private var cached_text: nullable Text = ""
+
+       # Last text drawn
+       fun text: nullable Text do return cached_text
+
+       # Update the text displayed by inserting new sprites into `app.ui_sprites`
+       #
+       # Does not redraw if `text` has not changed.
+       fun text=(text: nullable Text)
+       is autoinit do
+               # Don't redraw if text hasn't changed
+               if text == cached_text then return
+               cached_text = text
+
+               # Clean up last used sprites
+               for s in sprites do if target_sprite_set.has(s) then target_sprite_set.remove s
+               sprites.clear
+
+               if text == null then return
+
+               font.write_into(self, text)
+
+               # Register sprites to be drawn by `app.ui_camera`
+               target_sprite_set.add_all sprites
+       end
+end
+
+# Partial line forward (U+008B)
+fun pld: Char do return '\8b'
+
+# Partial line backward (U+008C)
+fun plu: Char do return '\8c'
index ecb40a2..1a784ae 100644 (file)
@@ -15,7 +15,7 @@
 # Support for `TileSet`, `TileSetFont` and drawing text with `TextSprites`
 module tileset
 
-import flat
+import font
 
 # Efficiently retrieve tiles in a big texture
 class TileSet
@@ -60,6 +60,7 @@ end
 # A monospace bitmap font where glyphs are stored in a tileset
 class TileSetFont
        super TileSet
+       super Font
 
        # Set the characters present in `texture`
        #
@@ -83,12 +84,6 @@ class TileSetFont
        # A negative value may display overlapped tiles.
        var vspace: Numeric = 0.0 is writable
 
-       # Line spacing modifier for `pld` and `plu`
-       #
-       # This value acts as multiplier to `height + vspace`.
-       # Defaults to 0.4, so a `pld` moves chars down by about half a line.
-       var partial_line_mod: Numeric = 0.4 is writable
-
        # The glyph/tile/texture associated to `char`
        #
        # Returns null if `char` is not in `chars`.
@@ -122,83 +117,37 @@ class TileSetFont
                var n_lines = text.chars.count('\n')
                return (n_lines+1).mul(height.add(vspace)).sub(vspace)
        end
-end
-
-# Manage a set of sprites to display some text
-class TextSprites
-
-       # Font used to draw text
-       var font: TileSetFont
-
-       # Top left of the first character in UI coordinates
-       var anchor: Point3d[Float]
-
-       # Last set of sprites generated to display `text=`
-       var sprites = new Array[Sprite]
-
-       # Sprite set where to put created sprites
-       #
-       # Defaults to `app::ui_sprites`, but it could also be set to a
-       # `app::sprites` or a custom collection.
-       var target_sprite_set: Set[Sprite] = app.ui_sprites is lazy, writable
-
-       private var cached_text: nullable Text = ""
-
-       # Last text drawn
-       fun text: nullable Text do return cached_text
-
-       # Update the text displayed by inserting new sprites into `app.ui_sprites`
-       #
-       # Does not redraw if `text` has not changed.
-       fun text=(text: nullable Text)
-       is autoinit do
-               # Don't redraw if text hasn't changed
-               if text == cached_text then return
-               cached_text = text
-
-               # Clean up last used sprites
-               for s in sprites do if target_sprite_set.has(s) then target_sprite_set.remove s
-               sprites.clear
-
-               if text == null then return
 
+       redef fun write_into(text_sprites, text)
+       do
                # Build new sprites
-               var dx = font.advance/2.0
-               var dy = font.hspace.to_f/2.0
+               var dx = advance/2.0
+               var dy = hspace.to_f/2.0
                for c in text do
                        if c == '\n' then
-                               dy -= font.height.to_f + font.vspace.to_f
-                               dx = font.advance/2.0
+                               dy -= height.to_f + vspace.to_f
+                               dx = advance/2.0
                                continue
                        else if c == pld then
-                               dy -= (font.height.to_f + font.vspace.to_f) * font.partial_line_mod.to_f
+                               dy -= (height.to_f + vspace.to_f) * partial_line_mod.to_f
                                continue
                        else if c == plu then
-                               dy += (font.height.to_f + font.vspace.to_f) * font.partial_line_mod.to_f
+                               dy += (height.to_f + vspace.to_f) * partial_line_mod.to_f
                                continue
                        else if c.is_whitespace then
-                               dx += font.advance
+                               dx += advance
                                continue
                        end
 
-                       var tex = font.char(c)
+                       var tex = char(c)
                        if tex == null then
                                # Try to fallback to '?'
-                               tex = font.char('?')
+                               tex = char('?')
                                if tex == null then continue
                        end
 
-                       sprites.add new Sprite(tex, anchor.offset(dx, dy, 0))
-                       dx += font.advance
+                       text_sprites.sprites.add new Sprite(tex, text_sprites.anchor.offset(dx, dy, 0))
+                       dx += advance
                end
-
-               # Register sprites to be drawn by `app.ui_camera`
-               target_sprite_set.add_all sprites
        end
 end
-
-# Partial line forward (U+008B)
-fun pld: Char do return '\8b'
-
-# Partial line backward (U+008C)
-fun plu: Char do return '\8c'