From 34d8bdf346072debbffe5255b443d81c591f00d1 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Alexis=20Laferri=C3=A8re?= Date: Mon, 22 May 2017 10:51:16 -0700 Subject: [PATCH] gamnit: extract general Font from TileSetFont MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Signed-off-by: Alexis Laferrière --- lib/gamnit/font.nit | 82 ++++++++++++++++++++++++++++++++++++++++++++++++ lib/gamnit/tileset.nit | 81 +++++++++-------------------------------------- 2 files changed, 97 insertions(+), 66 deletions(-) create mode 100644 lib/gamnit/font.nit diff --git a/lib/gamnit/font.nit b/lib/gamnit/font.nit new file mode 100644 index 0000000..8a5defe --- /dev/null +++ b/lib/gamnit/font.nit @@ -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 '‹' + +# Partial line backward (U+008C) +fun plu: Char do return 'Œ' diff --git a/lib/gamnit/tileset.nit b/lib/gamnit/tileset.nit index ecb40a2..1a784ae 100644 --- a/lib/gamnit/tileset.nit +++ b/lib/gamnit/tileset.nit @@ -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 '‹' - -# Partial line backward (U+008C) -fun plu: Char do return 'Œ' -- 1.7.9.5