diff --git a/README.md b/README.md index 17c17b890..6bf6d278e 100644 --- a/README.md +++ b/README.md @@ -104,6 +104,16 @@ Printing images as logo is supported using Sixel / Kitty / iTerm graphics protoc * Kitty: Because [kitty support png](https://sw.kovidgoyal.net/kitty/graphics-protocol/#png-data) natively, using `png` image file with both `--logo-width` and `--logo-height` being specified is recommanded to get maximum performance. Otherwise, imagemagick is required to convert image to RGBA data. * iTerm: [Since iTerm supports a lot of image format](https://iterm2.com/documentation-images.html), imagemagick support is not required. However, both `--logo-width` and `--logo-height` must be specified since fastfetch has no idea about the size of the image. * Chafa: Requires imagemagick support. +* Raw: use a pre-converted image file so that fastfetch don't need to convert the image format on the fly. +```shell +# brew install libsixel +$ img2sixel image.png -o image.sixel +$ fastfetch --raw image.sixel --logo-width 30 --logo-height 15 + +# wget https://iterm2.com/utilities/imgcat && chmod +x imgcat +$ imgcat image.png > image.raw +$ fastfetch --raw image.raw --logo-width 30 --logo-height 15 +``` ##### Package managers ``` diff --git a/src/fastfetch.c b/src/fastfetch.c index fd36ebc1d..c13130c0e 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -958,6 +958,7 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con "sixel", FF_LOGO_TYPE_IMAGE_SIXEL, "kitty", FF_LOGO_TYPE_IMAGE_KITTY, "chafa", FF_LOGO_TYPE_IMAGE_CHAFA, + "raw", FF_LOGO_TYPE_IMAGE_RAW, NULL ); } @@ -1036,6 +1037,11 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con optionParseString(key, value, &instance->config.logo.source); instance->config.logo.type = FF_LOGO_TYPE_IMAGE_ITERM; } + else if(strcasecmp(key, "--raw") == 0) + { + optionParseString(key, value, &instance->config.logo.source); + instance->config.logo.type = FF_LOGO_TYPE_IMAGE_RAW; + } else if(strcasecmp(key, "--chafa-fg-only") == 0) instance->config.logo.chafaFgOnly = optionParseBoolean(value); else if(strcasecmp(key, "--chafa-symbols") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index a99eadc44..d292e5983 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -37,6 +37,7 @@ typedef enum FFLogoType FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol 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 } FFLogoType; typedef enum FFBinaryPrefixType diff --git a/src/logo/image/image.c b/src/logo/image/image.c index ed0f0677f..bb1b2f46a 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -39,7 +39,7 @@ static bool printImageIterm(FFinstance* instance) ffStrbufInit(&buf); if(!ffAppendFileBuffer(instance->config.logo.source.chars, &buf)) { - fputs("Logo: failed to load image file\n", stderr); + fputs("Logo: Failed to load image file\n", stderr); return false; } diff --git a/src/logo/logo.c b/src/logo/logo.c index 3c48e0854..c259d8ca9 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -8,6 +8,16 @@ #include #include +static void ffLogoPrintCharsRaw(FFinstance* instance, const char* data, size_t length) +{ + fputs(FASTFETCH_TEXT_MODIFIER_BOLT, stdout); + ffPrintCharTimes(' ', instance->config.logo.paddingLeft); + fwrite(data, length, 1, stdout); + printf("\033[9999999D\n\033[%uA", instance->config.logo.height); + instance->state.logoWidth = instance->config.logo.paddingLeft + instance->config.logo.width + instance->config.logo.paddingRight; + instance->state.logoHeight = instance->config.logo.height; +} + void ffLogoPrintChars(FFinstance* instance, const char* data, bool doColorReplacement) { uint32_t currentlineLength = 0; @@ -271,19 +281,23 @@ static void logoPrintData(FFinstance* instance, bool doColorReplacement) { logoApplyColorsDetected(instance); } -static bool logoPrintFileIfExists(FFinstance* instance, bool doColorReplacement) +static bool logoPrintFileIfExists(FFinstance* instance, bool doColorReplacement, bool raw) { FFstrbuf content; - ffStrbufInitA(&content, 2047); + ffStrbufInit(&content); if(!ffAppendFileBuffer(instance->config.logo.source.chars, &content)) { ffStrbufDestroy(&content); + fputs("Logo: Failed to load file content from logo source\n", stderr); return false; } logoApplyColorsDetected(instance); - ffLogoPrintChars(instance, content.chars, doColorReplacement); + if(raw) + ffLogoPrintCharsRaw(instance, content.chars, content.length); + else + ffLogoPrintChars(instance, content.chars, doColorReplacement); ffStrbufDestroy(&content); return true; } @@ -304,13 +318,23 @@ static void logoPrintKnownType(FFinstance* instance) if(instance->config.logo.type == FF_LOGO_TYPE_BUILTIN) successfull = logoPrintBuiltinIfExists(instance, instance->config.logo.source.chars); else if(instance->config.logo.type == FF_LOGO_TYPE_FILE) - successfull = logoPrintFileIfExists(instance, true); + successfull = logoPrintFileIfExists(instance, true, false); else if(instance->config.logo.type == FF_LOGO_TYPE_FILE_RAW) - successfull = logoPrintFileIfExists(instance, false); + successfull = logoPrintFileIfExists(instance, false, false); else if(instance->config.logo.type == FF_LOGO_TYPE_DATA) logoPrintData(instance, true); else if(instance->config.logo.type == FF_LOGO_TYPE_DATA_RAW) logoPrintData(instance, false); + else if(instance->config.logo.type == FF_LOGO_TYPE_IMAGE_RAW) + { + if(instance->config.logo.width == 0 || instance->config.logo.height == 0) + { + fputs("both `--logo-width` and `--logo-height` must be specified\n", stderr); + successfull = false; + } + else + successfull = logoPrintFileIfExists(instance, false, true); + } else //image successfull = logoPrintImageIfExists(instance, instance->config.logo.type); @@ -362,7 +386,7 @@ void ffLogoPrint(FFinstance* instance) return; //Try to load the logo as a file. If it succeeds, print it and return. - if(logoPrintFileIfExists(instance, true)) + if(logoPrintFileIfExists(instance, true, false)) return; logoPrintDetected(instance);