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 0x200/print-buffer-size)
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 draw-text-rightward-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
142 var width/eax: int <- copy 0
143 var height/ecx: int <- copy 0
144 width, height <- screen-size screen
145 draw-text-rightward-from-cursor screen, text, width, color, background-color
146 }
147
148 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 {
149 compare g, 0xa/newline
150 var x/eax: int <- copy x
151 {
152 break-if-!=
153
154 draw-code-point screen, 0x20/space, x, y, color, background-color
155 x <- copy xmin
156 increment y
157 return x, y
158 }
159 draw-grapheme screen, g, x, y, color, background-color
160 x <- increment
161 compare x, xmax
162 {
163 break-if-<
164 x <- copy xmin
165 increment y
166 }
167 return x, y
168 }
169
170
171
172
173
174 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 {
175 var stream-storage: (stream byte 0x200/print-buffer-size)
176
177
178
179 var stream/edi: (addr stream byte) <- address stream-storage
180 var text/esi: (addr array byte) <- copy _text
181 var len/eax: int <- length text
182 compare len, 0x200
183 {
184 break-if-<
185 write stream, "ERROR: stream too small in draw-text-wrapping-right-then-down"
186 }
187 compare len, 0x200
188 {
189 break-if->=
190 write stream, text
191 }
192 var x/eax: int <- copy _x
193 var y/ecx: int <- copy _y
194 x, y <- draw-stream-wrapping-right-then-down screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color
195 return x, y
196 }
197
198
199
200
201
202 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 {
203 var xcurr/eax: int <- copy x
204 var ycurr/ecx: int <- copy y
205 var g/ebx: grapheme <- copy 0
206 {
207 {
208 var _g/eax: grapheme <- read-grapheme stream
209 g <- copy _g
210 }
211 compare g, 0xffffffff/end-of-file
212 break-if-=
213 xcurr, ycurr <- render-grapheme screen, g, xmin, ymin, xmax, ymax, xcurr, ycurr, color, background-color
214 loop
215 }
216 set-cursor-position screen, xcurr, ycurr
217 return xcurr, ycurr
218 }
219
220 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 {
221 var cursor-x/eax: int <- copy 0
222 var cursor-y/ecx: int <- copy 0
223 cursor-x, cursor-y <- cursor-position screen
224 var end-x/edx: int <- copy cursor-x
225 end-x <- increment
226 compare end-x, xmax
227 {
228 break-if-<
229 cursor-x <- copy xmin
230 cursor-y <- increment
231 }
232 cursor-x, cursor-y <- draw-stream-wrapping-right-then-down screen, stream, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
233 }
234
235 fn draw-stream-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), stream: (addr stream byte), color: int, background-color: int {
236 var width/eax: int <- copy 0
237 var height/ecx: int <- copy 0
238 width, height <- screen-size screen
239 draw-stream-wrapping-right-then-down-from-cursor screen, stream, 0/xmin, 0/ymin, width, height, color, background-color
240 }
241
242 fn move-cursor-rightward-and-downward screen: (addr screen), xmin: int, xmax: int {
243 var cursor-x/eax: int <- copy 0
244 var cursor-y/ecx: int <- copy 0
245 cursor-x, cursor-y <- cursor-position screen
246 cursor-x <- increment
247 compare cursor-x, xmax
248 {
249 break-if-<
250 cursor-x <- copy xmin
251 cursor-y <- increment
252 }
253 set-cursor-position screen, cursor-x, cursor-y
254 }
255
256 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 {
257 var x2/eax: int <- copy 0
258 var y2/ecx: int <- copy 0
259 x2, y2 <- screen-size screen
260 x2, y2 <- draw-text-wrapping-right-then-down screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
261 return x2, y2
262 }
263
264 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 {
265 var cursor-x/eax: int <- copy 0
266 var cursor-y/ecx: int <- copy 0
267 cursor-x, cursor-y <- cursor-position screen
268 var end-x/edx: int <- copy cursor-x
269 end-x <- increment
270 compare end-x, xmax
271 {
272 break-if-<
273 cursor-x <- copy xmin
274 cursor-y <- increment
275 }
276 cursor-x, cursor-y <- draw-text-wrapping-right-then-down screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
277 }
278
279 fn draw-text-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
280 var width/eax: int <- copy 0
281 var height/ecx: int <- copy 0
282 width, height <- screen-size screen
283 draw-text-wrapping-right-then-down-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
284 }
285
286 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 {
287 var stream-storage: (stream byte 0x100)
288 var stream/esi: (addr stream byte) <- address stream-storage
289 write-int32-hex stream, n
290 var xcurr/edx: int <- copy x
291 var ycurr/ecx: int <- copy y
292 {
293 var g/eax: grapheme <- read-grapheme stream
294 compare g, 0xffffffff/end-of-file
295 break-if-=
296 draw-grapheme screen, g, xcurr, ycurr, color, background-color
297 xcurr <- increment
298 compare xcurr, xmax
299 {
300 break-if-<
301 xcurr <- copy xmin
302 ycurr <- increment
303 }
304 loop
305 }
306 set-cursor-position screen, xcurr, ycurr
307 return xcurr, ycurr
308 }
309
310 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 {
311 var x2/eax: int <- copy 0
312 var y2/ecx: int <- copy 0
313 x2, y2 <- screen-size screen
314 x2, y2 <- draw-int32-hex-wrapping-right-then-down screen, n, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
315 return x2, y2
316 }
317
318 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 {
319 var cursor-x/eax: int <- copy 0
320 var cursor-y/ecx: int <- copy 0
321 cursor-x, cursor-y <- cursor-position screen
322 var end-x/edx: int <- copy cursor-x
323 end-x <- increment
324 compare end-x, xmax
325 {
326 break-if-<
327 cursor-x <- copy xmin
328 cursor-y <- increment
329 }
330 cursor-x, cursor-y <- draw-int32-hex-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
331 }
332
333 fn draw-int32-hex-wrapping-right-then-down-from-cursor-over-full-screen screen: (addr screen), n: int, color: int, background-color: int {
334 var width/eax: int <- copy 0
335 var height/ecx: int <- copy 0
336 width, height <- screen-size screen
337 draw-int32-hex-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
338 }
339
340 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 {
341 var stream-storage: (stream byte 0x100)
342 var stream/esi: (addr stream byte) <- address stream-storage
343 write-int32-decimal stream, n
344 var xcurr/edx: int <- copy x
345 var ycurr/ecx: int <- copy y
346 {
347 var g/eax: grapheme <- read-grapheme stream
348 compare g, 0xffffffff/end-of-file
349 break-if-=
350 draw-grapheme screen, g, xcurr, ycurr, color, background-color
351 xcurr <- increment
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-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 {
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-decimal-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-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 {
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-decimal-wrapping-right-then-down screen, n, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
385 }
386
387 fn draw-int32-decimal-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-decimal-wrapping-right-then-down-from-cursor screen, n, 0/xmin, 0/ymin, width, height, color, background-color
392 }
393
394
395
396
397
398
399 fn draw-text-downward screen: (addr screen), text: (addr array byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
400 var stream-storage: (stream byte 0x100)
401 var stream/esi: (addr stream byte) <- address stream-storage
402 write stream, text
403 var ycurr/eax: int <- draw-stream-downward screen, stream, x, y, ymax, color, background-color
404 return ycurr
405 }
406
407
408
409
410 fn draw-stream-downward screen: (addr screen), stream: (addr stream byte), x: int, y: int, ymax: int, color: int, background-color: int -> _/eax: int {
411 var ycurr/ecx: int <- copy y
412 {
413 var g/eax: grapheme <- read-grapheme stream
414 compare g, 0xffffffff/end-of-file
415 break-if-=
416 draw-grapheme screen, g, x, ycurr, color, background-color
417 ycurr <- increment
418 loop
419 }
420 set-cursor-position screen, x, ycurr
421 return ycurr
422 }
423
424 fn draw-text-downward-from-cursor screen: (addr screen), text: (addr array byte), ymax: int, color: int, background-color: int {
425 var cursor-x/eax: int <- copy 0
426 var cursor-y/ecx: int <- copy 0
427 cursor-x, cursor-y <- cursor-position screen
428 var result/eax: int <- draw-text-downward screen, text, cursor-x, cursor-y, ymax, color, background-color
429 }
430
431
432
433
434
435 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 {
436 var stream-storage: (stream byte 0x100)
437 var stream/esi: (addr stream byte) <- address stream-storage
438 write stream, text
439 var x/eax: int <- copy _x
440 var y/ecx: int <- copy _y
441 x, y <- draw-stream-wrapping-down-then-right screen, stream, xmin, ymin, xmax, ymax, x, y, color, background-color
442 return x, y
443 }
444
445
446
447
448
449 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 {
450 var xcurr/edx: int <- copy x
451 var ycurr/ecx: int <- copy y
452 {
453 var g/eax: grapheme <- read-grapheme stream
454 compare g, 0xffffffff/end-of-file
455 break-if-=
456 draw-grapheme screen, g, xcurr, ycurr, color, background-color
457 ycurr <- increment
458 compare ycurr, ymax
459 {
460 break-if-<
461 xcurr <- increment
462 ycurr <- copy ymin
463 }
464 loop
465 }
466 set-cursor-position screen, xcurr, ycurr
467 return xcurr, ycurr
468 }
469
470 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 {
471 var x2/eax: int <- copy 0
472 var y2/ecx: int <- copy 0
473 x2, y2 <- screen-size screen
474 x2, y2 <- draw-text-wrapping-down-then-right screen, text, 0/xmin, 0/ymin, x2, y2, x, y, color, background-color
475 return x2, y2
476 }
477
478 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 {
479 var cursor-x/eax: int <- copy 0
480 var cursor-y/ecx: int <- copy 0
481 cursor-x, cursor-y <- cursor-position screen
482 var end-y/edx: int <- copy cursor-y
483 end-y <- increment
484 compare end-y, ymax
485 {
486 break-if-<
487 cursor-x <- increment
488 cursor-y <- copy ymin
489 }
490 cursor-x, cursor-y <- draw-text-wrapping-down-then-right screen, text, xmin, ymin, xmax, ymax, cursor-x, cursor-y, color, background-color
491 }
492
493 fn draw-text-wrapping-down-then-right-from-cursor-over-full-screen screen: (addr screen), text: (addr array byte), color: int, background-color: int {
494 var width/eax: int <- copy 0
495 var height/ecx: int <- copy 0
496 width, height <- screen-size screen
497 draw-text-wrapping-down-then-right-from-cursor screen, text, 0/xmin, 0/ymin, width, height, color, background-color
498 }