mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
Logo (Image): support generate image data via kitten icat
This commit is contained in:
@@ -432,6 +432,7 @@
|
||||
"sixel",
|
||||
"kitty",
|
||||
"kitty-direct",
|
||||
"kitty-icat",
|
||||
"iterm",
|
||||
"chafa",
|
||||
"raw",
|
||||
|
||||
+2
-1
@@ -186,7 +186,8 @@
|
||||
"data-raw": "Text data, printed as is",
|
||||
"sixel": "Image file, printed as sixel codes",
|
||||
"kitty": "Image file, printed as kitty graphics protocol",
|
||||
"kitty_direct": "Image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)",
|
||||
"kitty-direct": "Image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)",
|
||||
"kitty-icat": "Image file, use `kitten icat` to display the image. Requires binary `kitten` to be installed",
|
||||
"iterm": "Image file, printed as iterm graphics protocol",
|
||||
"chafa": "Image file, printed as ascii art using libchafa",
|
||||
"raw": "Image file, printed as raw binary string",
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
#include "image.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/printing.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/base64.h"
|
||||
#include "detection/terminalsize/terminalsize.h"
|
||||
@@ -138,6 +139,126 @@ static bool printImageIterm(bool printError)
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool printImageKittyIcat(bool printError)
|
||||
{
|
||||
const FFOptionsLogo* options = &instance.config.logo;
|
||||
|
||||
if (!ffPathExists(options->source.chars, FF_PATHTYPE_FILE))
|
||||
{
|
||||
if (printError)
|
||||
fputs("Logo (kitty-icat): Failed to load image file\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
fflush(stdout);
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY buf = ffStrbufCreate();
|
||||
|
||||
if (options->position == FF_LOGO_POSITION_LEFT)
|
||||
{
|
||||
ffStrbufAppendF(&buf, "\e[2J\e[3J\e[%u;%uH",
|
||||
(unsigned) options->paddingTop + 1,
|
||||
(unsigned) options->paddingLeft + 1
|
||||
);
|
||||
}
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
if (!options->width)
|
||||
{
|
||||
ffStrbufAppendNC(&buf, options->paddingTop, '\n');
|
||||
ffStrbufAppendNC(&buf, options->paddingLeft, ' ');
|
||||
}
|
||||
else
|
||||
{
|
||||
if (printError)
|
||||
fputs("Logo (kitty-icat): position top is not supported when logo width is set\n", stderr);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else if (options->position == FF_LOGO_POSITION_RIGHT)
|
||||
{
|
||||
if (printError)
|
||||
fputs("Logo (kitty-icat): position right is not supported\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
uint32_t prevLength = buf.length;
|
||||
|
||||
const char* error = NULL;
|
||||
|
||||
if (options->width)
|
||||
{
|
||||
char place[64];
|
||||
snprintf(place,
|
||||
ARRAY_SIZE(place),
|
||||
"--place=%ux9999@%ux%u",
|
||||
options->width,
|
||||
options->paddingLeft + 1,
|
||||
options->paddingTop + 1);
|
||||
|
||||
error = ffProcessAppendStdOut(&buf, (char* []) {
|
||||
"kitten",
|
||||
"icat",
|
||||
"-n",
|
||||
"--align=left",
|
||||
place,
|
||||
"--scale-up",
|
||||
options->source.chars,
|
||||
NULL,
|
||||
});
|
||||
}
|
||||
else
|
||||
{
|
||||
error = ffProcessAppendStdOut(&buf, (char* []) {
|
||||
"kitten",
|
||||
"icat",
|
||||
"-n",
|
||||
"--align=left",
|
||||
options->source.chars,
|
||||
NULL,
|
||||
});
|
||||
}
|
||||
if (error)
|
||||
{
|
||||
if (printError)
|
||||
fprintf(stderr, "Logo (kitty-icat): running `kitten icat` failed %s\n", error);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (buf.length == prevLength)
|
||||
{
|
||||
if (printError)
|
||||
fputs("Logo (kitty-icat): `kitten icat` returned empty output\n", stderr);
|
||||
return false;
|
||||
}
|
||||
|
||||
ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf);
|
||||
|
||||
if (options->position == FF_LOGO_POSITION_LEFT || options->position == FF_LOGO_POSITION_RIGHT)
|
||||
{
|
||||
uint16_t X = 0, Y = 0;
|
||||
const char* error = ffGetTerminalResponse("\e[6n", 2, "%*[^0-9]%hu;%huR", &Y, &X);
|
||||
if (error)
|
||||
{
|
||||
fprintf(stderr, "\nLogo (kitty-icat): fail to query cursor position: %s\n", error);
|
||||
return true; // We already printed image logo, don't print ascii logo then
|
||||
}
|
||||
if (X < options->paddingLeft + options->width)
|
||||
X = (uint16_t) (options->paddingLeft + options->width);
|
||||
if (options->position == FF_LOGO_POSITION_LEFT)
|
||||
instance.state.logoWidth = X + options->paddingRight - 1;
|
||||
instance.state.logoHeight = Y;
|
||||
fputs("\e[H", stdout);
|
||||
}
|
||||
else if (options->position == FF_LOGO_POSITION_TOP)
|
||||
{
|
||||
instance.state.logoWidth = instance.state.logoHeight = 0;
|
||||
ffPrintCharTimes('\n', options->paddingRight);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool printImageKittyDirect(bool printError)
|
||||
{
|
||||
const FFOptionsLogo* options = &instance.config.logo;
|
||||
@@ -957,6 +1078,9 @@ bool ffLogoPrintImageIfExists(FFLogoType type, bool printError)
|
||||
if(type == FF_LOGO_TYPE_IMAGE_KITTY_DIRECT)
|
||||
return printImageKittyDirect(printError);
|
||||
|
||||
if(type == FF_LOGO_TYPE_IMAGE_KITTY_ICAT)
|
||||
return printImageKittyIcat(printError);
|
||||
|
||||
#if !defined(FF_HAVE_CHAFA)
|
||||
if(type == FF_LOGO_TYPE_IMAGE_CHAFA)
|
||||
{
|
||||
|
||||
@@ -63,6 +63,7 @@ logoType:
|
||||
{ "sixel", FF_LOGO_TYPE_IMAGE_SIXEL },
|
||||
{ "kitty", FF_LOGO_TYPE_IMAGE_KITTY },
|
||||
{ "kitty-direct", FF_LOGO_TYPE_IMAGE_KITTY_DIRECT },
|
||||
{ "kitty-icat", FF_LOGO_TYPE_IMAGE_KITTY_ICAT },
|
||||
{ "iterm", FF_LOGO_TYPE_IMAGE_ITERM },
|
||||
{ "chafa", FF_LOGO_TYPE_IMAGE_CHAFA },
|
||||
{ "raw", FF_LOGO_TYPE_IMAGE_RAW },
|
||||
@@ -283,6 +284,7 @@ const char* ffOptionsParseLogoJsonConfig(FFOptionsLogo* options, yyjson_val* roo
|
||||
{ "sixel", FF_LOGO_TYPE_IMAGE_SIXEL },
|
||||
{ "kitty", FF_LOGO_TYPE_IMAGE_KITTY },
|
||||
{ "kitty-direct", FF_LOGO_TYPE_IMAGE_KITTY_DIRECT },
|
||||
{ "kitty-icat", FF_LOGO_TYPE_IMAGE_KITTY_ICAT },
|
||||
{ "iterm", FF_LOGO_TYPE_IMAGE_ITERM },
|
||||
{ "chafa", FF_LOGO_TYPE_IMAGE_CHAFA },
|
||||
{ "raw", FF_LOGO_TYPE_IMAGE_RAW },
|
||||
|
||||
@@ -17,6 +17,7 @@ typedef enum __attribute__((__packed__)) FFLogoType
|
||||
FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes
|
||||
FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol
|
||||
FF_LOGO_TYPE_IMAGE_KITTY_DIRECT, //image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm)
|
||||
FF_LOGO_TYPE_IMAGE_KITTY_ICAT, //image file, use `kitten icat` to display the image. Requires binary `kitten` to be installed"
|
||||
FF_LOGO_TYPE_IMAGE_ITERM, //image file, printed as iterm graphics protocol
|
||||
FF_LOGO_TYPE_IMAGE_CHAFA, //image file, printed as ascii art using libchafa
|
||||
FF_LOGO_TYPE_IMAGE_RAW, //image file, printed as raw binary string
|
||||
|
||||
Reference in New Issue
Block a user