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-code-point-at-cursor-over-full-screen screen: (addr screen), c: code-point, 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 var _offset/eax: int <- draw-code-point screen, c, cursor-x, cursor-y, color, background-color
89 var offset/edx: int <- copy _offset
90 var width/eax: int <- copy 0
91 var dummy/ecx: int <- copy 0
92 width, dummy <- screen-size screen
93 move-cursor-rightward-and-downward screen, 0 width
94 offset <- decrement
95 compare offset, 0
96 {
97 break-if-=
98
99 move-cursor-rightward-and-downward screen, 0 width
100 }
101 }
102
103
104
105
106 fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int {
107 var stream-storage: (stream byte 0x400/print-buffer-size)
108 var stream/esi: (addr stream byte) <- address stream-storage
109 write stream, text
110 var xcurr/eax: int <- draw-stream-rightward screen, stream, x, xmax, y, color, background-color
111 return xcurr
112 }
113
114
115
116
117 fn draw-stream-rightward screen: (addr screen), stream: (addr stream byte), x: int, xmax: int, y: int, color: int, background-color: int -> _/eax: int {
118 var xcurr/ecx: int <- copy x
119 {
120 var g/eax: code-point-utf8 <- read-code-point-utf8 stream
121 compare g, 0xffffffff/end-of-file
122 break-if-=
123 var c/eax: code-point <- to-code-point g
124 var offset/eax: int <- draw-code-point screen, c, xcurr, y, color, background-color
125 xcurr <- add offset
126 loop
127 }
128 set-cursor-position screen, xcurr, y
129 return xcurr
130 }
131
132 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 {
133 var width/eax: int <- copy 0
134 var height/ecx: int <- copy 0
135 width, height <- screen-size screen
136 var result/eax: int <- draw-text-rightward screen, text, x, width, y, color, background-color
137 return result
138 }
139
140 fn draw-text-rightward-from-cursor screen: (addr screen), text: (addr array byte), xmax: int, color: int, background-color: int {
141 var cursor-x/eax: int <- copy 0
142 var cursor-y/ecx: int <- copy 0
143 cursor-x, cursor-y <- cursor-position screen
144 cursor-x <- draw-text-rightward screen, text, cursor-x, xmax, cursor-y, color, background-color
145 set-cursor-position screen, cursor-x, cursor-y
146 }
147
148 fn draw-text-rightward-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
149 var width/eax: int <- copy 0
150 var height/ecx: int <- copy 0
151 width, height <- screen-size screen
152 draw-text-rightward-from-cursor screen, text, width, color, background-color
153 }
154
155 fn render-code-point screen: (addr screen), c: code-point, xmin: int, ymin: int, xmax: int, ymax: int, x: int, y: int, color: int, background-color: int -> _/eax: int, _/ecx: int {
156 var x/ecx: int <- copy x
157 compare c, 0xa/newline
158 {
159 break-if-!=
160
161 var dummy/eax: int <- draw-code-point screen, 0x20/space, x, y, color, background-color
162 x <- copy xmin
163 increment y
164 return x, y
165 }
166 var offset/eax: int <- draw-code-point screen, c, x, y, color, background-color
167 x <- add offset
168 compare x, xmax
169 {
170 break-if-<
171 x <- copy xmin
172 increment y
173 }
174 return x, y
175 }
176
177
178
179
180
181 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 {
182 var stream-storage: (stream byte 0x200/print-buffer-size)
183 var stream/edi: (addr stream byte) <- address stream-storage
184 var text/esi: (addr array byte) <- copy _text
185 var len/eax: int <- length text
186 compare len, 0x200/print-buffer-size
187 {
188 break-if-<
189 write stream, "ERROR: stream too small in draw-text-wrapping-right-then-down"
190 }
191 compare len, 0x200/print-buffer-size
192 {
193 break-if->=
194 write stream, text
195 }
196 var x/eax: int <- copy _x
197 var y/ecx: int <- copy _y
198 x, y <- draw-stream-wrapping-right-then-down screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color
199 return x, y
200 }
201
202
203
204
205
206 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 {
207 var xcurr/ecx: int <- copy x
208 var ycurr/edx: int <- copy y
209 var c/ebx: code-point <- copy 0
210 var next-c/esi: code-point <- copy 0
211 $draw-stream-wrapping-right-then-down:loop: {
212
213 $draw-stream-wrapping-right-then-down:read-base: {
214 compare next-c, 0
215 {
216 break-if-=
217 c <- copy next-c
218 next-c <- copy 0
219 break $draw-stream-wrapping-right-then-down:read-base
220 }
221 var g/eax: code-point-utf8 <- read-code-point-utf8 stream
222 var _c/eax: code-point <- to-code-point g
223 c <- copy _c
224 }
225 compare c, 0xffffffff/end-of-file
226 break-if-=
227 compare c, 0xa/newline
228 {
229 break-if-!=
230
231 var dummy/eax: int <- draw-code-point screen, 0x20/space, xcurr, ycurr, color, background-color
232 xcurr <- copy xmin
233 ycurr <- increment
234 loop $draw-stream-wrapping-right-then-down:loop
235 }
236 var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color
237
238 $draw-stream-wrapping-right-then-down:read-combiner: {
239 var done?/eax: boolean <- stream-empty? stream
240 compare done?, 0/false
241 break-if-!=
242
243 var g/eax: code-point-utf8 <- read-code-point-utf8 stream
244 var c/eax: code-point <- to-code-point g
245
246 {
247 var combining-code-point?/eax: boolean <- combining-code-point? c
248 compare combining-code-point?, 0/false
249 }
250 {
251 break-if-!=
252 next-c <- copy c
253 break $draw-stream-wrapping-right-then-down:read-combiner
254 }
255
256
257
258 var dummy/eax: int <- overlay-code-point screen, c, xcurr, ycurr, color, background-color
259 }
260 xcurr <- add offset
261 compare xcurr, xmax
262 {
263 break-if-<
264 xcurr <- copy xmin
265 ycurr <- increment
266 }
267 loop
268 }
269 set-cursor-position screen, xcurr, ycurr
270 return xcurr, ycurr
271 }
272
273 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 {
274 var cursor-x/eax: int <- copy 0
275 var cursor-y/ecx: int <- copy 0
276 cursor-x, cursor-y <- cursor-position screen
277 var end-x/edx: int <- copy cursor-x
278 end-x <- increment
279 compare end-x, xmax
280 {
281 break-if-<
282 cursor-x <- copy xmin
283 cursor-y <- increment
284 }
285 cursor-x, cursor-y <- draw-stream-wrapping-right-then-down screen, stream, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
286 }
287
288 fn draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), stream: (addr stream byte), color: int, background-color: int {
289 var width/eax: int <- copy 0
290 var height/ecx: int <- copy 0
291 width, height <- screen-size screen
292 draw-stream-wrapping-right-then-down-from-cursor screen, stream, 0/xmin, 0/ymin, width, height, color, background-color
293 }
294
295 fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: int {
296 var cursor-x/eax: int <- copy 0
297 var cursor-y/ecx: int <- copy 0
298 cursor-x, cursor-y <- cursor-position screen
299 cursor-x <- increment
300 compare cursor-x, xmax
301 {
302 break-if-<
303 cursor-x <- copy xmin
304 cursor-y <- increment
305 }
306 set-cursor-position screen, cursor-x, cursor-y
307 }
308
309 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 {
310 var x2/eax: int <- copy 0
311 var y2/ecx: int <- copy 0
312 x2, y2 <- screen-size screen
313 x2, y2 <- draw-text-wrapping-right-then-down screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
314 return x2, y2
315 }
316
317 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 {
318 var cursor-x/eax: int <- copy 0
319 var cursor-y/ecx: int <- copy 0
320 cursor-x, cursor-y <- cursor-position screen
321 var end-x/edx: int <- copy cursor-x
322 end-x <- increment
323 compare end-x, xmax
324 {
325 break-if-<
326 cursor-x <- copy xmin
327 cursor-y <- increment
328 }
329 cursor-x, cursor-y <- draw-text-wrapping-right-then-down screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
330 }
331
332 fn draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
333 var width/eax: int <- copy 0
334 var height/ecx: int <- copy 0
335 width, height <- screen-size screen
336 draw-text-wrapping-right-then-down-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
337 }
338
339 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 {
340 var stream-storage: (stream byte 0x100)
341 var stream/esi: (addr stream byte) <- address stream-storage
342 write-int32-hex stream, n
343 var xcurr/edx: int <- copy x
344 var ycurr/ecx: int <- copy y
345 {
346 var g/eax: code-point-utf8 <- read-code-point-utf8 stream
347 compare g, 0xffffffff/end-of-file
348 break-if-=
349 var c/eax: code-point <- to-code-point g
350 var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color
351 xcurr <- add offset
352 compare xcurr, xmax
353 {
354 break-if-<
355 xcurr <- copy xmin
356 ycurr <- increment
357 }
358 loop
359 }
360 set-cursor-position screen, xcurr, ycurr
361 return xcurr, ycurr
362 }
363
364 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 {
365 var x2/eax: int <- copy 0
366 var y2/ecx: int <- copy 0
367 x2, y2 <- screen-size screen
368 x2, y2 <- draw-int32-hex-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
369 return x2, y2
370 }
371
372 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 {
373 var cursor-x/eax: int <- copy 0
374 var cursor-y/ecx: int <- copy 0
375 cursor-x, cursor-y <- cursor-position screen
376 var end-x/edx: int <- copy cursor-x
377 end-x <- increment
378 compare end-x, xmax
379 {
380 break-if-<
381 cursor-x <- copy xmin
382 cursor-y <- increment
383 }
384 cursor-x, cursor-y <- draw-int32-hex-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
385 }
386
387 fn draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
388 var width/eax: int <- copy 0
389 var height/ecx: int <- copy 0
390 width, height <- screen-size screen
391 draw-int32-hex-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
392 }
393
394 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 {
395 var stream-storage: (stream byte 0x100)
396 var stream/esi: (addr stream byte) <- address stream-storage
397 write-int32-decimal stream, n
398 var xcurr/edx: int <- copy x
399 var ycurr/ecx: int <- copy y
400 {
401 var g/eax: code-point-utf8 <- read-code-point-utf8 stream
402 compare g, 0xffffffff/end-of-file
403 break-if-=
404 var c/eax: code-point <- to-code-point g
405 var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color
406 xcurr <- add offset
407 compare xcurr, xmax
408 {
409 break-if-<
410 xcurr <- copy xmin
411 ycurr <- increment
412 }
413 loop
414 }
415 set-cursor-position screen, xcurr, ycurr
416 return xcurr, ycurr
417 }
418
419 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 {
420 var x2/eax: int <- copy 0
421 var y2/ecx: int <- copy 0
422 x2, y2 <- screen-size screen
423 x2, y2 <- draw-int32-decimal-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
424 return x2, y2
425 }
426
427 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 {
428 var cursor-x/eax: int <- copy 0
429 var cursor-y/ecx: int <- copy 0
430 cursor-x, cursor-y <- cursor-position screen
431 var end-x/edx: int <- copy cursor-x
432 end-x <- increment
433 compare end-x, xmax
434 {
435 break-if-<
436 cursor-x <- copy xmin
437 cursor-y <- increment
438 }
439 cursor-x, cursor-y <- draw-int32-decimal-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
440 }
441
442 fn draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
443 var width/eax: int <- copy 0
444 var height/ecx: int <- copy 0
445 width, height <- screen-size screen
446 draw-int32-decimal-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
447 }
448
449
450
451
452
453
454 fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
455 var stream-storage: (stream byte 0x100)
456 var stream/esi: (addr stream byte) <- address stream-storage
457 write stream, text
458 var ycurr/eax: int <- draw-stream-downward screen, stream, x, y, ymax, color, background-color
459 return ycurr
460 }
461
462
463
464
465
466 fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
467 var ycurr/ecx: int <- copy y
468 {
469 var g/eax: code-point-utf8 <- read-code-point-utf8 stream
470 compare g, 0xffffffff/end-of-file
471 break-if-=
472 var c/eax: code-point <- to-code-point g
473 var dummy/eax: int <- draw-code-point screen, c, x, ycurr, color, background-color
474 ycurr <- increment
475 loop
476 }
477 set-cursor-position screen, x, ycurr
478 return ycurr
479 }
480
481 fn draw-text-downward-from-cursor screen: (addr screen), text: (addr array byte), ymax: int, color: int, background-color: int {
482 var cursor-x/eax: int <- copy 0
483 var cursor-y/ecx: int <- copy 0
484 cursor-x, cursor-y <- cursor-position screen
485 var result/eax: int <- draw-text-downward screen, text, cursor-x, cursor-y, ymax, color, background-color
486 }
487
488
489
490
491
492 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 {
493 var stream-storage: (stream byte 0x100)
494 var stream/esi: (addr stream byte) <- address stream-storage
495 write stream, text
496 var x/eax: int <- copy _x
497 var y/ecx: int <- copy _y
498 x, y <- draw-stream-wrapping-down-then-right screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color
499 return x, y
500 }
501
502
503
504
505
506
507 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 {
508 var xcurr/edx: int <- copy x
509 var ycurr/ecx: int <- copy y
510 {
511 var g/eax: code-point-utf8 <- read-code-point-utf8 stream
512 compare g, 0xffffffff/end-of-file
513 break-if-=
514 var c/eax: code-point <- to-code-point g
515 var offset/eax: int <- draw-code-point screen, c, xcurr, ycurr, color, background-color
516 ycurr <- increment
517 compare ycurr, ymax
518 {
519 break-if-<
520 xcurr <- add 2
521 ycurr <- copy ymin
522 }
523 loop
524 }
525 set-cursor-position screen, xcurr, ycurr
526 return xcurr, ycurr
527 }
528
529 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 {
530 var x2/eax: int <- copy 0
531 var y2/ecx: int <- copy 0
532 x2, y2 <- screen-size screen
533 x2, y2 <- draw-text-wrapping-down-then-right screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
534 return x2, y2
535 }
536
537 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 {
538 var cursor-x/eax: int <- copy 0
539 var cursor-y/ecx: int <- copy 0
540 cursor-x, cursor-y <- cursor-position screen
541 var end-y/edx: int <- copy cursor-y
542 end-y <- increment
543 compare end-y, ymax
544 {
545 break-if-<
546 cursor-x <- increment
547 cursor-y <- copy ymin
548 }
549 cursor-x, cursor-y <- draw-text-wrapping-down-then-right screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
550 }
551
552 fn draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
553 var width/eax: int <- copy 0
554 var height/ecx: int <- copy 0
555 width, height <- screen-size screen
556 draw-text-wrapping-down-then-right-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
557 }