diff --git a/doc/json_schema.json b/doc/json_schema.json index dc6e28486..b07bd08fb 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -166,6 +166,11 @@ "title": "If true, regenerate image logo cache", "default": false }, + "separate": { + "type": "boolean", + "title": "If true, print modules at bottom of the logo", + "default": false + }, "chafa": { "type": "object", "title": "Chafa configuration. See chafa document for details", diff --git a/src/logo/image/image.c b/src/logo/image/image.c index dc0d7e052..3cd7c6294 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -51,23 +51,36 @@ static bool printImageIterm(void) if (!instance.config.logo.width || !instance.config.logo.height) { - ffStrbufAppendF(&buf, "\e[2J\e[3J\e[%u;%uH\e]1337;File=inline=1:%s\a", - (unsigned) instance.config.logo.paddingTop, - (unsigned) instance.config.logo.paddingLeft, + if (!instance.config.logo.separate) + { + ffStrbufAppendF(&buf, "\e[2J\e[3J\e[%u;%uH", + (unsigned) instance.config.logo.paddingTop, + (unsigned) instance.config.logo.paddingLeft + ); + } + ffStrbufAppendF(&buf, "\e]1337;File=inline=1:%s\a", base64.chars ); ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf); - uint16_t X = 0, Y = 0; - const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X); - if (error) + if (!instance.config.logo.separate) { - fprintf(stderr, "\nLogo (iterm): fail to query cursor position: %s\n", error); - return true; // We already printed image logo, don't print ascii logo then + uint16_t X = 0, Y = 0; + const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X); + if (error) + { + fprintf(stderr, "\nLogo (iterm): fail to query cursor position: %s\n", error); + return true; // We already printed image logo, don't print ascii logo then + } + instance.state.logoWidth = X + instance.config.logo.paddingRight; + instance.state.logoHeight = Y; + fputs("\e[H", stdout); + } + else + { + instance.state.logoWidth = instance.state.logoHeight = 0; + ffPrintCharTimes('\n', instance.config.logo.paddingRight); } - instance.state.logoWidth = X + instance.config.logo.paddingRight; - instance.state.logoHeight = Y; - fputs("\e[H", stdout); } else { @@ -75,15 +88,24 @@ static bool printImageIterm(void) ffStrbufAppendC(&buf, '\n'); for (uint32_t i = 0; i < instance.config.logo.paddingLeft; ++i) ffStrbufAppendC(&buf, ' '); - instance.state.logoWidth = instance.config.logo.width + instance.config.logo.paddingLeft + instance.config.logo.paddingRight; - instance.state.logoHeight = instance.config.logo.paddingTop + instance.config.logo.height; - ffStrbufAppendF(&buf, "\e]1337;File=inline=1;width=%u;height=%u;preserveAspectRatio=%u:%s\a\n\e[%uA", + ffStrbufAppendF(&buf, "\e]1337;File=inline=1;width=%u;height=%u;preserveAspectRatio=%u:%s\a\n", (unsigned) instance.config.logo.width, (unsigned) instance.config.logo.height, (unsigned) instance.config.logo.preserveAspectRadio, - base64.chars, - (unsigned) instance.state.logoHeight + base64.chars ); + + if (!instance.config.logo.separate) + { + instance.state.logoWidth = instance.config.logo.width + instance.config.logo.paddingLeft + instance.config.logo.paddingRight; + instance.state.logoHeight = instance.config.logo.paddingTop + instance.config.logo.height; + ffStrbufAppendF(&buf, "\e[%uA", (unsigned) instance.state.logoHeight); + } + else + { + instance.state.logoWidth = instance.state.logoHeight = 0; + ffPrintCharTimes('\n', instance.config.logo.paddingRight); + } ffWriteFDBuffer(FFUnixFD2NativeFD(STDOUT_FILENO), &buf); } @@ -96,37 +118,56 @@ static bool printImageKittyDirect(void) if (!instance.config.logo.width || !instance.config.logo.height) { - // We must clear the entre screen to make sure that terminal buffer won't scroll up - printf("\e[2J\e[3J\e[%u;%uH\e_Ga=T,f=100,t=f;%s\e\\", - (unsigned) instance.config.logo.paddingTop, - (unsigned) instance.config.logo.paddingLeft, - base64.chars - ); - fflush(stdout); - uint16_t X = 0, Y = 0; - const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X); - if (error) + if (!instance.config.logo.separate) { - fprintf(stderr, "\nLogo (kitty-direct): fail to query cursor position: %s\n", error); - return true; // We already printed image logo, don't print ascii logo then + // We must clear the entre screen to make sure that terminal buffer won't scroll up + printf("\e[2J\e[3J\e[%u;%uH", + (unsigned) instance.config.logo.paddingTop, + (unsigned) instance.config.logo.paddingLeft + ); + } + printf("\e_Ga=T,f=100,t=f;%s\e\\", base64.chars); + fflush(stdout); + if (!instance.config.logo.separate) + { + uint16_t X = 0, Y = 0; + const char* error = ffGetTerminalResponse("\e[6n", "\e[%hu;%huR", &Y, &X); + if (error) + { + fprintf(stderr, "\nLogo (kitty-direct): fail to query cursor position: %s\n", error); + return true; // We already printed image logo, don't print ascii logo then + } + instance.state.logoWidth = X + instance.config.logo.paddingRight; + instance.state.logoHeight = Y; + fputs("\e[H", stdout); + } + else + { + instance.state.logoWidth = instance.state.logoHeight = 0; + ffPrintCharTimes('\n', instance.config.logo.paddingRight); } - instance.state.logoWidth = X + instance.config.logo.paddingRight; - instance.state.logoHeight = Y; - fputs("\e[H", stdout); } else { ffPrintCharTimes('\n', instance.config.logo.paddingTop); ffPrintCharTimes(' ', instance.config.logo.paddingLeft); - instance.state.logoWidth = instance.config.logo.width + instance.config.logo.paddingLeft + instance.config.logo.paddingRight; - instance.state.logoHeight = instance.config.logo.paddingTop + instance.config.logo.height; - printf("\e_Ga=T,f=100,t=f,c=%u,r=%u;%s\e\\\n\e[%uA", + printf("\e_Ga=T,f=100,t=f,c=%u,r=%u;%s\e\\\n", (unsigned) instance.config.logo.width, (unsigned) instance.config.logo.height, - base64.chars, - (unsigned) instance.state.logoHeight + base64.chars ); + if (!instance.config.logo.separate) + { + instance.state.logoWidth = instance.config.logo.width + instance.config.logo.paddingLeft + instance.config.logo.paddingRight; + instance.state.logoHeight = instance.config.logo.paddingTop + instance.config.logo.height; + printf("\e[%uA", (unsigned) instance.state.logoHeight); + } + else + { + instance.state.logoWidth = instance.state.logoHeight = 0; + ffPrintCharTimes('\n', instance.config.logo.paddingRight); + } } return true; diff --git a/src/logo/logo.c b/src/logo/logo.c index c0aa519f5..af240c549 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -188,17 +188,24 @@ void ffLogoPrintChars(const char* data, bool doColorReplacement) } } - ffPrintCharTimes(' ', options->paddingRight); fputs(FASTFETCH_TEXT_MODIFIER_RESET, stdout); - //Happens if the last line is the longest - if(currentlineLength > instance.state.logoWidth) - instance.state.logoWidth = currentlineLength; + if(!options->separate) + { + //Happens if the last line is the longest + if(currentlineLength > instance.state.logoWidth) + instance.state.logoWidth = currentlineLength; - instance.state.logoWidth += options->paddingLeft + options->paddingRight; + instance.state.logoWidth += options->paddingLeft + options->paddingRight; - //Go to the leftmost position and go up the height - printf("\e[1G\e[%uA", instance.state.logoHeight); + //Go to the leftmost position and go up the height + printf("\e[1G\e[%uA", instance.state.logoHeight); + } + else + { + instance.state.logoWidth = instance.state.logoHeight = 0; + ffPrintCharTimes('\n', options->paddingRight); + } } static void logoApplyColors(const FFlogo* logo) diff --git a/src/logo/option.c b/src/logo/option.c index 59474a2d3..32114de22 100644 --- a/src/logo/option.c +++ b/src/logo/option.c @@ -17,6 +17,7 @@ void ffInitLogoOptions(FFLogoOptions* options) options->printRemaining = true; options->preserveAspectRadio = false; options->recache = false; + options->separate = false; options->chafaFgOnly = false; ffStrbufInitStatic(&options->chafaSymbols, "block+border+space-wide-inverted"); // Chafa default @@ -116,6 +117,8 @@ logoType: options->preserveAspectRadio = ffOptionParseBoolean(value); else if(strcasecmp(subKey, "recache") == 0) options->recache = ffOptionParseBoolean(value); + else if(strcasecmp(subKey, "separate") == 0) + options->separate = ffOptionParseBoolean(value); else return false; } @@ -342,6 +345,11 @@ const char* ffParseLogoJsonConfig(void) options->recache = yyjson_get_bool(val); continue; } + else if (strcasecmp(key, "separate") == 0) + { + options->separate = yyjson_get_bool(val); + continue; + } else if (strcasecmp(key, "chafa") == 0) { if (!yyjson_is_obj(val)) diff --git a/src/logo/option.h b/src/logo/option.h index 1eb41c1e9..9273e2a3f 100644 --- a/src/logo/option.h +++ b/src/logo/option.h @@ -36,6 +36,7 @@ typedef struct FFLogoOptions bool printRemaining; bool preserveAspectRadio; bool recache; + bool separate; bool chafaFgOnly; FFstrbuf chafaSymbols;