From fea9cac21e3965ff96d327b059444fb80d1961b4 Mon Sep 17 00:00:00 2001 From: NishiOwO Date: Sun, 28 Dec 2025 16:06:21 +0900 Subject: [PATCH] improve icon lookup --- core/CMakeLists.txt | 2 + core/icon.c | 179 ++++++++++++++++++++++++++------------ core/stb_ds.c | 2 + core/string.c | 19 ++++ include/MDE/Core/String.h | 4 + 5 files changed, 151 insertions(+), 55 deletions(-) create mode 100644 core/stb_ds.c diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt index 329858c..b1fc30d 100644 --- a/core/CMakeLists.txt +++ b/core/CMakeLists.txt @@ -9,3 +9,5 @@ if(NOT CMAKE_SYSTEM_NAME STREQUAL "Windows") pthread ) endif() + +mde_pkg_config_add(MDECore inih) diff --git a/core/icon.c b/core/icon.c index 08942fb..279a913 100644 --- a/core/icon.c +++ b/core/icon.c @@ -3,73 +3,142 @@ #include #include -static char* try_file(const char* path, const char* genre, const char* name, int size) { - char sz[512]; - char* s; - char* s2; - char* s3; - char* s4; - char* s5; - char* s6; - char* t; - FILE* f; +#include +#include - sprintf(sz, "%dx%d", size, size); +typedef struct entry { + char* key; + int value; + char* genre; + int scalable; +} entry_t; - s = MDEStringConcatenate(path, "/"); - s2 = MDEStringConcatenate(s, sz); - s3 = MDEStringConcatenate(s2, "/"); - s4 = MDEStringConcatenate(s3, genre); - s5 = MDEStringConcatenate(s4, "/"); - s6 = MDEStringConcatenate(s5, name); - t = MDEStringConcatenate(s6, ".png"); +typedef struct opaque { + entry_t* entries; +} opaque_t; - free(s6); - free(s5); - free(s4); - free(s3); - free(s2); - free(s); +static int dumper(void* user, const char* section, const char* key, const char* value) { + opaque_t* o = user; - if((f = fopen(t, "rb")) == NULL) { - free(t); - return NULL; + if(strcmp(section, "Icon Theme") != 0 && strcmp(key, "Size") == 0 && value != NULL) { + int v = atoi(value); + int ind; + + if((ind = shgeti(o->entries, section)) == -1) { + shput(o->entries, section, 0); + + ind = shgeti(o->entries, section); + + o->entries[ind].genre = NULL; + o->entries[ind].scalable = 0; + } + + o->entries[ind].value = v; + } else if(strcmp(section, "Icon Theme") != 0 && strcmp(key, "Context") == 0 && value != NULL) { + int v = atoi(value); + int ind; + + if((ind = shgeti(o->entries, section)) == -1) { + shput(o->entries, section, 0); + + ind = shgeti(o->entries, section); + + o->entries[ind].genre = NULL; + o->entries[ind].scalable = 0; + } + + if(o->entries[ind].genre != NULL) free(o->entries[ind].genre); + o->entries[ind].genre = MDEStringDuplicate(value); + } else if(strcmp(section, "Icon Theme") != 0 && strcmp(key, "Type") == 0 && value != NULL && strcmp(value, "Scalable") == 0) { + int ind; + + if((ind = shgeti(o->entries, section)) == -1) { + shput(o->entries, section, 0); + + ind = shgeti(o->entries, section); + + o->entries[ind].genre = NULL; + o->entries[ind].scalable = 0; + } + + o->entries[ind].scalable = 1; } - fclose(f); - return t; + return 1; +} + +static int sort_num(const void* a, const void* b) { + return ((entry_t*)b)->value - ((entry_t*)a)->value; +} + +static char* try_icon(const char* dir, const char* genre, const char* name, int size) { + opaque_t o; + char* ini = MDEStringConcatenate(dir, "/index.theme"); + char* p = NULL; + int i; + + o.entries = NULL; + + sh_new_strdup(o.entries); + + if(ini_parse(ini, dumper, &o) >= 0) { + entry_t* a = NULL; + + for(i = 0; i < shlen(o.entries); i++) arrput(a, o.entries[i]); + + qsort(a, arrlen(a), sizeof(*a), sort_num); + + for(i = 0; i < arrlen(a); i++) { + char* pth = NULL; + int c = (genre == NULL || (a[i].genre != NULL && strcmp(genre, a[i].genre) == 0)) ? 1 : 0; + + if(size == 0 && c) { + pth = MDEStringConcatenate3(dir, "/", a[i].key); + } else if(size == a[i].value && c) { + pth = MDEStringConcatenate3(dir, "/", a[i].key); + } + + if(pth != NULL) { + char* f = MDEStringConcatenate4(pth, "/", name, ".png"); + FILE* fp = fopen(f, "rb"); + + if(fp != NULL) { + if(p != NULL) free(p); + p = f; + + fclose(fp); + + free(pth); + + break; + } else { + free(f); + } + + free(pth); + } + } + + arrfree(a); + } + + for(i = 0; i < shlen(o.entries); i++) { + if(o.entries[i].genre != NULL) free(o.entries[i].genre); + } + shfree(o.entries); + + return p; } char* MDEIconLookUp(const char* genre, const char* name, int size) { - char* s; - const char* g = genre; - int i = 0; - const char* genres[] = { - "actions", - "apps", - "categories", - "devices", - "emblems", - "emotes", - "mimetypes", - "places", - "status", - NULL}; + char* s; - do { - if(genre == NULL) g = genres[i]; - if(g == NULL) break; - if((s = try_file(DATAROOTDIR "/icons/mde", g, name, size)) != NULL) return s; - if((s = try_file(DATAROOTDIR "/icons/hicolor", g, name, size)) != NULL) return s; + if((s = try_icon(DATAROOTDIR "/icons/mde", genre, name, size)) != NULL) return s; + if((s = try_icon(DATAROOTDIR "/icons/hicolor", genre, name, size)) != NULL) return s; #ifdef __NetBSD__ - if((s = try_file("/usr/pkg/share/icons/hicolor", g, name, size)) != NULL) return s; + if((s = try_icon("/usr/pkg/share/icons/hicolor", genre, name, size)) != NULL) return s; #endif - if((s = try_file("/usr/share/icons/hicolor", g, name, size)) != NULL) return s; - - i++; - - if(genre != NULL) break; - } while(1); + if((s = try_icon("/usr/share/icons/hicolor", genre, name, size)) != NULL) return s; return NULL; } diff --git a/core/stb_ds.c b/core/stb_ds.c new file mode 100644 index 0000000..689615c --- /dev/null +++ b/core/stb_ds.c @@ -0,0 +1,2 @@ +#define STB_DS_IMPLEMENTATION +#include diff --git a/core/string.c b/core/string.c index 29bef70..83ba086 100644 --- a/core/string.c +++ b/core/string.c @@ -15,3 +15,22 @@ char* MDEStringConcatenate(const char* str1, const char* str2) { return r; } + +char* MDEStringConcatenate3(const char* str1, const char* str2, const char* str3) { + char* r = malloc(strlen(str1) + strlen(str2) + strlen(str3) + 1); + strcpy(r, str1); + strcat(r, str2); + strcat(r, str3); + + return r; +} + +char* MDEStringConcatenate4(const char* str1, const char* str2, const char* str3, const char* str4) { + char* r = malloc(strlen(str1) + strlen(str2) + strlen(str3) + strlen(str4) + 1); + strcpy(r, str1); + strcat(r, str2); + strcat(r, str3); + strcat(r, str4); + + return r; +} diff --git a/include/MDE/Core/String.h b/include/MDE/Core/String.h index a85e8b4..f09bff9 100644 --- a/include/MDE/Core/String.h +++ b/include/MDE/Core/String.h @@ -11,6 +11,10 @@ char* MDEStringDuplicate(const char* src); char* MDEStringConcatenate(const char* str1, const char* str2); +char* MDEStringConcatenate3(const char* str1, const char* str2, const char* str3); + +char* MDEStringConcatenate4(const char* str1, const char* str2, const char* str3, const char* str4); + #ifdef __cplusplus } #endif