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.
|
no cursor positioning, no escape sequences.
|
||||||
|
|
||||||
#+BEGIN_SRC lisp :tangle ../src/backend/simple.lisp
|
#+BEGIN_SRC lisp :tangle ../src/backend/simple.lisp
|
||||||
(defmethod draw-text ((b simple-backend) x y string fg bg
|
(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))
|
(declare (ignore x y fg bg bold italic underline reverse dim blink))
|
||||||
(backend-write b string))
|
(backend-write b string))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|||||||
@@ -359,6 +359,29 @@ does not need (e.g., reverse, dim, blink).
|
|||||||
:link-url link-url)))
|
:link-url link-url)))
|
||||||
#+END_SRC
|
#+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
|
*** draw-rect
|
||||||
|
|
||||||
Fill a rectangular region with space characters and an optional background
|
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
|
#+BEGIN_SRC lisp :tangle ../src/backend/modern.lisp
|
||||||
(defmethod backend-size ((b modern-backend))
|
(defmethod backend-size ((b modern-backend))
|
||||||
|
(or (ignore-errors
|
||||||
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
||||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
@@ -662,6 +663,7 @@ compatibility across SBCL versions. Returns (values cols rows).
|
|||||||
(values (sb-alien:deref winsize 1) ;; cols
|
(values (sb-alien:deref winsize 1) ;; cols
|
||||||
(sb-alien:deref winsize 0))) ;; rows
|
(sb-alien:deref winsize 0))) ;; rows
|
||||||
(sb-alien:free-alien winsize))))
|
(sb-alien:free-alien winsize))))
|
||||||
|
(values 80 24)))
|
||||||
#+END_SRC
|
#+END_SRC
|
||||||
|
|
||||||
** Capability query and write
|
** Capability query and write
|
||||||
@@ -703,8 +705,9 @@ calls --- one =backend-write= per draw operation --- by packing everything
|
|||||||
into one buffer.
|
into one buffer.
|
||||||
|
|
||||||
#+BEGIN_SRC lisp :tangle ../src/backend/modern.lisp
|
#+BEGIN_SRC lisp :tangle ../src/backend/modern.lisp
|
||||||
(defmethod draw-text ((b modern-backend) x y string fg bg
|
(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)
|
(let ((parts (list (cursor-move-escape x y)
|
||||||
(sgr-fg fg) (sgr-bg bg)
|
(sgr-fg fg) (sgr-bg bg)
|
||||||
(when bold (sgr-attr :bold))
|
(when bold (sgr-attr :bold))
|
||||||
|
|||||||
@@ -772,10 +772,12 @@ portability.
|
|||||||
|
|
||||||
#+BEGIN_SRC lisp :tangle ../src/components/input.lisp
|
#+BEGIN_SRC lisp :tangle ../src/components/input.lisp
|
||||||
(defun %raw-mode-on ()
|
(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 ()
|
(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)
|
(defmacro with-raw-terminal (&body body)
|
||||||
"Execute BODY with the terminal in raw mode."
|
"Execute BODY with the terminal in raw mode."
|
||||||
|
|||||||
@@ -162,6 +162,7 @@ as a fallback when a keyword is not in *named-colors*.")
|
|||||||
(values))
|
(values))
|
||||||
|
|
||||||
(defmethod backend-size ((b modern-backend))
|
(defmethod backend-size ((b modern-backend))
|
||||||
|
(or (ignore-errors
|
||||||
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
(let* ((+tiocgwinsz+ 21523) ; 0x5413 on Linux
|
||||||
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
(winsize (sb-alien:make-alien sb-alien:unsigned-short 4)))
|
||||||
(unwind-protect
|
(unwind-protect
|
||||||
@@ -172,6 +173,7 @@ as a fallback when a keyword is not in *named-colors*.")
|
|||||||
(values (sb-alien:deref winsize 1) ;; cols
|
(values (sb-alien:deref winsize 1) ;; cols
|
||||||
(sb-alien:deref winsize 0))) ;; rows
|
(sb-alien:deref winsize 0))) ;; rows
|
||||||
(sb-alien:free-alien winsize))))
|
(sb-alien:free-alien winsize))))
|
||||||
|
(values 80 24)))
|
||||||
|
|
||||||
(defmethod backend-write ((b modern-backend) string)
|
(defmethod backend-write ((b modern-backend) string)
|
||||||
(let ((stream (backend-output-stream b)))
|
(let ((stream (backend-output-stream b)))
|
||||||
@@ -185,7 +187,8 @@ as a fallback when a keyword is not in *named-colors*.")
|
|||||||
:kitty-keyboard)))
|
:kitty-keyboard)))
|
||||||
|
|
||||||
(defmethod draw-text ((b modern-backend) x y string fg bg
|
(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)
|
(let ((parts (list (cursor-move-escape x y)
|
||||||
(sgr-fg fg) (sgr-bg bg)
|
(sgr-fg fg) (sgr-bg bg)
|
||||||
(when bold (sgr-attr :bold))
|
(when bold (sgr-attr :bold))
|
||||||
|
|||||||
@@ -32,7 +32,8 @@
|
|||||||
(length string)))
|
(length string)))
|
||||||
|
|
||||||
(defmethod draw-text ((b simple-backend) x y string fg bg
|
(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))
|
(declare (ignore x y fg bg bold italic underline reverse dim blink))
|
||||||
(backend-write b string))
|
(backend-write b string))
|
||||||
|
|
||||||
|
|||||||
@@ -228,10 +228,12 @@ Returns a mouse-event struct."
|
|||||||
(setf *terminal-resized-p* t))))
|
(setf *terminal-resized-p* t))))
|
||||||
|
|
||||||
(defun %raw-mode-on ()
|
(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 ()
|
(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)
|
(defmacro with-raw-terminal (&body body)
|
||||||
"Execute BODY with the terminal in raw mode."
|
"Execute BODY with the terminal in raw mode."
|
||||||
|
|||||||
@@ -78,6 +78,21 @@
|
|||||||
:bold bold :italic italic :underline underline
|
:bold bold :italic italic :underline underline
|
||||||
:link-url link-url)))
|
: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)
|
(defmethod draw-rect ((fb framebuffer-backend) x y w h &key bg)
|
||||||
(dotimes (row h)
|
(dotimes (row h)
|
||||||
(dotimes (col w)
|
(dotimes (col w)
|
||||||
|
|||||||
Reference in New Issue
Block a user