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 draw-stream-wrapping-right-then-down-from-cursor screen: (addr screen), stream: (addr stream byte), xmin: int, ymin: int, xmax: int, ymax: int, color: int, background-color: 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 var end-x/edx: int <- copy cursor-x
204 end-x <- increment
205 compare end-x, xmax
206 {
207 break-if-<
208 cursor-x <- copy xmin
209 cursor-y <- increment
210 }
211 cursor-x, cursor-y <- draw-stream-wrapping-right-then-down screen, stream, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
212 }
213
214 fn draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), stream: (addr stream byte), color: int, background-color: int {
215 var width/eax: int <- copy 0
216 var height/ecx: int <- copy 0
217 width, height <- screen-size screen
218 draw-stream-wrapping-right-then-down-from-cursor screen, stream, 0/xmin, 0/ymin, width, height, color, background-color
219 }
220
221 fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: 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 cursor-x <- increment
226 compare cursor-x, xmax
227 {
228 break-if-<
229 cursor-x <- copy xmin
230 cursor-y <- increment
231 }
232 set-cursor-position screen, cursor-x, cursor-y
233 }
234
235 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 {
236 var x2/eax: int <- copy 0
237 var y2/ecx: int <- copy 0
238 x2, y2 <- screen-size screen
239 x2, y2 <- draw-text-wrapping-right-then-down screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
240 return x2, y2
241 }
242
243 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 {
244 var cursor-x/eax: int <- copy 0
245 var cursor-y/ecx: int <- copy 0
246 cursor-x, cursor-y <- cursor-position screen
247 var end-x/edx: int <- copy cursor-x
248 end-x <- increment
249 compare end-x, xmax
250 {
251 break-if-<
252 cursor-x <- copy xmin
253 cursor-y <- increment
254 }
255 cursor-x, cursor-y <- draw-text-wrapping-right-then-down screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
256 }
257
258 fn draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
259 var width/eax: int <- copy 0
260 var height/ecx: int <- copy 0
261 width, height <- screen-size screen
262 draw-text-wrapping-right-then-down-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
263 }
264
265 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 {
266 var stream-storage: (stream byte 0x100)
267 var stream/esi: (addr stream byte) <- address stream-storage
268 write-int32-hex stream, n
269 var xcurr/edx: int <- copy x
270 var ycurr/ecx: int <- copy y
271 {
272 var g/eax: grapheme <- read-grapheme stream
273 compare g, 0xffffffff/end-of-file
274 break-if-=
275 draw-grapheme screen, g, xcurr, ycurr, color, background-color
276 xcurr <- increment
277 compare xcurr, xmax
278 {
279 break-if-<
280 xcurr <- copy xmin
281 ycurr <- increment
282 }
283 loop
284 }
285 set-cursor-position screen, xcurr, ycurr
286 return xcurr, ycurr
287 }
288
289 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 {
290 var x2/eax: int <- copy 0
291 var y2/ecx: int <- copy 0
292 x2, y2 <- screen-size screen
293 x2, y2 <- draw-int32-hex-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
294 return x2, y2
295 }
296
297 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 {
298 var cursor-x/eax: int <- copy 0
299 var cursor-y/ecx: int <- copy 0
300 cursor-x, cursor-y <- cursor-position screen
301 var end-x/edx: int <- copy cursor-x
302 end-x <- increment
303 compare end-x, xmax
304 {
305 break-if-<
306 cursor-x <- copy xmin
307 cursor-y <- increment
308 }
309 cursor-x, cursor-y <- draw-int32-hex-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
310 }
311
312 fn draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
313 var width/eax: int <- copy 0
314 var height/ecx: int <- copy 0
315 width, height <- screen-size screen
316 draw-int32-hex-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
317 }
318
319 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 {
320 var stream-storage: (stream byte 0x100)
321 var stream/esi: (addr stream byte) <- address stream-storage
322 write-int32-decimal stream, n
323 var xcurr/edx: int <- copy x
324 var ycurr/ecx: int <- copy y
325 {
326 var g/eax: grapheme <- read-grapheme stream
327 compare g, 0xffffffff/end-of-file
328 break-if-=
329 draw-grapheme screen, g, xcurr, ycurr, color, background-color
330 xcurr <- increment
331 compare xcurr, xmax
332 {
333 break-if-<
334 xcurr <- copy xmin
335 ycurr <- increment
336 }
337 loop
338 }
339 set-cursor-position screen, xcurr, ycurr
340 return xcurr, ycurr
341 }
342
343 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 {
344 var x2/eax: int <- copy 0
345 var y2/ecx: int <- copy 0
346 x2, y2 <- screen-size screen
347 x2, y2 <- draw-int32-decimal-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
348 return x2, y2
349 }
350
351 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 {
352 var cursor-x/eax: int <- copy 0
353 var cursor-y/ecx: int <- copy 0
354 cursor-x, cursor-y <- cursor-position screen
355 var end-x/edx: int <- copy cursor-x
356 end-x <- increment
357 compare end-x, xmax
358 {
359 break-if-<
360 cursor-x <- copy xmin
361 cursor-y <- increment
362 }
363 cursor-x, cursor-y <- draw-int32-decimal-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
364 }
365
366 fn draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
367 var width/eax: int <- copy 0
368 var height/ecx: int <- copy 0
369 width, height <- screen-size screen
370 draw-int32-decimal-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
371 }
372
373
374
375
376
377
378 fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
379 var stream-storage: (stream byte 0x100)
380 var stream/esi: (addr stream byte) <- address stream-storage
381 write stream, text
382 var ycurr/eax: int <- draw-stream-downward screen, stream, x, y, ymax, color, background-color
383 return ycurr
384 }
385
386
387
388
389 fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
390 var ycurr/ecx: int <- copy y
391 {
392 var g/eax: grapheme <- read-grapheme stream
393 compare g, 0xffffffff/end-of-file
394 break-if-=
395 draw-grapheme screen, g, x, ycurr, color, background-color
396 ycurr <- increment
397 loop
398 }
399 set-cursor-position screen, x, ycurr
400 return ycurr
401 }
402
403 fn draw-text-downward-from-cursor screen: (addr screen), text: (addr array byte), ymax: int, color: int, background-color: int {
404 var cursor-x/eax: int <- copy 0
405 var cursor-y/ecx: int <- copy 0
406 cursor-x, cursor-y <- cursor-position screen
407 var result/eax: int <- draw-text-downward screen, text, cursor-x, cursor-y, ymax, color, background-color
408 }
409
410
411
412
413
414 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 {
415 var stream-storage: (stream byte 0x100)
416 var stream/esi: (addr stream byte) <- address stream-storage
417 write stream, text
418 var x/eax: int <- copy _x
419 var y/ecx: int <- copy _y
420 x, y <- draw-stream-wrapping-down-then-right screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color
421 return x, y
422 }
423
424
425
426
427
428 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 {
429 var xcurr/edx: int <- copy x
430 var ycurr/ecx: int <- copy y
431 {
432 var g/eax: grapheme <- read-grapheme stream
433 compare g, 0xffffffff/end-of-file
434 break-if-=
435 draw-grapheme screen, g, xcurr, ycurr, color, background-color
436 ycurr <- increment
437 compare ycurr, ymax
438 {
439 break-if-<
440 xcurr <- increment
441 ycurr <- copy ymin
442 }
443 loop
444 }
445 set-cursor-position screen, xcurr, ycurr
446 return xcurr, ycurr
447 }
448
449 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 {
450 var x2/eax: int <- copy 0
451 var y2/ecx: int <- copy 0
452 x2, y2 <- screen-size screen
453 x2, y2 <- draw-text-wrapping-down-then-right screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
454 return x2, y2
455 }
456
457 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 {
458 var cursor-x/eax: int <- copy 0
459 var cursor-y/ecx: int <- copy 0
460 cursor-x, cursor-y <- cursor-position screen
461 var end-y/edx: int <- copy cursor-y
462 end-y <- increment
463 compare end-y, ymax
464 {
465 break-if-<
466 cursor-x <- increment
467 cursor-y <- copy ymin
468 }
469 cursor-x, cursor-y <- draw-text-wrapping-down-then-right screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
470 }
471
472 fn draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
473 var width/eax: int <- copy 0
474 var height/ecx: int <- copy 0
475 width, height <- screen-size screen
476 draw-text-wrapping-down-then-right-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
477 }
478
479
480
481 fn abort e: (addr array byte) {
482 var dummy1/eax: int <- copy 0
483 var dummy2/ecx: int <- copy 0
484 dummy1, dummy2 <- draw-text-wrapping-right-then-down-over-full-screen 0/screen, e, 0/x, 0x2f/y, 0xf/fg=white, 0xc/bg=red
485 {
486 loop
487 }
488 }