https://github.com/akkartik/mu/blob/main/501draw-text.mu
1
2
3 fn move-cursor-left screen: (addr screen) {
4 var cursor-x/eax: int <- copy 0
5 var cursor-y/ecx: int <- copy 0
6 cursor-x, cursor-y <- cursor-position screen
7 compare cursor-x, 0
8 {
9 break-if->
10 return
11 }
12 cursor-x <- decrement
13 set-cursor-position screen, cursor-x, cursor-y
14 }
15
16 fn move-cursor-right screen: (addr screen) {
17 var _width/eax: int <- copy 0
18 var dummy/ecx: int <- copy 0
19 _width, dummy <- screen-size screen
20 var limit/edx: int <- copy _width
21 limit <- decrement
22 var cursor-x/eax: int <- copy 0
23 var cursor-y/ecx: int <- copy 0
24 cursor-x, cursor-y <- cursor-position screen
25 compare cursor-x, limit
26 {
27 break-if-<
28 return
29 }
30 cursor-x <- increment
31 set-cursor-position screen, cursor-x, cursor-y
32 }
33
34 fn move-cursor-up screen: (addr screen) {
35 var cursor-x/eax: int <- copy 0
36 var cursor-y/ecx: int <- copy 0
37 cursor-x, cursor-y <- cursor-position screen
38 compare cursor-y, 0
39 {
40 break-if->
41 return
42 }
43 cursor-y <- decrement
44 set-cursor-position screen, cursor-x, cursor-y
45 }
46
47 fn move-cursor-down screen: (addr screen) {
48 var dummy/eax: int <- copy 0
49 var _height/ecx: int <- copy 0
50 dummy, _height <- screen-size screen
51 var limit/edx: int <- copy _height
52 limit <- decrement
53 var cursor-x/eax: int <- copy 0
54 var cursor-y/ecx: int <- copy 0
55 cursor-x, cursor-y <- cursor-position screen
56 compare cursor-y, limit
57 {
58 break-if-<
59 return
60 }
61 cursor-y <- increment
62 set-cursor-position screen, cursor-x, cursor-y
63 }
64
65 fn move-cursor-to-left-margin-of-next-line screen: (addr screen) {
66 var dummy/eax: int <- copy 0
67 var _height/ecx: int <- copy 0
68 dummy, _height <- screen-size screen
69 var limit/edx: int <- copy _height
70 limit <- decrement
71 var cursor-x/eax: int <- copy 0
72 var cursor-y/ecx: int <- copy 0
73 cursor-x, cursor-y <- cursor-position screen
74 compare cursor-y, limit
75 {
76 break-if-<
77 return
78 }
79 cursor-y <- increment
80 cursor-x <- copy 0
81 set-cursor-position screen, cursor-x, cursor-y
82 }
83
84 fn draw-grapheme-at-cursor screen: (addr screen), g: grapheme, color: int, background-color: int {
85 var cursor-x/eax: int <- copy 0
86 var cursor-y/ecx: int <- copy 0
87 cursor-x, cursor-y <- cursor-position screen
88 draw-grapheme screen, g, cursor-x, cursor-y, color, background-color
89 }
90
91
92 fn draw-code-point-at-cursor screen: (addr screen), c: code-point, color: int, background-color: int {
93 var g/eax: grapheme <- copy c
94 draw-grapheme-at-cursor screen, g, color, background-color
95 }
96
97
98
99
100 fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int {
101 var stream-storage: (stream byte 0x100)
102 var stream/esi: (addr stream byte) <- address stream-storage
103 write stream, text
104 var xcurr/eax: int <- draw-stream-rightward screen, stream, x, xmax, y, color, background-color
105 return xcurr
106 }
107
108
109
110
111 fn draw-stream-rightward screen: (addr screen), stream: (addr stream byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int {
112 var xcurr/ecx: int <- copy x
113 {
114 var g/eax: grapheme <- read-grapheme stream
115 compare g, 0xffffffff/end-of-file
116 break-if-=
117 draw-grapheme screen, g, xcurr, y, color, background-color
118 xcurr <- increment
119 loop
120 }
121 set-cursor-position screen, xcurr, y
122 return xcurr
123 }
124
125 fn draw-text-rightward-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int {
126 var width/eax: int <- copy 0
127 var height/ecx: int <- copy 0
128 width, height <- screen-size screen
129 var result/eax: int <- draw-text-rightward screen, text, x, width, y, color, background-color
130 return result
131 }
132
133 fn draw-text-rightward-from-cursor screen: (addr screen), text: (addr array byte), xmax: int, color: int, background-color: int {
134 var cursor-x/eax: int <- copy 0
135 var cursor-y/ecx: int <- copy 0
136 cursor-x, cursor-y <- cursor-position screen
137 cursor-x <- draw-text-rightward screen, text, cursor-x, xmax, cursor-y, color, background-color
138 set-cursor-position screen, cursor-x, cursor-y
139 }
140
141 fn render-grapheme screen: (addr screen), g: grapheme, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
142 compare g, 0xa/newline
143 var x/eax: int <- copy x
144 {
145 break-if-!=
146
147 draw-code-point screen, 0x20/space, x, y, color, background-color
148 x <- copy xmin
149 increment y
150 return x, y
151 }
152 draw-grapheme screen, g, x, y, color, background-color
153 x <- increment
154 compare x, xmax
155 {
156 break-if-<
157 x <- copy xmin
158 increment y
159 }
160 return x, y
161 }
162
163
164
165
166
167 fn draw-text-wrapping-right-then-down screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
168 var stream-storage: (stream byte 0x100)
169 var stream/esi: (addr stream byte) <- address stream-storage
170 write stream, text
171 var x/eax: int <- copy _x
172 var y/ecx: int <- copy _y
173 x, y <- draw-stream-wrapping-right-then-down screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color
174 return x, y
175 }
176
177
178
179
180
181 fn draw-stream-wrapping-right-then-down screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
182 var xcurr/eax: int <- copy x
183 var ycurr/ecx: int <- copy y
184 var g/ebx: grapheme <- copy 0
185 {
186 {
187 var _g/eax: grapheme <- read-grapheme stream
188 g <- copy _g
189 }
190 compare g, 0xffffffff/end-of-file
191 break-if-=
192 xcurr, ycurr <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
193 loop
194 }
195 set-cursor-position screen, xcurr, ycurr
196 return xcurr, ycurr
197 }
198
199 fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: int {
200 var cursor-x/eax: int <- copy 0
201 var cursor-y/ecx: int <- copy 0
202 cursor-x, cursor-y <- cursor-position screen
203 cursor-x <- increment
204 compare cursor-x, xmax
205 {
206 break-if-<
207 cursor-x <- copy xmin
208 cursor-y <- increment
209 }
210 set-cursor-position screen, cursor-x, cursor-y
211 }
212
213 fn draw-text-wrapping-right-then-down-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
214 var x2/eax: int <- copy 0
215 var y2/ecx: int <- copy 0
216 x2, y2 <- screen-size screen
217 x2, y2 <- draw-text-wrapping-right-then-down screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
218 return x2, y2
219 }
220
221 fn draw-text-wrapping-right-then-down-from-cursor screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int {
222 var cursor-x/eax: int <- copy 0
223 var cursor-y/ecx: int <- copy 0
224 cursor-x, cursor-y <- cursor-position screen
225 var end-x/edx: int <- copy cursor-x
226 end-x <- increment
227 compare end-x, xmax
228 {
229 break-if-<
230 cursor-x <- copy xmin
231 cursor-y <- increment
232 }
233 cursor-x, cursor-y <- draw-text-wrapping-right-then-down screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
234 }
235
236 fn draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
237 var width/eax: int <- copy 0
238 var height/ecx: int <- copy 0
239 width, height <- screen-size screen
240 draw-text-wrapping-right-then-down-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
241 }
242
243 fn draw-int32-hex-wrapping-right-then-down screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
244 var stream-storage: (stream byte 0x100)
245 var stream/esi: (addr stream byte) <- address stream-storage
246 write-int32-hex stream, n
247 var xcurr/edx: int <- copy x
248 var ycurr/ecx: int <- copy y
249 {
250 var g/eax: grapheme <- read-grapheme stream
251 compare g, 0xffffffff/end-of-file
252 break-if-=
253 draw-grapheme screen, g, xcurr, ycurr, color, background-color
254 xcurr <- increment
255 compare xcurr, xmax
256 {
257 break-if-<
258 xcurr <- copy xmin
259 ycurr <- increment
260 }
261 loop
262 }
263 set-cursor-position screen, xcurr, ycurr
264 return xcurr, ycurr
265 }
266
267 fn draw-int32-hex-wrapping-right-then-down-over-full-screen screen: (addr screen), n: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
268 var x2/eax: int <- copy 0
269 var y2/ecx: int <- copy 0
270 x2, y2 <- screen-size screen
271 x2, y2 <- draw-int32-hex-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
272 return x2, y2
273 }
274
275 fn draw-int32-hex-wrapping-right-then-down-from-cursor screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int {
276 var cursor-x/eax: int <- copy 0
277 var cursor-y/ecx: int <- copy 0
278 cursor-x, cursor-y <- cursor-position screen
279 var end-x/edx: int <- copy cursor-x
280 end-x <- increment
281 compare end-x, xmax
282 {
283 break-if-<
284 cursor-x <- copy xmin
285 cursor-y <- increment
286 }
287 cursor-x, cursor-y <- draw-int32-hex-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
288 }
289
290 fn draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
291 var width/eax: int <- copy 0
292 var height/ecx: int <- copy 0
293 width, height <- screen-size screen
294 draw-int32-hex-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
295 }
296
297 fn draw-int32-decimal-wrapping-right-then-down screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
298 var stream-storage: (stream byte 0x100)
299 var stream/esi: (addr stream byte) <- address stream-storage
300 write-int32-decimal stream, n
301 var xcurr/edx: int <- copy x
302 var ycurr/ecx: int <- copy y
303 {
304 var g/eax: grapheme <- read-grapheme stream
305 compare g, 0xffffffff/end-of-file
306 break-if-=
307 draw-grapheme screen, g, xcurr, ycurr, color, background-color
308 xcurr <- increment
309 compare xcurr, xmax
310 {
311 break-if-<
312 xcurr <- copy xmin
313 ycurr <- increment
314 }
315 loop
316 }
317 set-cursor-position screen, xcurr, ycurr
318 return xcurr, ycurr
319 }
320
321 fn draw-int32-decimal-wrapping-right-then-down-over-full-screen screen: (addr screen), n: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
322 var x2/eax: int <- copy 0
323 var y2/ecx: int <- copy 0
324 x2, y2 <- screen-size screen
325 x2, y2 <- draw-int32-decimal-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
326 return x2, y2
327 }
328
329 fn draw-int32-decimal-wrapping-right-then-down-from-cursor screen: (addr screen), n: int, xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int {
330 var cursor-x/eax: int <- copy 0
331 var cursor-y/ecx: int <- copy 0
332 cursor-x, cursor-y <- cursor-position screen
333 var end-x/edx: int <- copy cursor-x
334 end-x <- increment
335 compare end-x, xmax
336 {
337 break-if-<
338 cursor-x <- copy xmin
339 cursor-y <- increment
340 }
341 cursor-x, cursor-y <- draw-int32-decimal-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
342 }
343
344 fn draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
345 var width/eax: int <- copy 0
346 var height/ecx: int <- copy 0
347 width, height <- screen-size screen
348 draw-int32-decimal-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
349 }
350
351
352
353
354
355
356 fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
357 var stream-storage: (stream byte 0x100)
358 var stream/esi: (addr stream byte) <- address stream-storage
359 write stream, text
360 var ycurr/eax: int <- draw-stream-downward screen, stream, x, y, ymax, color, background-color
361 return ycurr
362 }
363
364
365
366
367 fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
368 var ycurr/ecx: int <- copy y
369 {
370 var g/eax: grapheme <- read-grapheme stream
371 compare g, 0xffffffff/end-of-file
372 break-if-=
373 draw-grapheme screen, g, x, ycurr, color, background-color
374 ycurr <- increment
375 loop
376 }
377 set-cursor-position screen, x, ycurr
378 return ycurr
379 }
380
381 fn draw-text-downward-from-cursor screen: (addr screen), text: (addr array byte), ymax: int, color: int, background-color: int {
382 var cursor-x/eax: int <- copy 0
383 var cursor-y/ecx: int <- copy 0
384 cursor-x, cursor-y <- cursor-position screen
385 var result/eax: int <- draw-text-downward screen, text, cursor-x, cursor-y, ymax, color, background-color
386 }
387
388
389
390
391
392 fn draw-text-wrapping-down-then-right screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, _x: int, _y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
393 var stream-storage: (stream byte 0x100)
394 var stream/esi: (addr stream byte) <- address stream-storage
395 write stream, text
396 var x/eax: int <- copy _x
397 var y/ecx: int <- copy _y
398 x, y <- draw-stream-wrapping-down-then-right screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color
399 return x, y
400 }
401
402
403
404
405
406 fn draw-stream-wrapping-down-then-right screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
407 var xcurr/edx: int <- copy x
408 var ycurr/ecx: int <- copy y
409 {
410 var g/eax: grapheme <- read-grapheme stream
411 compare g, 0xffffffff/end-of-file
412 break-if-=
413 draw-grapheme screen, g, xcurr, ycurr, color, background-color
414 ycurr <- increment
415 compare ycurr, ymax
416 {
417 break-if-<
418 xcurr <- increment
419 ycurr <- copy ymin
420 }
421 loop
422 }
423 set-cursor-position screen, xcurr, ycurr
424 return xcurr, ycurr
425 }
426
427 fn draw-text-wrapping-down-then-right-over-full-screen screen: (addr screen), text: (addr array byte), x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
428 var x2/eax: int <- copy 0
429 var y2/ecx: int <- copy 0
430 x2, y2 <- screen-size screen
431 x2, y2 <- draw-text-wrapping-down-then-right screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
432 return x2, y2
433 }
434
435 fn draw-text-wrapping-down-then-right-from-cursor screen: (addr screen), text: (addr array byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: int {
436 var cursor-x/eax: int <- copy 0
437 var cursor-y/ecx: int <- copy 0
438 cursor-x, cursor-y <- cursor-position screen
439 var end-y/edx: int <- copy cursor-y
440 end-y <- increment
441 compare end-y, ymax
442 {
443 break-if-<
444 cursor-x <- increment
445 cursor-y <- copy ymin
446 }
447 cursor-x, cursor-y <- draw-text-wrapping-down-then-right screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
448 }
449
450 fn draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
451 var width/eax: int <- copy 0
452 var height/ecx: int <- copy 0
453 width, height <- screen-size screen
454 draw-text-wrapping-down-then-right-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
455 }
456
457
458
459 fn abort e: (addr array byte) {
460 var dummy1/eax: int <- copy 0
461 var dummy2/ecx: int <- copy 0
462 dummy1, dummy2 <- draw-text-wrapping-right-then-down-over-full-screen 0/screen, e, 0/x, 0x2f/y, 0xf/fg=white, 0xc/bg=red
463 {
464 loop
465 }
466 }