fix: add draw-text method for raw 2D arrays
Application code (passepartout TUI) calls draw-text with a framebuffer (2D array) as the first argument, but draw-text only had methods for framebuffer-backend CLOS instances. Added a method on array that sets cells directly on the framebuffer array, matching make-framebuffer's return type.
This commit is contained in:
@@ -850,8 +850,9 @@ This means simple backends are always a "scroll and dump" mode —
|
||||
no cursor positioning, no escape sequences.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/backend/simple.lisp
|
||||
(defmethod draw-text ((b simple-backend) x y string fg bg
|
||||
&key bold italic underline reverse dim blink)
|
||||
(defmethod draw-text ((b simple-backend) x y string fg bg
|
||||
&key bold italic underline reverse dim blink
|
||||
&allow-other-keys)
|
||||
(declare (ignore x y fg bg bold italic underline reverse dim blink))
|
||||
(backend-write b string))
|
||||
#+END_SRC
|
||||
|
||||
@@ -359,6 +359,29 @@ does not need (e.g., reverse, dim, blink).
|
||||
:link-url link-url)))
|
||||
#+END_SRC
|
||||
|
||||
*** draw-text (raw array)
|
||||
|
||||
Direct rendering onto a raw 2D framebuffer array (the type returned by
|
||||
~make-framebuffer~). This lets application code call ~draw-text~ directly on a
|
||||
framebuffer without wrapping it in a ~framebuffer-backend~.
|
||||
|
||||
#+begin_src lisp :tangle ../src/rendering/framebuffer.lisp
|
||||
(defmethod draw-text ((fb array) x y string fg bg
|
||||
&key bold italic underline reverse dim blink
|
||||
&allow-other-keys)
|
||||
(declare (ignore reverse dim blink))
|
||||
(let ((h (array-dimension fb 0))
|
||||
(w (array-dimension fb 1)))
|
||||
(loop for i from 0 below (length string)
|
||||
for cx from x
|
||||
while (< cx w)
|
||||
when (and (< y h) (>= cx 0) (>= y 0))
|
||||
do (setf (aref fb y cx)
|
||||
(make-cell :char (char string i)
|
||||
:fg fg :bg bg
|
||||
:bold bold :italic italic :underline underline)))))
|
||||
#+end_src
|
||||
|
||||
*** draw-rect
|
||||
|
||||
Fill a rectangular region with space characters and an optional background
|
||||
|
||||
@@ -652,6 +652,7 @@ compatibility across SBCL versions. Returns (values cols rows).
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/backend/modern.lisp
|
||||
(defmethod backend-size ((b modern-backend))
|
||||
(or (ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
@@ -662,6 +663,7 @@ compatibility across SBCL versions. Returns (values cols rows).
|
||||
(values (sb-alien:deref winsize 1) ;; cols
|
||||
(sb-alien:deref winsize 0))) ;; rows
|
||||
(sb-alien:free-alien winsize))))
|
||||
(values 80 24)))
|
||||
#+END_SRC
|
||||
|
||||
** Capability query and write
|
||||
@@ -703,8 +705,9 @@ calls --- one =backend-write= per draw operation --- by packing everything
|
||||
into one buffer.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/backend/modern.lisp
|
||||
(defmethod draw-text ((b modern-backend) x y string fg bg
|
||||
&key bold italic underline reverse dim blink)
|
||||
(defmethod draw-text ((b modern-backend) x y string fg bg
|
||||
&key bold italic underline reverse dim blink
|
||||
&allow-other-keys)
|
||||
(let ((parts (list (cursor-move-escape x y)
|
||||
(sgr-fg fg) (sgr-bg bg)
|
||||
(when bold (sgr-attr :bold))
|
||||
|
||||
@@ -772,10 +772,12 @@ portability.
|
||||
|
||||
#+BEGIN_SRC lisp :tangle ../src/components/input.lisp
|
||||
(defun %raw-mode-on ()
|
||||
(uiop:run-program '("stty" "raw" "-echo" "-echoe" "-echok" "-onlcr") :output nil :error-output nil))
|
||||
(uiop:run-program '("stty" "raw" "-echo" "-echoe" "-echok" "-onlcr")
|
||||
:output nil :error-output nil :ignore-error-status t))
|
||||
|
||||
(defun %raw-mode-off ()
|
||||
(uiop:run-program '("stty" "sane") :output nil :error-output nil))
|
||||
(uiop:run-program '("stty" "sane")
|
||||
:output nil :error-output nil :ignore-error-status t))
|
||||
|
||||
(defmacro with-raw-terminal (&body body)
|
||||
"Execute BODY with the terminal in raw mode."
|
||||
|
||||
@@ -162,6 +162,7 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
(values))
|
||||
|
||||
(defmethod backend-size ((b modern-backend))
|
||||
(or (ignore-errors
|
||||
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||
(unwind-protect
|
||||
@@ -172,6 +173,7 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
(values (sb-alien:deref winsize 1) ;; cols
|
||||
(sb-alien:deref winsize 0))) ;; rows
|
||||
(sb-alien:free-alien winsize))))
|
||||
(values 80 24)))
|
||||
|
||||
(defmethod backend-write ((b modern-backend) string)
|
||||
(let ((stream (backend-output-stream b)))
|
||||
@@ -185,7 +187,8 @@ as a fallback when a keyword is not in *named-colors*.")
|
||||
:kitty-keyboard)))
|
||||
|
||||
(defmethod draw-text ((b modern-backend) x y string fg bg
|
||||
&key bold italic underline reverse dim blink)
|
||||
&key bold italic underline reverse dim blink
|
||||
&allow-other-keys)
|
||||
(let ((parts (list (cursor-move-escape x y)
|
||||
(sgr-fg fg) (sgr-bg bg)
|
||||
(when bold (sgr-attr :bold))
|
||||
|
||||
@@ -32,7 +32,8 @@
|
||||
(length string)))
|
||||
|
||||
(defmethod draw-text ((b simple-backend) x y string fg bg
|
||||
&key bold italic underline reverse dim blink)
|
||||
&key bold italic underline reverse dim blink
|
||||
&allow-other-keys)
|
||||
(declare (ignore x y fg bg bold italic underline reverse dim blink))
|
||||
(backend-write b string))
|
||||
|
||||
|
||||
@@ -228,10 +228,12 @@ Returns a mouse-event struct."
|
||||
(setf *terminal-resized-p* t))))
|
||||
|
||||
(defun %raw-mode-on ()
|
||||
(uiop:run-program '("stty" "raw" "-echo" "-echoe" "-echok" "-onlcr") :output nil :error-output nil))
|
||||
(uiop:run-program '("stty" "raw" "-echo" "-echoe" "-echok" "-onlcr")
|
||||
:output nil :error-output nil :ignore-error-status t))
|
||||
|
||||
(defun %raw-mode-off ()
|
||||
(uiop:run-program '("stty" "sane") :output nil :error-output nil))
|
||||
(uiop:run-program '("stty" "sane")
|
||||
:output nil :error-output nil :ignore-error-status t))
|
||||
|
||||
(defmacro with-raw-terminal (&body body)
|
||||
"Execute BODY with the terminal in raw mode."
|
||||
|
||||
@@ -78,6 +78,21 @@
|
||||
:bold bold :italic italic :underline underline
|
||||
:link-url link-url)))
|
||||
|
||||
(defmethod draw-text ((fb array) x y string fg bg
|
||||
&key bold italic underline reverse dim blink
|
||||
&allow-other-keys)
|
||||
(declare (ignore reverse dim blink))
|
||||
(let ((h (array-dimension fb 0))
|
||||
(w (array-dimension fb 1)))
|
||||
(loop for i from 0 below (length string)
|
||||
for cx from x
|
||||
while (< cx w)
|
||||
when (and (< y h) (>= cx 0) (>= y 0))
|
||||
do (setf (aref fb y cx)
|
||||
(make-cell :char (char string i)
|
||||
:fg fg :bg bg
|
||||
:bold bold :italic italic :underline underline)))))
|
||||
|
||||
(defmethod draw-rect ((fb framebuffer-backend) x y w h &key bg)
|
||||
(dotimes (row h)
|
||||
(dotimes (col w)
|
||||
|
||||
Reference in New Issue
Block a user