# Manage images that are tileset or glyphset (for bitmap fonts)
module tileset
-import mnit_display
+import mnit::display
-# Efficienly retrieve tiles in a big image
+# Efficiently retrieve tiles in a big image
class TileSet
# The image containing the tileset
var image: Image
# The height of a tile
var height: Int
- init(image: Image, width: Int, height: Int)
+ init
do
- self.image = image
- self.width = width
- self.height = height
-
self.nb_cols = image.width / width
self.nb_rows = image.height / height
end
# The number of columns of tiles in the image
- var nb_cols: Int
+ var nb_cols: Int is noinit
# The number of rows of tiles in the image
- var nb_rows: Int
+ var nb_rows: Int is noinit
# Cache for images of tiles
var subimages = new Array[Image]
class TileSetFont
super TileSet
- # Each caracter in the image
+ # Each character in the image
# in left->right, then top->bottom order
# Use space (' ') for holes in the tileset
var chars: String
- init(image: Image, width: Int, height: Int, chars: String)
- do
- super
- self.chars = chars
- end
-
# Additional space to insert horizontally between characters
- # A negave value will display tile overlaped
- var hspace: Int = 0 is writable
+ # A negative value will display tile overlapped
+ var hspace: Numeric = 0.0 is writable
# Additional space to insert vertically between characters
- # A negave value will display tile overlaped
- var vspace: Int = 0 is writable
+ # A negative value will display tile overlapped
+ var vspace: Numeric = 0.0 is writable
- # The glyph (tile) associated to the caracter `c` according to `chars`
+ # The glyph (tile) associated to the character `c` according to `chars`
# Returns null if `c` is not in `chars`
fun char(c: Char): nullable Image
do
if i == -1 then return null
return subimages[i]
end
+
+ # Distance between the beginning of a letter tile and the beginning of the next letter tile
+ fun advance: Numeric do return width.add(hspace)
+
+ # Distance between the beginning and the end of the longest line of `text`
+ fun text_width(text: String): Numeric
+ do
+ var lines = text.split('\n')
+ if lines.is_empty then return 0
+
+ var longest = 0
+ for line in lines do longest = longest.max(line.length)
+
+ return longest.mul(advance)
+ end
+
+ # Distance between the top of the first line to the bottom of the last line in `text`
+ fun text_height(text: Text): Numeric
+ do
+ if text.is_empty then return 0
+
+ var n_lines = text.chars.count('\n')
+ return (n_lines+1).mul(height.add(vspace)).sub(vspace)
+ end
end
redef class Display
# Blit the text using a monospace bitmap font
# '\n' are rendered as carriage return
- fun text(text: String, font: TileSetFont, x, y: Int)
+ fun text(text: String, font: TileSetFont, x, y: Numeric)
do
+ x = x.to_f
var cx = x
- var cy = y
- var sw = font.width + font.hspace
- var sh = font.height + font.vspace
+ var cy = y.to_f
+ var sw = font.width.to_f + font.hspace.to_f
+ var sh = font.height.to_f + font.vspace.to_f
for c in text.chars do
if c == '\n' then
cx = x