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