From fac3f746cda24bd223c57a414d8c6242fa35c1e6 Mon Sep 17 00:00:00 2001 From: Akib Azmain Turja Date: Tue, 3 Oct 2023 18:51:24 +0600 Subject: [PATCH] Support rendering Sixel with XPM images * eat.el (eat--t-sixel-render-bitmap): Support conversion to XPM format. * eat.el (eat-sixel-render-formats): Add XPM to the default. * eat.el (eat-term-set-parameter, eat--sixel-render-format): Support XPM as an allowed format. * eat.texi (Sixel): Update. --- eat.el | 51 ++++++++++++++++++++++++++++++++++++++++++++++----- eat.texi | 11 ++++++----- 2 files changed, 52 insertions(+), 10 deletions(-) diff --git a/eat.el b/eat.el index 3d543ea..07d929e 100644 --- a/eat.el +++ b/eat.el @@ -198,9 +198,11 @@ aspect ratio of 3:2." :group 'eat-ui :group 'eat-eshell) -(defcustom eat-sixel-render-formats '(svg half-block background none) +(defcustom eat-sixel-render-formats + '(xpm svg half-block background none) "List of formats to render Sixel, in order of preference." - :type '(repeat (choice (const :tag "SVG Image" svg) + :type '(repeat (choice (const :tag "XPM Image" xpm) + (const :tag "SVG Image" svg) (const :tag "UTF-8 half block" half-block) (const :tag "Background color" background) (const :tag "None" none))) @@ -3043,6 +3045,42 @@ CHAR-SIZE is the width and height of a character." (format " fill=\"%s\">" color)) strs)))) strs)) + ,@(eat--t-term-sixel-image-extra-props eat--t-term)))) + ('xpm + (put-text-property + (point) (1+ (point)) 'display + `(image + :type xpm + :data ,(let ((color-map nil) + (pixmap nil) + (color-key-length + (length (format "%x" (* (car char-size) + (cdr char-size)))))) + (dotimes (i (cdr char-size)) + (push nil pixmap) + (dotimes (j (car char-size)) + (let ((idx (format + (format "%%0%ix" color-key-length) + (+ (* i (car char-size)) j))) + (color (or (aref (aref bitmap i) j) + "None"))) + (push (format "%s c %s" idx color) color-map) + (push idx (car pixmap))))) + (concat + "/* XPM */\n" + "static char * XFACE[] = {\n" + (format "\"%i %i %i %i\",\n" (car char-size) + (cdr char-size) (* (car char-size) + (cdr char-size)) + color-key-length) + (mapconcat (lambda (line) + (format "\"%s\",\n" line)) + color-map) + (mapconcat (lambda (row) + (format "\"%s\"" (string-join + (nreverse row)))) + (nreverse pixmap) ",\n") + "\n};")) ,@(eat--t-term-sixel-image-extra-props eat--t-term))))))) (defun eat--t-sixel-flush-line (nullify) @@ -4016,9 +4054,9 @@ If NULLIFY is non-nil, nullify flushed part of Sixel buffer." (setf (eat--t-term-char-width terminal) (car value)) (setf (eat--t-term-char-height terminal) (cdr value))) ('sixel-render-format - (unless (memq value '(background half-block svg none)) + (unless (memq value '(background half-block svg xpm none)) (error "`sixel-render-format' parameter must be set to one of\ - the supported methods")) + the supported formats")) (setf (eat--t-term-sixel-render-format terminal) value)) ('sixel-image-extra-properties (setf (eat--t-term-sixel-image-extra-props terminal) value))) @@ -5092,7 +5130,10 @@ selection, or nil if none." (cl-return 'half-block))) ('svg (when (and (display-graphic-p) (image-type-available-p 'svg)) - (cl-return 'svg))))) + (cl-return 'svg))) + ('xpm (when (and (display-graphic-p) + (image-type-available-p 'xpm)) + (cl-return 'xpm))))) 'none)) (defun eat--set-term-sixel-params () diff --git a/eat.texi b/eat.texi index 244de7c..47f9d8e 100644 --- a/eat.texi +++ b/eat.texi @@ -991,11 +991,12 @@ customizing the @code{eat-sixel-render-formats} user option. @vindex eat-sixel-render-formats @defopt eat-sixel-render-formats List of formats to render Sixel, in order of preference. Each element -of the list is one of @code{svg}, @code{half-block}, -@code{background}, @code{none}. @code{svg} means to use SVG image -format, @code{half-block} means to use UTF-8 half block characters, -@code{background} means to just use background color, and @code{none} -means to not render the image, instead just clear the area. +of the list is one of @code{xpm}, @code{svg}, @code{half-block}, +@code{background}, @code{none}. @code{xpm} and @code{svg} means to +use XPM and SVG image format respectively, @code{half-block} means to +use UTF-8 half block characters, @code{background} means to just use +background color, and @code{none} means to not render the image, +instead just clear the area. @end defopt @node Blinking Text