]> git.sesse.net Git - ccbs/blobdiff - bigscreen/theme.cpp
Shape text using Pango and HarfBuzz; gives us nice ligatures and exotic scripts.
[ccbs] / bigscreen / theme.cpp
index e873c9d9dfdcb3e16dee7e52bda4298e5384f89b..0b51fe2e8f795d23355af155cd6d1c3e10736dcb 100644 (file)
@@ -5,13 +5,15 @@
 #include <string>
 #include <stdexcept>
 
+#include "theme.h"
+
 std::map<std::string, std::string> config;
 
-void init_theme()
+void read_config(const char *filename)
 {
-       FILE *fp = fopen("theme.config", "rb");
+       FILE *fp = fopen(filename, "r");
        if (fp == NULL)
-               throw std::runtime_error("Couldn't open theme.config.");
+               throw std::runtime_error("Couldn't open theme file.");
 
        while (!feof(fp)) {
                char buf[1024];
@@ -46,25 +48,44 @@ void init_theme()
                        continue;
                }
 
-               config.insert(std::make_pair(key, value));
+               config[key] = value;
        }
        fclose(fp);
 }
 
+void init_theme()
+{
+       read_config("theme.config");
+       try {
+               read_config("theme.config.local");
+       } catch (...) {
+               // Ignore.
+       }
+}
+
 std::string get_theme_config(const std::string &key, const std::string subkey)
 {
        if (config.count(key + "." + subkey)) {
                return config[key + "." + subkey];
        }
 
+       std::string modkey = key;
+       while (modkey.find_last_of(".") != std::string::npos) {
+               modkey.resize(modkey.find_last_of("."));
+               if (config.count(modkey + "." + subkey)) {
+                       return config[modkey + "." + subkey];
+               }
+       }
+
        return config["default." + subkey];
 }
 
-void fill_background(unsigned char *buf, unsigned width, unsigned height)
+void fill_background(unsigned char *buf, const std::string &screen_name, unsigned width, unsigned height)
 {
-       int bg_r = atoi(get_theme_config("background", "red").c_str());
-       int bg_g = atoi(get_theme_config("background", "green").c_str());
-       int bg_b = atoi(get_theme_config("background", "blue").c_str());
+       std::string key = "background." + screen_name;
+       int bg_r = atoi(get_theme_config(key, "red").c_str());
+       int bg_g = atoi(get_theme_config(key, "green").c_str());
+       int bg_b = atoi(get_theme_config(key, "blue").c_str());
 
        unsigned char *ptr = buf;
        for (unsigned i = 0; i < width * height; ++i) {
@@ -73,4 +94,30 @@ void fill_background(unsigned char *buf, unsigned width, unsigned height)
                *ptr++ = bg_r;
                *ptr++ = 0;
        }
+
+       for (unsigned i = 0; i < 10; ++i) {
+               char rectkey[1024];
+               snprintf(rectkey, sizeof(rectkey), "background.%s.rect%u", screen_name.c_str(), i);
+               if (get_theme_config(rectkey, "x0").empty()) {
+                       continue;
+               }
+
+               int x0 = std::max<int>(atoi(get_theme_config(rectkey, "x0").c_str()) * width / LOGICAL_SCREEN_WIDTH, 0);
+               int y0 = std::max<int>(atoi(get_theme_config(rectkey, "y0").c_str()) * height / LOGICAL_SCREEN_HEIGHT, 0);
+               int x1 = std::min<int>(atoi(get_theme_config(rectkey, "x1").c_str()) * width / LOGICAL_SCREEN_WIDTH, width);
+               int y1 = std::min<int>(atoi(get_theme_config(rectkey, "y1").c_str()) * height / LOGICAL_SCREEN_HEIGHT, height);
+               int r = atoi(get_theme_config(rectkey, "red").c_str());
+               int g = atoi(get_theme_config(rectkey, "green").c_str());
+               int b = atoi(get_theme_config(rectkey, "blue").c_str());
+
+               for (int y = y0; y < y1; ++y) {
+                       unsigned char *ptr = buf + (y * width + x0) * 4;
+                       for (int x = x0; x < x1; ++x) {
+                               *ptr++ = b;
+                               *ptr++ = g;
+                               *ptr++ = r;
+                               *ptr++ = 0;
+                       }
+               }
+       }
 }