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