lib/tileset: fix typos in doc
[nit.git] / lib / mnit / tileset.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License");
4 # you may not use this file except in compliance with the License.
5 # You may obtain a copy of the License at
6 #
7 # http://www.apache.org/licenses/LICENSE-2.0
8 #
9 # Unless required by applicable law or agreed to in writing, software
10 # distributed under the License is distributed on an "AS IS" BASIS,
11 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 # See the License for the specific language governing permissions and
13 # limitations under the License.
14
15 # Manage images that are tileset or glyphset (for bitmap fonts)
16 module tileset
17
18 import mnit_display
19
20 # Efficiently retrieve tiles in a big image
21 class TileSet
22 # The image containing the tileset
23 var image: Image
24
25 # The witdh of a tile
26 var width: Int
27
28 # The height of a tile
29 var height: Int
30
31 init
32 do
33 self.nb_cols = image.width / width
34 self.nb_rows = image.height / height
35
36 for j in [0..nb_rows[ do
37 for i in [0..nb_cols[ do
38 subimages.add image.subimage(i*width,j*height,width,height)
39 end
40 end
41 end
42
43 # The number of columns of tiles in the image
44 var nb_cols: Int is noinit
45
46 # The number of rows of tiles in the image
47 var nb_rows: Int is noinit
48
49 # Cache for images of tiles
50 var subimages = new Array[Image]
51
52 # The subimage of given tile
53 # Aborts if x or y are out of bound
54 fun [](x,y: Int): Image
55 do
56 assert x >= 0 and x < nb_cols and y >= 0 and y <= nb_rows else print "{x}x{y}<?{nb_cols}x{nb_rows}"
57 var idx = x + y * nb_cols
58 return subimages[idx]
59 end
60 end
61
62 # A monospace bitmap font where glyphs are stored in a tileset
63 class TileSetFont
64 super TileSet
65
66 # Each character in the image
67 # in left->right, then top->bottom order
68 # Use space (' ') for holes in the tileset
69 var chars: String
70
71 # Additional space to insert horizontally between characters
72 # A negative value will display tile overlapped
73 var hspace: Numeric = 0.0 is writable
74
75 # Additional space to insert vertically between characters
76 # A negative value will display tile overlapped
77 var vspace: Numeric = 0.0 is writable
78
79 # The glyph (tile) associated to the character `c` according to `chars`
80 # Returns null if `c` is not in `chars`
81 fun char(c: Char): nullable Image
82 do
83 var i = chars.index_of(c)
84 if i == -1 then return null
85 return subimages[i]
86 end
87
88 # Distance between the beginning of a letter tile and the beginning of the next letter tile
89 fun advance: Numeric do return width.add(hspace)
90
91 # Distance between the beginning and the end of the longest line of `text`
92 fun text_width(text: String): Numeric
93 do
94 var lines = text.split('\n')
95 if lines.is_empty then return 0
96
97 var longest = 0
98 for line in lines do longest = longest.max(line.length)
99
100 return longest.mul(advance)
101 end
102
103 # Distance between the top of the first line to the bottom of the last line in `text`
104 fun text_height(text: Text): Numeric
105 do
106 if text.is_empty then return 0
107
108 var n_lines = text.chars.count('\n')
109 return (n_lines+1).mul(height.add(vspace)).sub(vspace)
110 end
111 end
112
113 redef class Display
114 # Blit the text using a monospace bitmap font
115 # '\n' are rendered as carriage return
116 fun text(text: String, font: TileSetFont, x, y: Numeric)
117 do
118 x = x.to_f
119 var cx = x
120 var cy = y.to_f
121 var sw = font.width.to_f + font.hspace.to_f
122 var sh = font.height.to_f + font.vspace.to_f
123 for c in text.chars do
124 if c == '\n' then
125 cx = x
126 cy += sh
127 continue
128 end
129 if c == ' ' then
130 cx += sw
131 continue
132 end
133 var image = font.char(c)
134 if image != null then
135 blit(image, cx, cy)
136 end
137 cx += sw
138 end
139 end
140 end