7501 - baremetal: draw text within a rectangle
This commit is contained in:
parent
589eba07e2
commit
bb0e67a308
|
@ -34,3 +34,54 @@ fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, x
|
||||||
}
|
}
|
||||||
return xcurr
|
return xcurr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# draw text from (x, y) to (xmax, ymax), wrapping as necessary
|
||||||
|
# return the next (x, y) coordinate in raster order where drawing stopped
|
||||||
|
# if there isn't enough space, return 0 without modifying the screen
|
||||||
|
fn draw-text-rightward-wrapped screen: (addr screen), text: (addr array byte), x: int, y: int, xmax: int, ymax: int, color: int -> _/eax: int, _/ecx: int {
|
||||||
|
var stream-storage: (stream byte 0x100)
|
||||||
|
var stream/esi: (addr stream byte) <- address stream-storage
|
||||||
|
write stream, text
|
||||||
|
# check if we have enough space
|
||||||
|
var xcurr/edx: int <- copy x
|
||||||
|
var ycurr/ecx: int <- copy y
|
||||||
|
{
|
||||||
|
compare ycurr, ymax
|
||||||
|
break-if->=
|
||||||
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
|
compare g, 0xffffffff # end-of-file
|
||||||
|
break-if-=
|
||||||
|
xcurr <- add 8 # font-width
|
||||||
|
compare xcurr, xmax
|
||||||
|
{
|
||||||
|
break-if-<
|
||||||
|
xcurr <- copy x
|
||||||
|
ycurr <- add 0x10 # font-height
|
||||||
|
}
|
||||||
|
loop
|
||||||
|
}
|
||||||
|
compare ycurr, ymax
|
||||||
|
{
|
||||||
|
break-if-<
|
||||||
|
return 0, 0
|
||||||
|
}
|
||||||
|
# we do; actually draw
|
||||||
|
rewind-stream stream
|
||||||
|
xcurr <- copy x
|
||||||
|
ycurr <- copy y
|
||||||
|
{
|
||||||
|
var g/eax: grapheme <- read-grapheme stream
|
||||||
|
compare g, 0xffffffff # end-of-file
|
||||||
|
break-if-=
|
||||||
|
draw-grapheme screen, g, xcurr, ycurr, color
|
||||||
|
xcurr <- add 8 # font-width
|
||||||
|
compare xcurr, xmax
|
||||||
|
{
|
||||||
|
break-if-<
|
||||||
|
xcurr <- copy x
|
||||||
|
ycurr <- add 0x10 # font-height
|
||||||
|
}
|
||||||
|
loop
|
||||||
|
}
|
||||||
|
return xcurr, ycurr
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,28 @@
|
||||||
|
fn draw-box screen: (addr screen), x1: int, y1: int, x2: int, y2: int, color: int {
|
||||||
|
draw-horizontal-line screen, x1, x2, y1, color
|
||||||
|
draw-vertical-line screen, x1, y1, y2, color
|
||||||
|
draw-horizontal-line screen, x1, x2, y2, color
|
||||||
|
draw-vertical-line screen, x2, y1, y2, color
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-horizontal-line screen: (addr screen), x1: int, x2: int, y: int, color: int {
|
||||||
|
var x/eax: int <- copy x1
|
||||||
|
{
|
||||||
|
compare x, x2
|
||||||
|
break-if->=
|
||||||
|
pixel screen, x, y, color
|
||||||
|
x <- increment
|
||||||
|
loop
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn draw-vertical-line screen: (addr screen), x: int, y1: int, y2: int, color: int {
|
||||||
|
var y/eax: int <- copy y1
|
||||||
|
{
|
||||||
|
compare y, y2
|
||||||
|
break-if->=
|
||||||
|
pixel screen, x, y, color
|
||||||
|
y <- increment
|
||||||
|
loop
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
# Draw ASCII text within a bounding box, while wrapping.
|
||||||
|
#
|
||||||
|
# To build a disk image:
|
||||||
|
# ./translate_mu_baremetal baremetal/ex6.mu # emits disk.img
|
||||||
|
# To run:
|
||||||
|
# qemu-system-i386 disk.img
|
||||||
|
# Or:
|
||||||
|
# bochs -f baremetal/boot.bochsrc # boot.bochsrc loads disk.img
|
||||||
|
#
|
||||||
|
# Expected output: a box and text that doesn't overflow it
|
||||||
|
|
||||||
|
fn main {
|
||||||
|
draw-box 0, 0xf, 0xf, 0x61, 0x41, 0x4
|
||||||
|
var x/eax: int <- copy 0
|
||||||
|
var y/ecx: int <- copy 0
|
||||||
|
x, y <- draw-text-rightward-wrapped 0, "hello from baremetal Mu!", 0x10, 0x10, 0x60, 0x40, 0xa # xmax = 0x60, ymax = 0x40
|
||||||
|
}
|
Loading…
Reference in New Issue