From e7db3cd7fe766198027ea77945034799d2bf1a83 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 6 Jul 2023 23:16:05 +0800 Subject: [PATCH] Logo: support builtin small logo Also improve performance of builtin logo finding Assume you are running macOS * default -> macos * `-l small` -> macos_small * `--logo-type small` -> macos_small * `-l macos` -> macos * `-l macos --logo-type small` -> macos_small * `-l macos_small` -> macos_small * `-l macos_small --logo-type small` -> error, because Logo `macos_small_small` doesn't exist --- README.md | 2 +- doc/json_schema.json | 1 + src/logo/builtin.c | 96 +++++++++++++++++++++++++++++++------------- src/logo/logo.c | 85 +++++++++++++++++++++++++-------------- src/logo/logo.h | 1 + src/logo/option.c | 10 ++++- src/logo/option.h | 1 + 7 files changed, 134 insertions(+), 62 deletions(-) diff --git a/README.md b/README.md index 208279acd..11af03dae 100644 --- a/README.md +++ b/README.md @@ -25,7 +25,7 @@ Currently, the performance difference is measurable, but too small to be recogni There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `--load-config `. They may also serve as a good example for format arguments. -Logos can be heavily customized too; see the [logo documentation](doc/logo.md) for more information. +Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information. ## Dependencies diff --git a/doc/json_schema.json b/doc/json_schema.json index 6b03607df..b12848e4f 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -45,6 +45,7 @@ "enum": [ "auto", "builtin", + "small", "file", "file-raw", "data", diff --git a/src/logo/builtin.c b/src/logo/builtin.c index b5a0985ff..f5e278944 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -1,6 +1,8 @@ #include "logo.h" #define FF_LOGO_INIT static FFlogo logo; static bool init = false; if(init) return &logo; init = true; +// The names of small logo must end with `_small` or `-small` +#define FF_LOGO_INIT_SMALL FF_LOGO_INIT logo.small = true; #define FF_LOGO_NAMES(...) static const char* names[] = (const char*[]) { __VA_ARGS__, NULL }; logo.names = names; #define FF_LOGO_LINES(x) logo.data = x; #define FF_LOGO_COLORS(...) static const char* colors[] = (const char*[]) { __VA_ARGS__, NULL }; logo.builtinColors = colors; @@ -112,7 +114,7 @@ static const FFlogo* getLogoAlpine(void) static const FFlogo* getLogoAlpineSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("alpine_small", "alpine-linux-small") FF_LOGO_LINES( " /\\ /\\\n" @@ -165,7 +167,7 @@ static const FFlogo* getLogoAndroid(void) static const FFlogo* getLogoAndroidSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("android-small", "android_small") FF_LOGO_LINES( " ;, ,;\n" @@ -219,7 +221,7 @@ static const FFlogo* getLogoArch(void) static const FFlogo* getLogoArchSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("arch_small", "archlinux_small", "arch-linux-small") FF_LOGO_LINES( " /\\\n" @@ -274,7 +276,7 @@ static const FFlogo* getLogoArtix(void) static const FFlogo* getLogoArtixSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("artix_small", "artixlinux_small", "artix-linux-small") FF_LOGO_LINES( " /\\\n" @@ -437,7 +439,7 @@ static const FFlogo* getLogoCachyOS(void) static const FFlogo* getLogoCachyOSSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("cachy_small", "cachyos_small", "cachy-linux-small", "cachyos-linux-small") FF_LOGO_LINES( " /''''''''''''/\n" @@ -527,7 +529,7 @@ static const FFlogo* getLogoCentOS(void) static const FFlogo* getLogoCentOSSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("cent_small", "centos_small", "cent-linux_small", "cent-linux-small", "centos-linux-small") FF_LOGO_LINES( " $2____$1^$4____\n" @@ -653,7 +655,7 @@ static const FFlogo* getLogoDebian(void) static const FFlogo* getLogoDebianSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("debian_small", "debian-linux-small") FF_LOGO_LINES( " _____\n" @@ -702,7 +704,7 @@ static const FFlogo* getLogoDevuan(void) static const FFlogo* getLogoDevuanSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("devuan_small", "devuan-linux-small") FF_LOGO_LINES( " ..:::.\n" @@ -853,7 +855,7 @@ static const FFlogo* getLogoFedora(void) static const FFlogo* getLogoFedoraSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("fedora_small", "fedora-linux-small") FF_LOGO_LINES( " ,'''''.\n" @@ -938,7 +940,7 @@ static const FFlogo* getLogoFreeBSD(void) static const FFlogo* getLogoFreeBSDSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("freebsd_small") FF_LOGO_LINES( "$1/\\,-'''''-,/\\\n" @@ -990,7 +992,7 @@ static const FFlogo* getLogoGaruda(void) static const FFlogo* getLogoGarudaSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("garuda_small", "garudalinux_small", "garuda-linux-small") FF_LOGO_LINES( " .----.\n" @@ -1042,7 +1044,7 @@ static const FFlogo* getLogoGentoo(void) static const FFlogo* getLogoGentooSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("gentoo_small", "gentoo-linux-small") FF_LOGO_LINES( " _-----_\n" @@ -1243,7 +1245,7 @@ static const FFlogo* getLogoMacOS(void) FF_LOGO_INIT FF_LOGO_NAMES("macos", "mac", "apple", "darwin", "osx") FF_LOGO_LINES( - " $1c.'\n" + " $1..'\n" " ,xNMM.\n" " .OMMMMo\n" " lMM\"\n" @@ -1275,7 +1277,7 @@ static const FFlogo* getLogoMacOS(void) static const FFlogo* getLogoMacOSSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("macos_small", "mac_small", "apple_small", "darwin_small", "osx_small") FF_LOGO_LINES( "$1 .:'\n" @@ -1298,10 +1300,45 @@ static const FFlogo* getLogoMacOSSmall(void) FF_LOGO_RETURN } -static const FFlogo* getLogoMacOSSmall2(void) +static const FFlogo* getLogoMacOS2(void) { FF_LOGO_INIT - FF_LOGO_NAMES("macos_small2", "mac_small2", "apple_small2", "darwin_small2", "osx_small2") + FF_LOGO_NAMES("macos2", "mac2", "apple2", "darwin2", "osx2") + FF_LOGO_LINES( + " $1..'\n" + " ,xN .\n" + " .O o\n" + " l \"\n" + " .;loddo:. .olloddol;.\n" + " cK NW 0:\n" + " $2.K Wd.\n" + " X X.\n" + "$3; :\n" + ": :\n" + ". X.\n" + " k Wd.\n" + " $4'X k\n" + " 'X K.\n" + " $5k d\n" + " ;K WXXW k.\n" + " \"cooc*\" \"*coo'\"" + ) + FF_LOGO_COLORS( + "32", //green + "33", //yellow + "31", //red + "35", //magenta + "34" //blue + ) + FF_LOGO_COLOR_KEYS("33"); //yellow + FF_LOGO_COLOR_TITLE("32"); //green + FF_LOGO_RETURN +} + +static const FFlogo* getLogoMacOS2Small(void) +{ + FF_LOGO_INIT_SMALL + FF_LOGO_NAMES("macos2_small", "mac2_small", "apple2_small", "darwin2_small", "osx2_small") FF_LOGO_LINES( "$1 .:'\n" " __ :'__\n" @@ -1353,7 +1390,7 @@ static const FFlogo* getLogoManjaro(void) static const FFlogo* getLogoManjaroSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("manjaro_small", "manjaro-linux-small") FF_LOGO_LINES( "||||||||| ||||\n" @@ -1408,7 +1445,7 @@ static const FFlogo* getLogoMint(void) static const FFlogo* getLogoMintSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("mint_small", "linuxmint_small", "mint-linux-small") FF_LOGO_LINES( " __________\n" @@ -1536,7 +1573,7 @@ static const FFlogo* getLogoWindows11(void) static const FFlogo* getLogoWindows11Small(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("Windows 11_small", "Windows 11-small") FF_LOGO_LINES( "$1lllllllll $2lllllllll\n" @@ -1706,7 +1743,7 @@ static const FFlogo* getLogoNixOsOld(void) static const FFlogo* getLogoNixOsSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("nixos_small", "nix-small", "nixos-small", "nix_small", "nix-os-small", "nix_os_small") FF_LOGO_LINES( "$1 \\\\ \\\\ //\n" @@ -1791,7 +1828,7 @@ static const FFlogo* getLogoOpenSuse(void) static const FFlogo* getLogoOpenSuseSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("suse_small", "opensuse_small", "open_suse_small", "open-suse_small") FF_LOGO_LINES( " _______\n" @@ -1973,7 +2010,7 @@ static const FFlogo* getLogoParabola(void) static const FFlogo* getLogoParabolaSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("parabola_small", "parabola-gnulinux_small") FF_LOGO_LINES( " __ __ __ _\n" @@ -1993,7 +2030,7 @@ static const FFlogo* getLogoParabolaSmall(void) static const FFlogo* getLogoPopSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("pop_small", "popos_small", "pop_os_small", "pop-linux-small") FF_LOGO_LINES( "______\n" @@ -2052,7 +2089,7 @@ static const FFlogo* getLogoRaspbian(void) static const FFlogo* getLogoRaspbianSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("raspbian_small", "raspi_small", "raspberrypi_small" "raspberrypios_small" "pios_small") FF_LOGO_LINES( " $2.~~. .~~.\n" @@ -2112,7 +2149,7 @@ static const FFlogo* getLogoReborn(void) static const FFlogo* getLogoRebornSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("reborn_small", "reborn-os-small", "rebornos_small", "rebornos-linux-small", "reborn-os-linux-small") FF_LOGO_LINES( " _______________\n" @@ -2304,7 +2341,7 @@ static const FFlogo* getLogoSlackware(void) static const FFlogo* getLogoSlackwareSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("slackware-small", "slackware-linux-small", "slackware_small", "slackwarelinux_small") FF_LOGO_LINES( " ________\n" @@ -2464,7 +2501,7 @@ static const FFlogo* getLogoUbuntuOld(void) static const FFlogo* getLogoUbuntuSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("ubuntu_small", "ubuntu-linux-small") FF_LOGO_LINES( " _\n" @@ -2550,7 +2587,7 @@ static const FFlogo* getLogoVoid(void) static const FFlogo* getLogoVoidSmall(void) { - FF_LOGO_INIT + FF_LOGO_INIT_SMALL FF_LOGO_NAMES("void_small", "void-linux-small") FF_LOGO_LINES( " _______\n" @@ -2647,7 +2684,8 @@ GetLogoMethod* ffLogoBuiltinGetAll(void) getLogoLinux, getLogoMacOS, getLogoMacOSSmall, - getLogoMacOSSmall2, + getLogoMacOS2, + getLogoMacOS2Small, getLogoManjaro, getLogoManjaroSmall, getLogoMint, diff --git a/src/logo/logo.c b/src/logo/logo.c index c1e2b9f28..449901856 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -4,10 +4,18 @@ #include "detection/os/os.h" #include "detection/terminalshell/terminalshell.h" #include "util/textModifier.h" +#include "util/stringUtils.h" #include #include +typedef enum FFLogoSize +{ + FF_LOGO_SIZE_UNKNOWN, + FF_LOGO_SIZE_NORMAL, + FF_LOGO_SIZE_SMALL, +} FFLogoSize; + static void ffLogoPrintCharsRaw(const char* data, size_t length) { FFLogoOptions* options = &instance.config.logo; @@ -177,58 +185,71 @@ static void logoApplyColors(const FFlogo* logo) ffStrbufAppendS(&instance.config.colorTitle, logo->colorTitle); } -static bool logoHasName(const FFlogo* logo, const char* name) +static bool logoHasName(const FFlogo* logo, const FFstrbuf* name, bool small) { - const char** logoName = logo->names; - - while(*logoName != NULL) + for(const char** logoName = logo->names; *logoName != NULL; ++logoName) { - if(strcasecmp(*logoName, name) == 0) + if(small) + { + uint32_t logoNameLength = (uint32_t) (strlen(*logoName) - strlen("_small")); + if(name->length == logoNameLength && strncasecmp(*logoName, name->chars, logoNameLength) == 0) return true; + } + if(ffStrbufIgnCaseEqualS(name, *logoName)) return true; - ++logoName; } return false; } -static const FFlogo* logoGetBuiltin(const char* name) +static const FFlogo* logoGetBuiltin(const FFstrbuf* name, FFLogoSize size) { - GetLogoMethod* methods = ffLogoBuiltinGetAll(); + if (name->length == 0) + return NULL; - while(*methods != NULL) + for(GetLogoMethod* methods = ffLogoBuiltinGetAll(); *methods; ++methods) { const FFlogo* logo = (*methods)(); - if(logoHasName(logo, name)) - return logo; + switch (size) + { + case FF_LOGO_SIZE_NORMAL: + if(logo->small) continue; + break; + case FF_LOGO_SIZE_SMALL: + if(!logo->small) continue; + break; + default: + break; + } - ++methods; + if(logoHasName(logo, name, size == FF_LOGO_SIZE_SMALL)) + return logo; } return NULL; } -static const FFlogo* logoGetBuiltinDetected(void) +static const FFlogo* logoGetBuiltinDetected(FFLogoSize size) { const FFOSResult* os = ffDetectOS(); - const FFlogo* logo = logoGetBuiltin(os->id.chars); + const FFlogo* logo = logoGetBuiltin(&os->id, size); if(logo != NULL) return logo; - logo = logoGetBuiltin(os->name.chars); + logo = logoGetBuiltin(&os->name, size); if(logo != NULL) return logo; - logo = logoGetBuiltin(os->prettyName.chars); + logo = logoGetBuiltin(&os->prettyName, size); if(logo != NULL) return logo; - logo = logoGetBuiltin(os->idLike.chars); + logo = logoGetBuiltin(&os->idLike, size); if(logo != NULL) return logo; - logo = logoGetBuiltin(instance.state.platform.systemName.chars); + logo = logoGetBuiltin(&instance.state.platform.systemName, size); if(logo != NULL) return logo; @@ -237,7 +258,7 @@ static const FFlogo* logoGetBuiltinDetected(void) static inline void logoApplyColorsDetected(void) { - logoApplyColors(logoGetBuiltinDetected()); + logoApplyColors(logoGetBuiltinDetected(FF_LOGO_SIZE_NORMAL)); } static void logoPrintStruct(const FFlogo* logo) @@ -263,15 +284,15 @@ static void logoPrintNone(void) instance.state.logoWidth = 0; } -static bool logoPrintBuiltinIfExists(const char* name) +static bool logoPrintBuiltinIfExists(const FFstrbuf* name, FFLogoSize size) { - if(strcasecmp(name, "none") == 0) + if(ffStrbufIgnCaseEqualS(name, "none")) { logoPrintNone(); return true; } - const FFlogo* logo = logoGetBuiltin(name); + const FFlogo* logo = logoGetBuiltin(name, size); if(logo == NULL) return false; @@ -280,12 +301,13 @@ static bool logoPrintBuiltinIfExists(const char* name) return true; } -static inline void logoPrintDetected(void) +static inline void logoPrintDetected(FFLogoSize size) { - logoPrintStruct(logoGetBuiltinDetected()); + logoPrintStruct(logoGetBuiltinDetected(size)); } -static bool logoPrintData(bool doColorReplacement) { +static bool logoPrintData(bool doColorReplacement) +{ FFLogoOptions* options = &instance.config.logo; if(options->source.length == 0) return false; @@ -360,7 +382,10 @@ static bool logoTryKnownType(void) } if(options->type == FF_LOGO_TYPE_BUILTIN) - return logoPrintBuiltinIfExists(options->source.chars); + return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_NORMAL); + + if(options->type == FF_LOGO_TYPE_SMALL) + return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_SMALL); if(options->type == FF_LOGO_TYPE_DATA) return logoPrintData(true); @@ -393,7 +418,7 @@ static bool logoTryKnownType(void) static void logoPrintKnownType(void) { if(!logoTryKnownType()) - logoPrintDetected(); + logoPrintDetected(FF_LOGO_SIZE_UNKNOWN); } void ffLogoPrint(void) @@ -419,7 +444,7 @@ void ffLogoPrint(void) //If the source is not set, we can directly print the detected logo. if(options->source.length == 0) { - logoPrintDetected(); + logoPrintDetected(options->type == FF_LOGO_TYPE_SMALL ? FF_LOGO_SIZE_SMALL : FF_LOGO_SIZE_NORMAL); return; } @@ -431,7 +456,7 @@ void ffLogoPrint(void) } //If source matches the name of a builtin logo, print it and return. - if(logoPrintBuiltinIfExists(options->source.chars)) + if(logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_UNKNOWN)) return; //Make sure the logo path is set correctly. @@ -454,7 +479,7 @@ void ffLogoPrint(void) if(logoPrintFileIfExists(true, false)) return; - logoPrintDetected(); + logoPrintDetected(FF_LOGO_SIZE_UNKNOWN); } void ffLogoPrintLine(void) diff --git a/src/logo/logo.h b/src/logo/logo.h index 4c4d42c3f..6bbfa7cff 100644 --- a/src/logo/logo.h +++ b/src/logo/logo.h @@ -12,6 +12,7 @@ typedef struct FFlogo const char** builtinColors; //Null terminated const char* colorKeys; const char* colorTitle; + bool small; } FFlogo; typedef const FFlogo*(*GetLogoMethod)(); diff --git a/src/logo/option.c b/src/logo/option.c index a277616a8..86433f90f 100644 --- a/src/logo/option.c +++ b/src/logo/option.c @@ -35,8 +35,6 @@ bool ffParseLogoCommandOptions(FFLogoOptions* options, const char* key, const ch if (subKey[0] == '\0') { logoType: - ffOptionParseString(key, value, &options->source); - //this is usally wanted when using the none logo if(strcasecmp(value, "none") == 0) { @@ -45,12 +43,19 @@ logoType: options->paddingLeft = 0; options->type = FF_LOGO_TYPE_NONE; } + else if(strcasecmp(value, "small") == 0) + { + options->type = FF_LOGO_TYPE_SMALL; + } + else + ffOptionParseString(key, value, &options->source); } else if(strcasecmp(subKey, "type") == 0) { options->type = (FFLogoType) ffOptionParseEnum(key, value, (FFKeyValuePair[]) { { "auto", FF_LOGO_TYPE_AUTO }, { "builtin", FF_LOGO_TYPE_BUILTIN }, + { "small", FF_LOGO_TYPE_SMALL }, { "file", FF_LOGO_TYPE_FILE }, { "file-raw", FF_LOGO_TYPE_FILE_RAW }, { "data", FF_LOGO_TYPE_DATA }, @@ -231,6 +236,7 @@ const char* ffParseLogoJsonConfig(void) const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) { { "auto", FF_LOGO_TYPE_AUTO }, { "builtin", FF_LOGO_TYPE_BUILTIN }, + { "small", FF_LOGO_TYPE_SMALL }, { "file", FF_LOGO_TYPE_FILE }, { "file-raw", FF_LOGO_TYPE_FILE_RAW }, { "data", FF_LOGO_TYPE_DATA }, diff --git a/src/logo/option.h b/src/logo/option.h index 09f7822d1..9039b4b57 100644 --- a/src/logo/option.h +++ b/src/logo/option.h @@ -8,6 +8,7 @@ typedef enum FFLogoType { FF_LOGO_TYPE_AUTO, //if something is given, first try builtin, then file. Otherwise detect logo FF_LOGO_TYPE_BUILTIN, //builtin ascii art + FF_LOGO_TYPE_SMALL, //builtin ascii art, small version FF_LOGO_TYPE_FILE, //text file, printed with color code replacement FF_LOGO_TYPE_FILE_RAW, //text file, printed as is FF_LOGO_TYPE_DATA, //text data, printed with color code replacement