about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2021-01-12 00:20:22 -0800
committerKartik Agaram <vc@akkartik.com>2021-01-12 00:20:22 -0800
commitbb0e67a308922fc1a1a6972b00fcc37909a028ce (patch)
tree4636ba8cfaad3ad2f3d64c67a08557c2d89cc8b4
parent589eba07e2b1f1f3c6dbb3087b306071a2f9809b (diff)
downloadmu-bb0e67a308922fc1a1a6972b00fcc37909a028ce.tar.gz
7501 - baremetal: draw text within a rectangle
-rw-r--r--baremetal/501draw-text.mu51
-rw-r--r--baremetal/502manhattan-line.mu28
-rw-r--r--baremetal/ex6.mu17
3 files changed, 96 insertions, 0 deletions
diff --git a/baremetal/501draw-text.mu b/baremetal/501draw-text.mu
index f19536ca..af165e78 100644
--- a/baremetal/501draw-text.mu
+++ b/baremetal/501draw-text.mu
@@ -34,3 +34,54 @@ fn draw-text-rightward screen: (addr screen), text: (addr array byte), x: int, x
   }
   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
+}
diff --git a/baremetal/502manhattan-line.mu b/baremetal/502manhattan-line.mu
new file mode 100644
index 00000000..0351fcb6
--- /dev/null
+++ b/baremetal/502manhattan-line.mu
@@ -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
+  }
+}
diff --git a/baremetal/ex6.mu b/baremetal/ex6.mu
new file mode 100644
index 00000000..f0c1f896
--- /dev/null
+++ b/baremetal/ex6.mu
@@ -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
+}