Lagrange [work/v1.6]

Color: Load palettes from a config file

=> aac0bc8a49d06fffcaca7a1fd3c35de035ac3e7c

diff --git a/src/app.c b/src/app.c
index 749d998e..3a1ee101 100644
--- a/src/app.c
+++ b/src/app.c
@@ -761,6 +761,7 @@ static void init_App_(iApp *d, int argc, char **argv) {
     setupApplication_iOS();
 #endif
     init_Keys();
+    loadPalette_Color(dataDir_App_());
     setThemePalette_Color(d->prefs.theme); /* default UI colors */
     loadPrefs_App_(d);
     load_Keys(dataDir_App_());
diff --git a/src/ui/color.c b/src/ui/color.c
index 6c51bc06..05ec1f6f 100644
--- a/src/ui/color.c
+++ b/src/ui/color.c
@@ -24,11 +24,13 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
 #include "root.h"
 #include "app.h"
 
+#include 
+#include 
 #include 
 
 static const iColor transparent_;
 
-static const iColor darkPalette_[] = {
+static iColor darkPalette_[] = {
     { 0,   0,   0,   255 },
     { 40,  40,  40,  255 },
     { 80,  80,  80,  255 },
@@ -47,7 +49,7 @@ static const iColor darkPalette_[] = {
     { 0,   200, 0,   255 },
 };
 
-static const iColor lightPalette_[] = {
+static iColor lightPalette_[] = {
     { 0,   0,   0,   255 },
     { 75,  75,  75,  255 },
     { 150, 150, 150, 255 },
@@ -804,3 +806,77 @@ iColor ansiForeground_Color(iRangecc escapeSequence, int fallback) {
     }
     return clr;
 }
+
+iBool loadPalette_Color(const char *path) {
+    iBool wasLoaded = iFalse;
+    iFile *f = newCStr_File(concatPath_CStr(path, "palette.txt"));
+    if (open_File(f, text_FileMode | readOnly_FileMode)) {
+        iColor *dstPal = darkPalette_;
+        iRangecc srcLine = iNullRange;
+        const iBlock *src = collect_Block(readAll_File(f));
+        while (nextSplit_Rangecc(range_Block(src), "\n", &srcLine)) {
+            iRangecc line = srcLine;
+            trim_Rangecc(&line);
+            if (isEmpty_Range(&line)) {
+                continue;
+            }
+            if (*line.start == '#') {
+                /* Control directive. */
+                line.start++;
+                trim_Rangecc(&line);
+                if (equalCase_Rangecc(line, "dark")) {
+                    dstPal = darkPalette_;
+                }
+                else if (equalCase_Rangecc(line, "light")) {
+                    dstPal = lightPalette_;
+                }
+                continue;
+            }
+            static const struct {
+                const char *label;
+                int         paletteIndex;
+            } colors_[] = {
+                { "black:", 0 }, { "gray25:", 1 }, { "gray50:", 2 }, { "gray75:", 3 },
+                { "white:", 4 }, { "brown:", 5 },  { "orange:", 6 }, { "teal:", 7 },
+                { "cyan:", 8 },  { "yellow:", 9 }, { "red:", 10 },   { "magenta:", 11 },
+                { "blue:", 12 }, { "green:", 13 },
+            };
+            iForIndices(i, colors_) {
+                if (startsWithCase_Rangecc(line, colors_[i].label)) {
+                    iColor *dst = &dstPal[colors_[i].paletteIndex];
+                    line.start += strlen(colors_[i].label);
+                    trim_Rangecc(&line);
+                    if (!isEmpty_Range(&line)) {
+                        if (*line.start == '#') {
+                            /* Hexadecimal color. */
+                            line.start++;
+                            if (size_Range(&line) == 6) {
+                                iBlock *vals = hexDecode_Rangecc(line);
+                                iAssert(size_Block(vals) == 3);
+                                const uint8_t *rgb = constData_Block(vals);
+                                *dst = (iColor){ rgb[0], rgb[1], rgb[2], 255 };
+                                delete_Block(vals);
+                            }
+                            else {
+                                fprintf(stderr, "[Color] invalid custom color: %s\n",
+                                        cstr_Rangecc(line));
+                            }
+                        }
+                        else {
+                            unsigned int red = 0, green = 0, blue = 0;
+                            sscanf(line.start, "%u %u %u", &red, &green, &blue);
+                            if (red > 255 || green > 255 || blue > 255) {
+                                fprintf(stderr, "[Color] RGB value(s) out of range: %s\n",
+                                        cstr_Rangecc(line));
+                            }
+                            *dst = (iColor){ red, green, blue, 255 };
+                        }
+                    }
+                }
+            }
+        }
+        wasLoaded = iTrue;
+    }
+    iRelease(f);
+    return wasLoaded;
+}
diff --git a/src/ui/color.h b/src/ui/color.h
index aafc1794..37ec49eb 100644
--- a/src/ui/color.h
+++ b/src/ui/color.h
@@ -244,7 +244,9 @@ iLocalDef void setHsl_Color(int color, iHSLColor hsl) {
     set_Color(color, rgb_HSLColor(hsl));
 }
 
+iBool           loadPalette_Color       (const char *path);
 void            setThemePalette_Color   (enum iColorTheme theme);
 
 iColor          ansiForeground_Color    (iRangecc escapeSequence, int fallback);
 const char *    escape_Color            (int color);
+
Proxy Information
Original URL
gemini://git.skyjake.fi/lagrange/work%2Fv1.6/cdiff/aac0bc8a49d06fffcaca7a1fd3c35de035ac3e7c
Status Code
Success (20)
Meta
text/gemini; charset=utf-8
Capsule Response Time
69.181033 milliseconds
Gemini-to-HTML Time
0.455419 milliseconds

This content has been proxied by September (3851b).