From bd3c2364808560e1cd733e8c78894664ff4f7ed8 Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Sun, 23 May 2021 19:40:34 +0200 Subject: [PATCH] a bit better parsing of fonts --- src/common/format.c | 10 ++ src/common/parsing.c | 249 +++++++++++++++++++++++++++++++------ src/fastfetch.c | 31 +++-- src/fastfetch.h | 19 ++- src/modules/font.c | 109 +++++++--------- src/modules/terminal.c | 5 +- src/modules/terminalfont.c | 95 ++++++++------ src/util/FFlist.c | 4 +- src/util/FFlist.h | 4 +- src/util/FFstrbuf.c | 51 ++++++++ src/util/FFstrbuf.h | 4 + 11 files changed, 424 insertions(+), 157 deletions(-) diff --git a/src/common/format.c b/src/common/format.c index dbf152cfa..1d14d521b 100644 --- a/src/common/format.c +++ b/src/common/format.c @@ -14,6 +14,16 @@ void ffFormatAppendFormatArg(FFstrbuf* buffer, const FFformatarg* formatarg) ffStrbufAppend(buffer, (FFstrbuf*)formatarg->value); else if(formatarg->type == FF_FORMAT_ARG_TYPE_DOUBLE) ffStrbufAppendF(buffer, "%g", *(double*)formatarg->value); + else if(formatarg->type == FF_FORMAT_ARG_TYPE_LIST) + { + const FFlist* list = formatarg->value; + for(uint32_t i = 0; i < list->length; i++) + { + ffStrbufAppend(buffer, ffListGet(list, i)); + if(i < list->length - 1) + ffStrbufAppendS(buffer, ", "); + } + } else if(formatarg->type != FF_FORMAT_ARG_TYPE_NULL) { fprintf(stderr, "Error: format string \"%s\": argument is not implemented: %i\n", buffer->chars, formatarg->type); diff --git a/src/common/parsing.c b/src/common/parsing.c index 3263173b4..12f023c49 100644 --- a/src/common/parsing.c +++ b/src/common/parsing.c @@ -1,5 +1,7 @@ #include "fastfetch.h" +#include + void ffGetGtkPretty(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4) { if(gtk2->length > 0 && gtk3->length > 0 && gtk4->length > 0) @@ -80,43 +82,218 @@ void ffGetGtkPretty(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3 } } -void ffGetFont(const char* font, FFstrbuf* name, double* size) +static void fontInit(FFfont* font) { - ffStrbufEnsureCapacity(name, 32); - - int scanned = sscanf(font, "%31[^,], %lf", name->chars, size); - - ffStrbufRecalculateLength(name); - - if(scanned < 2) - *size = 0.0; - - if(scanned == 0) - ffStrbufSetS(name, font); + ffStrbufInit(&font->pretty); + ffStrbufInit(&font->name); + ffStrbufInitA(&font->size, 4); + ffListInitA(&font->styles, sizeof(FFstrbuf), 4); } -void ffGetFontPretty(FFstrbuf* buffer, const FFstrbuf* name, double size) +static void fontInitPretty(FFfont* font) { - ffStrbufAppend(buffer, name); + ffStrbufAppend(&font->pretty, &font->name); - if(size > 0) + if(font->size.length == 0 && font->styles.length == 0) + return; + else if(font->pretty.length == 0) + ffStrbufAppendS(&font->pretty, "default"); + + ffStrbufAppendS(&font->pretty, " ("); + + if(font->size.length > 0) { - ffStrbufAppendS(buffer, " ("); - ffStrbufAppendF(buffer, "%g", size); - ffStrbufAppendS(buffer, "pt)"); + ffStrbufAppend(&font->pretty, &font->size); + ffStrbufAppendS(&font->pretty, "pt"); + + if(font->styles.length > 0) + ffStrbufAppendS(&font->pretty, ", "); } + + for(uint32_t i = 0; i < font->styles.length; i++) + { + ffStrbufAppend(&font->pretty, ffListGet(&font->styles, i)); + + if(i < font->styles.length - 1) + ffStrbufAppendS(&font->pretty, ", "); + } + + ffStrbufAppendC(&font->pretty, ')'); } -static bool getPropValueLine(const char** linePtr, const char* start, FFstrbuf* buffer) +void ffFontInitQt(FFfont* font, const char* data) { - const char* line = *linePtr; + fontInit(font); - if(*line == '\0') + //See https://doc.qt.io/qt-5/qfont.html#toString + + //Family + while(*data != ',' && *data != '\0') + { + ffStrbufAppendC(&font->name, *data); + ++data; + } + if(*data != '\0') + ++data; + ffStrbufTrim(&font->name, ' '); + + //Size + while(*data != ',' && *data != '\0') + { + ffStrbufAppendC(&font->size, *data); + ++data; + } + if(*data != '\0') + ++data; + ffStrbufTrim(&font->size, ' '); + + #define FF_FONT_QT_SKIP_VALUE \ + while(*data != ',' && *data != '\0') \ + ++data; \ + if(*data != '\0') \ + ++data; + + FF_FONT_QT_SKIP_VALUE //Pixel size + FF_FONT_QT_SKIP_VALUE //Style hint + FF_FONT_QT_SKIP_VALUE //Font weight + FF_FONT_QT_SKIP_VALUE //Font style + FF_FONT_QT_SKIP_VALUE //Underline + FF_FONT_QT_SKIP_VALUE //Strike out + FF_FONT_QT_SKIP_VALUE //Fixed pitch + FF_FONT_QT_SKIP_VALUE //Always 0 + + #undef FF_FONT_QT_SKIP_VALUE + + while(*data != '\0') + { + while(*data == ' ') + ++data; + + if(*data == '\0') + break; + + FFstrbuf* style = ffListAdd(&font->styles); + ffStrbufInit(style); + while(*data != ' ' && *data != '\0') + { + ffStrbufAppendC(style, *data); + ++data; + } + } + + fontInitPretty(font); +} + +void fontPangoParseWord(const char** data, FFfont* font, FFstrbuf* alternativeBuffer) +{ + while(**data == ' ' || **data == '\t' || **data == ',') + ++(*data); + + const char* wordStart = *data; + + while(**data != ' ' && **data != '\t' && **data != ',' && **data != '\0' && **data != '`' && **data != '\\') + ++(*data); + + uint32_t wordLength = *data - wordStart; + if(wordLength == 0) + return; + + if(**data == '\0' || **data == '`' || **data == '\\') + { + ffStrbufAppendNS(&font->size, wordLength, wordStart); + if(ffStrbufEndsWithS(&font->size, "px")) + ffStrbufSubstrBefore(&font->size, font->size.length - 2); + + double dummy; + if(sscanf(font->size.chars, "%lf", &dummy) == 1) + return; + + ffStrbufClear(&font->size); + } + + if( + strncasecmp(wordStart, "Ultra", 5) == 0 || + strncasecmp(wordStart, "Extra", 5) == 0 || + strncasecmp(wordStart, "Semi", 4) == 0 || + strncasecmp(wordStart, "Demi", 4) == 0 || + strncasecmp(wordStart, "Normal", wordLength) == 0 || + strncasecmp(wordStart, "Roman", wordLength) == 0 || + strncasecmp(wordStart, "Oblique", wordLength) == 0 || + strncasecmp(wordStart, "Italic", wordLength) == 0 || + strncasecmp(wordStart, "Thin", wordLength) == 0 || + strncasecmp(wordStart, "Light", wordLength) == 0 || + strncasecmp(wordStart, "Bold", wordLength) == 0 || + strncasecmp(wordStart, "Black", wordLength) == 0 || + strncasecmp(wordStart, "Condensed", wordLength) == 0 || + strncasecmp(wordStart, "Expanded", wordLength) == 0 + ) { + if(alternativeBuffer == NULL) + { + alternativeBuffer = ffListAdd(&font->styles); + ffStrbufInit(alternativeBuffer); + } + + ffStrbufAppendNSExludingC(alternativeBuffer, wordLength, wordStart, '-'); + + if( + strncasecmp(wordStart, "Ultra ", 6) == 0 || + strncasecmp(wordStart, "Extra ", 6) == 0 || + strncasecmp(wordStart, "Semi ", 5) == 0 || + strncasecmp(wordStart, "Demi ", 5) == 0 + ) { + fontPangoParseWord(data, font, alternativeBuffer); + } + + return; + } + + if(alternativeBuffer != NULL) + { + ffStrbufAppendNSExludingC(alternativeBuffer, wordLength, wordStart, '-'); + return; + } + + if(font->name.length > 0) + ffStrbufAppendC(&font->name, ' '); + ffStrbufAppendNS(&font->name, wordLength, wordStart); +} + +void ffFontInitPango(FFfont* font, const char* data) +{ + fontInit(font); + + while(*data != '\0' && *data != '`' && *data != '\\') + fontPangoParseWord(&data, font, NULL); + + fontInitPretty(font); +} + +void ffFontInitCopy(FFfont* font, const char* name) +{ + fontInit(font); + ffStrbufAppendS(&font->name, name); + fontInitPretty(font); +} + +void ffFontDestroy(FFfont* font) +{ + ffStrbufDestroy(&font->pretty); + ffStrbufDestroy(&font->name); + ffStrbufDestroy(&font->size); + + for(uint32_t i = 0; i < font->styles.length; i++) + ffStrbufDestroy(ffListGet(&font->styles, i)); + ffListDestroy(&font->styles); +} + +static bool getPropValueLine(const char** line, const char* start, FFstrbuf* buffer) +{ + if(**line == '\0') return false; //Skip any amount of whitespace at the begin of line - while(*line == ' ' || *line == '\t') - ++line; + while(**line == ' ' || **line == '\t') + ++(*line); while(*start != '\0') { @@ -126,43 +303,43 @@ static bool getPropValueLine(const char** linePtr, const char* start, FFstrbuf* while(*start == ' ' || *start == '\t') ++start; - while(*line == ' ' || *line == '\t') - ++line; + while(**line == ' ' || **line == '\t') + ++(*line); continue; } //Line doesn't match start, skip it - if(*line != *start || *line == '\0') + if(**line != *start || **line == '\0') return false; //Line and start match, continue testing - ++line; + ++(*line); ++start; } char valueEnd = '\n'; //Allow faster parsing of XML - if(*(line - 1) == '>') + if(*(*line - 1) == '>') valueEnd = '<'; //Skip any amount of whitespace at the begin of the value - while(*line == ' ' || *line == '\t') - ++line; + while(**line == ' ' || **line == '\t') + ++(*line); //Allow faster parsing of quotet values - if(*line == '"' || *line == '\'') + if(**line == '"' || **line == '\'') { - valueEnd = *line; - ++line; + valueEnd = **line; + ++(*line); } //Copy the value to the buffer - while(*line != valueEnd && *line != '\n' && *line != '\0') + while(**line != valueEnd && **line != '\n' && **line != '\0') { - ffStrbufAppendC(buffer, *line); - ++line; + ffStrbufAppendC(buffer, **line); + ++(*line); } ffStrbufTrimRight(buffer, ' '); diff --git a/src/fastfetch.c b/src/fastfetch.c index 707968a73..d342af3a1 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -353,24 +353,28 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "font-format") == 0) { - constructAndPrintCommandHelpFormat("font", "{4}, {17}", 17, - "Plasma as in resource file", + constructAndPrintCommandHelpFormat("font", "{5} [Plasma], {21}", 21, + "Plasma raw", "Plasma name", "Plasma size", - "Plasma name and size pretty together", - "GTK2 as in resource file", + "Plasma styles", + "Plasma pretty", + "GTK2 raw", "GTK2 name", "GTK2 size", - "GTK2 name and size pretty together", - "GTK3 as in resource file", + "GTK2 styles", + "GTK2 pretty", + "GTK3 raw", "GTK3 name", "GTK3 size", - "GTK3 name and size pretty together", - "GTK4 as in resource file", + "GTK3 styles", + "GTK3 pretty", + "GTK4 raw", "GTK4 name", "GTK4 size", - "GTK4 name and size pretty together", - "GTK 2/3/4 name and size pretty together" + "GTK4 styles", + "GTK4 pretty", + "GTK2/3/4 pretty" ); } else if(strcasecmp(command, "terminal-format") == 0) @@ -383,11 +387,12 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "terminal-font-format") == 0) { - constructAndPrintCommandHelpFormat("terminal-font", "{4}", 4, - "Terminal font as in resource file", + constructAndPrintCommandHelpFormat("terminal-font", "{5}", 5, + "Terminal font raw", "Terminal font name", "Termianl font size", - "Terminal font name and size pretty together" + "Terminal font styles" + "Terminal font pretty" ); } else if(strcasecmp(command, "cpu-format") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index 526263cab..0cecc551b 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -180,7 +180,8 @@ typedef enum FFformatargtype FF_FORMAT_ARG_TYPE_INT, FF_FORMAT_ARG_TYPE_STRING, FF_FORMAT_ARG_TYPE_STRBUF, - FF_FORMAT_ARG_TYPE_DOUBLE + FF_FORMAT_ARG_TYPE_DOUBLE, + FF_FORMAT_ARG_TYPE_LIST } FFformatargtype; typedef struct FFformatarg @@ -212,6 +213,14 @@ typedef union FFvariant }; } FFvariant; +typedef struct FFfont +{ + FFstrbuf pretty; + FFstrbuf name; + FFstrbuf size; + FFlist styles; +} FFfont; + /*************************/ /* Common util functions */ /*************************/ @@ -269,8 +278,12 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, const FFst //common/parsing.c void ffGetGtkPretty(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4); -void ffGetFont(const char* font, FFstrbuf* name, double* size); -void ffGetFontPretty(FFstrbuf* buffer, const FFstrbuf* name, double size); + +void ffFontInitQt(FFfont* font, const char* data); +void ffFontInitPango(FFfont* font, const char* data); +void ffFontInitCopy(FFfont* font, const char* name); +void ffFontDestroy(FFfont* font); + bool ffGetPropValue(const char* line, const char* start, FFstrbuf* buffer); bool ffGetPropValueFromLines(const char* lines, const char* start, FFstrbuf* buffer); diff --git a/src/modules/font.c b/src/modules/font.c index 2453df3fd..7c34beb1c 100644 --- a/src/modules/font.c +++ b/src/modules/font.c @@ -1,95 +1,80 @@ #include "fastfetch.h" #define FF_FONT_MODULE_NAME "Font" -#define FF_FONT_NUM_FORMAT_ARGS 17 +#define FF_FONT_NUM_FORMAT_ARGS 21 void ffPrintFont(FFinstance* instance) { - const FFstrbuf* plasma = &ffDetectPlasma(instance)->font; - const FFstrbuf* gtk2 = &ffDetectGTK2(instance)->font; - const FFstrbuf* gtk3 = &ffDetectGTK3(instance)->font; - const FFstrbuf* gtk4 = &ffDetectGTK4(instance)->font; + const FFstrbuf* plasmaRaw = &ffDetectPlasma(instance)->font; + const FFstrbuf* gtk2Raw = &ffDetectGTK2(instance)->font; + const FFstrbuf* gtk3Raw = &ffDetectGTK3(instance)->font; + const FFstrbuf* gtk4Raw = &ffDetectGTK4(instance)->font; - if(plasma->length == 0 && gtk2->length == 0 && gtk3->length == 0 && gtk4->length == 0) + if(plasmaRaw->length == 0 && gtk2Raw->length == 0 && gtk3Raw->length == 0 && gtk4Raw->length == 0) { ffPrintError(instance, FF_FONT_MODULE_NAME, 0, &instance->config.fontKey, &instance->config.fontFormat, FF_FONT_NUM_FORMAT_ARGS, "No fonts found"); return; } - FF_STRBUF_CREATE(plasmaName); - double plasmaSize; - ffGetFont(plasma->chars, &plasmaName, &plasmaSize); - FF_STRBUF_CREATE(plasmaPretty); - ffGetFontPretty(&plasmaPretty, &plasmaName, plasmaSize); + FFfont plasma; + ffFontInitQt(&plasma, plasmaRaw->chars); - FF_STRBUF_CREATE(gtk2Name); - double gtk2Size; - ffGetFont(gtk2->chars, >k2Name, >k2Size); - FF_STRBUF_CREATE(gtk2Pretty); - ffGetFontPretty(>k2Pretty, >k2Name, gtk2Size); + FFfont gtk2; + ffFontInitPango(>k2, gtk2Raw->chars); - FF_STRBUF_CREATE(gtk3Name); - double gtk3Size; - ffGetFont(gtk3->chars, >k3Name, >k3Size); - FF_STRBUF_CREATE(gtk3Pretty); - ffGetFontPretty(>k3Pretty, >k3Name, gtk3Size); + FFfont gtk3; + ffFontInitPango(>k3, gtk3Raw->chars); - FF_STRBUF_CREATE(gtk4Name); - double gtk4Size; - ffGetFont(gtk4->chars, >k4Name, >k4Size); - FF_STRBUF_CREATE(gtk4Pretty); - ffGetFontPretty(>k4Pretty, >k4Name, gtk4Size); + FFfont gtk4; + ffFontInitPango(>k4, gtk4Raw->chars); - FF_STRBUF_CREATE(gtkPretty); - ffGetGtkPretty(>kPretty, >k2Pretty, >k3Pretty, >k4Pretty); + FFstrbuf gtk; + ffStrbufInit(>k); + ffGetGtkPretty(>k, >k2.pretty, >k3.pretty, >k4.pretty); if(instance->config.fontFormat.length == 0) { ffPrintLogoAndKey(instance, FF_FONT_MODULE_NAME, 0, &instance->config.fontKey); - if(plasma->length > 0) + if(plasma.pretty.length > 0) { - ffStrbufWriteTo(&plasmaPretty, stdout); + ffStrbufWriteTo(&plasma.pretty, stdout); fputs(" [Plasma]", stdout); - if(gtkPretty.length > 0) + if(gtk.length > 0) fputs(", ", stdout); } - ffStrbufPutTo(>kPretty, stdout); + ffStrbufPutTo(>k, stdout); } else { ffPrintFormatString(instance, FF_FONT_MODULE_NAME, 0, &instance->config.fontKey, &instance->config.fontFormat, NULL, FF_FONT_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, plasma}, - {FF_FORMAT_ARG_TYPE_STRBUF, &plasmaName}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &plasmaSize}, - {FF_FORMAT_ARG_TYPE_STRBUF, &plasmaPretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, gtk2}, - {FF_FORMAT_ARG_TYPE_STRBUF, >k2Name}, - {FF_FORMAT_ARG_TYPE_DOUBLE, >k2Size}, - {FF_FORMAT_ARG_TYPE_STRBUF, >k2Pretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, gtk3}, - {FF_FORMAT_ARG_TYPE_STRBUF, >k3Name}, - {FF_FORMAT_ARG_TYPE_DOUBLE, >k3Size}, - {FF_FORMAT_ARG_TYPE_STRBUF, >k3Pretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, gtk4}, - {FF_FORMAT_ARG_TYPE_STRBUF, >k4Name}, - {FF_FORMAT_ARG_TYPE_DOUBLE, >k4Size}, - {FF_FORMAT_ARG_TYPE_STRBUF, >k4Pretty}, - {FF_FORMAT_ARG_TYPE_STRBUF, >kPretty} + {FF_FORMAT_ARG_TYPE_STRBUF, plasmaRaw}, + {FF_FORMAT_ARG_TYPE_STRBUF, &plasma.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &plasma.size}, + {FF_FORMAT_ARG_TYPE_LIST, &plasma.styles}, + {FF_FORMAT_ARG_TYPE_STRBUF, &plasma.pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk2Raw}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k2.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k2.size}, + {FF_FORMAT_ARG_TYPE_LIST, >k2.styles}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k2.pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk3Raw}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k3.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k3.size}, + {FF_FORMAT_ARG_TYPE_LIST, >k3.styles}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k3.pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, gtk4Raw}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k4.name}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k4.size}, + {FF_FORMAT_ARG_TYPE_LIST, >k4.styles}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k4.pretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, >k} }); } - ffStrbufDestroy(&plasmaName); - ffStrbufDestroy(&plasmaPretty); - - ffStrbufDestroy(>k2Name); - ffStrbufDestroy(>k2Pretty); - - ffStrbufDestroy(>k3Name); - ffStrbufDestroy(>k3Pretty); - - ffStrbufDestroy(>k4Name); - ffStrbufDestroy(>k4Pretty); - - ffStrbufDestroy(>kPretty); + ffFontDestroy(&plasma); + ffFontDestroy(>k2); + ffFontDestroy(>k3); + ffFontDestroy(>k4); + ffStrbufDestroy(>k); } diff --git a/src/modules/terminal.c b/src/modules/terminal.c index 1624cd07e..8d91df423 100644 --- a/src/modules/terminal.c +++ b/src/modules/terminal.c @@ -51,8 +51,9 @@ static void getTerminalName(FFinstance* instance, const char* pid, FFTerminalRes strcasecmp(name, "sudo") == 0 || strcasecmp(name, "su") == 0 || strcasecmp(name, "doas") == 0 || - strcasecmp(name, "strace") == 0 ) - { + strcasecmp(name, "strace") == 0 || + strcasecmp(name, "gdb") == 0 + ) { getTerminalName(instance, ppid, result); return; } diff --git a/src/modules/terminalfont.c b/src/modules/terminalfont.c index c2db6e8f1..4cbff47ed 100644 --- a/src/modules/terminalfont.c +++ b/src/modules/terminalfont.c @@ -1,33 +1,31 @@ #include "fastfetch.h" #define FF_TERMFONT_MODULE_NAME "Terminal Font" -#define FF_TERMFONT_NUM_FORMAT_ARGS 4 +#define FF_TERMFONT_NUM_FORMAT_ARGS 5 -static void printTerminalFont(FFinstance* instance, const char* font) +static void printTerminalFont(FFinstance* instance, const char* raw, FFfont* font) { - FF_STRBUF_CREATE(name); - double size; - ffGetFont(font, &name, &size); - FF_STRBUF_CREATE(pretty); - ffGetFontPretty(&pretty, &name, size); + if(font->pretty.length == 0) + { + ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Terminal font is an empty value"); + return; + } if(instance->config.termFontFormat.length == 0) { ffPrintLogoAndKey(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey); - ffStrbufPutTo(&pretty, stdout); + ffStrbufPutTo(&font->pretty, stdout); } else { ffPrintFormatString(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, NULL, FF_TERMFONT_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRING, font}, - {FF_FORMAT_ARG_TYPE_STRBUF, &name}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &size}, - {FF_FORMAT_ARG_TYPE_STRBUF, &pretty} + {FF_FORMAT_ARG_TYPE_STRING, raw}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font->name}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font->size}, + {FF_FORMAT_ARG_TYPE_LIST, &font->styles}, + {FF_FORMAT_ARG_TYPE_STRBUF, &font->pretty} }); } - - ffStrbufDestroy(&name); - ffStrbufDestroy(&pretty); } static const char* getSystemMonospaceFont(FFinstance* instance) @@ -52,16 +50,21 @@ static const char* getSystemMonospaceFont(FFinstance* instance) static void printTerminalFontFromConfigFile(FFinstance* instance, const char* configFile, const char* start) { - FFstrbuf font; - ffStrbufInit(&font); - ffParsePropFileConfig(instance, configFile, start, &font); + FFstrbuf fontName; + ffStrbufInit(&fontName); + ffParsePropFileConfig(instance, configFile, start, &fontName); - if(font.length == 0) + if(fontName.length == 0) ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Couldn't find terminal font in \"$XDG_CONFIG_HOME/%s\"", configFile); else - printTerminalFont(instance, font.chars); + { + FFfont font; + ffFontInitPango(&font, fontName.chars); + printTerminalFont(instance, fontName.chars, &font); + ffFontDestroy(&font); + } - ffStrbufDestroy(&font); + ffStrbufDestroy(&fontName); } static void printTerminalFontFromGSettings(FFinstance* instance, char* profilePath, char* profileList, char* profile) @@ -99,7 +102,10 @@ static void printTerminalFontFromGSettings(FFinstance* instance, char* profilePa if(fontName == NULL) return; - printTerminalFont(instance, fontName); + FFfont font; + ffFontInitPango(&font, fontName); + printTerminalFont(instance, fontName, &font); + ffFontDestroy(&font); } static void printKonsole(FFinstance* instance) @@ -120,16 +126,21 @@ static void printKonsole(FFinstance* instance) ffStrbufAppendS(&profilePath, ".local/share/konsole/"); ffStrbufAppend(&profilePath, &profile); - FFstrbuf font; - ffStrbufInit(&font); - ffParsePropFileHome(instance, profilePath.chars, "Font =", &font); + FFstrbuf fontName; + ffStrbufInit(&fontName); + ffParsePropFileHome(instance, profilePath.chars, "Font =", &fontName); - if(font.length == 0) + if(fontName.length == 0) ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Couldn't find \"Font=%%[^\\n]\" in \"%s\"", profilePath.chars); else - printTerminalFont(instance, font.chars); + { + FFfont font; + ffFontInitQt(&font, fontName.chars); + printTerminalFont(instance, fontName.chars, &font); + ffFontDestroy(&font); + } - ffStrbufDestroy(&font); + ffStrbufDestroy(&fontName); ffStrbufDestroy(&profilePath); ffStrbufDestroy(&profile); } @@ -160,28 +171,38 @@ static void printXCFETerminal(FFinstance* instance) if(fontName == NULL) ffPrintError(instance, FF_TERMFONT_MODULE_NAME, 0, &instance->config.termFontKey, &instance->config.termFontFormat, FF_TERMFONT_NUM_FORMAT_ARGS, "Couldn't find \"xsettings::/Gtk/MonospaceFontName\" in XFConf"); else - printTerminalFont(instance, fontName); + { + FFfont font; + ffFontInitPango(&font, fontName); + printTerminalFont(instance, fontName, &font); + ffFontDestroy(&font); + } } static void printTTY(FFinstance* instance) { - FFstrbuf font; - ffStrbufInit(&font); + FFstrbuf fontName; + ffStrbufInit(&fontName); - ffParsePropFile("/etc/vconsole.conf", "Font =", &font); + ffParsePropFile("/etc/vconsole.conf", "Font =", &fontName); - if(font.length == 0) + if(fontName.length == 0) { - ffStrbufAppendS(&font, "VGA default kernel font "); - ffProcessAppendStdOut(&font, (char* const[]){ + ffStrbufAppendS(&fontName, "VGA default kernel font "); + ffProcessAppendStdOut(&fontName, (char* const[]){ "showconsolefont", "--info", NULL }); } - printTerminalFont(instance, font.chars); - ffStrbufDestroy(&font); + ffStrbufTrimRight(&fontName, ' '); + + FFfont font; + ffFontInitCopy(&font, fontName.chars); + printTerminalFont(instance, fontName.chars, &font); + ffFontDestroy(&font); + ffStrbufDestroy(&fontName); } void ffPrintTerminalFont(FFinstance* instance) diff --git a/src/util/FFlist.c b/src/util/FFlist.c index 7c3b64253..31d7d6500 100644 --- a/src/util/FFlist.c +++ b/src/util/FFlist.c @@ -16,7 +16,7 @@ void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity) list->data = malloc(list->capacity * list->elementSize); } -void* ffListGet(FFlist* list, uint32_t index) +void* ffListGet(const FFlist* list, uint32_t index) { return list->data + (index * list->elementSize); } @@ -33,7 +33,7 @@ void* ffListAdd(FFlist* list) return adress; } -uint32_t ffListFirstIndexComp(FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*)) +uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*)) { for(uint32_t i = 0; i < list->length; i++) { diff --git a/src/util/FFlist.h b/src/util/FFlist.h index 3a0ab4f8d..30cef1b7a 100644 --- a/src/util/FFlist.h +++ b/src/util/FFlist.h @@ -19,11 +19,11 @@ typedef struct FFlist void ffListInit(FFlist* list, uint32_t elementSize); void ffListInitA(FFlist* list, uint32_t elementSize, uint32_t capacity); -void* ffListGet(FFlist* list, uint32_t index); +void* ffListGet(const FFlist* list, uint32_t index); void* ffListAdd(FFlist* list); -uint32_t ffListFirstIndexComp(FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*)); +uint32_t ffListFirstIndexComp(const FFlist* list, void* compElement, bool(*compFunc)(const void*, const void*)); void ffListDestroy(FFlist* list); diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index b37775b34..186d67fa4 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -172,6 +172,7 @@ void ffStrbufAppendS(FFstrbuf* strbuf, const char* value) ffStrbufEnsureFree(strbuf, 16); strbuf->chars[strbuf->length++] = value[i]; } + strbuf->chars[strbuf->length] = '\0'; } @@ -189,6 +190,40 @@ void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value) strbuf->chars[strbuf->length++] = value[i]; } + + strbuf->chars[strbuf->length] = '\0'; +} + +void ffStrbufAppendSExcludingC(FFstrbuf* strbuf, const char* value, char exclude) +{ + if(value == NULL) + return; + + for(uint32_t i = 0; value[i] != '\0'; i++) + { + if(i % 16 == 0) + ffStrbufEnsureFree(strbuf, 16); + + if(value[i] != exclude) + strbuf->chars[strbuf->length++] = value[i]; + } + + strbuf->chars[strbuf->length] = '\0'; +} + +void ffStrbufAppendNSExludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude) +{ + if(value == NULL) + return; + + ffStrbufEnsureFree(strbuf, length); + + for(uint32_t i = 0; i < length; i++) + { + if(value[i] != exclude) + strbuf->chars[strbuf->length++] = value[i]; + } + strbuf->chars[strbuf->length] = '\0'; } @@ -509,6 +544,22 @@ bool ffStrbufStartsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t length, const return true; } +bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end) +{ + uint32_t endLength = strlen(end); + + if(endLength > strbuf->length) + return false; + + for(uint32_t i = 0; i < endLength; ++i) + { + if(strbuf->chars[strbuf->length - endLength + i] != end[i]) + return false; + } + + return true; +} + void ffStrbufRecalculateLength(FFstrbuf* strbuf) { for(strbuf->length = 0; strbuf->chars[strbuf->length] != '\0'; ++strbuf->length); diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 6d197c218..93f04244e 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -45,6 +45,8 @@ void ffStrbufSetVF(FFstrbuf* strbuf, const char* format, va_list arguments); void ffStrbufAppend(FFstrbuf* strbuf, const FFstrbuf* value); void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int(*transformFunc)(int)); +void ffStrbufAppendSExcludingC(FFstrbuf* strbuf, const char* value, char exclude); +void ffStrbufAppendNSExludingC(FFstrbuf* strbuf, uint32_t length, const char* value, char exclude); void ffStrbufAppendS(FFstrbuf* strbuf, const char* value); void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value); void ffStrbufAppendC(FFstrbuf* strbuf, const char c); @@ -91,6 +93,8 @@ bool ffStrbufStartsWithIgnCase(const FFstrbuf* strbuf, const FFstrbuf* start); bool ffStrbufStartsWithIgnCaseS(const FFstrbuf* strbuf, const char* start); bool ffStrbufStartsWithIgnCaseNS(const FFstrbuf* strbuf, uint32_t length, const char* start); +bool ffStrbufEndsWithS(const FFstrbuf* strbuf, const char* end); + void ffStrbufRecalculateLength(FFstrbuf* strbuf); void ffStrbufDestroy(FFstrbuf* strbuf);