Files
optifetch/logos.c
T
2026-06-26 19:24:41 +02:00

94 lines
2.7 KiB
C

#include "optifetch.h"
#define MAX_LOGO_LINES 100
#define MAX_LOGO_WIDTH 512
typedef struct {
char id[64];
char lines[MAX_LOGO_LINES][MAX_LOGO_WIDTH];
int count;
int width;
} LogoCache;
static LogoCache cache_normal[32];
static LogoCache cache_small[32];
static int cache_normal_count = 0;
static int cache_small_count = 0;
static LogoCache* load_logo(const char* os_id, int small) {
LogoCache* cache_arr = small ? cache_small : cache_normal;
int* cache_cnt = small ? &cache_small_count : &cache_normal_count;
for(int i=0; i<*cache_cnt; i++) {
if(strcmp(cache_arr[i].id, os_id) == 0) return &cache_arr[i];
}
if(*cache_cnt >= 32) return NULL;
LogoCache* new_cache = &cache_arr[(*cache_cnt)++];
snprintf(new_cache->id, sizeof(new_cache->id), "%s", os_id);
new_cache->count = 0;
new_cache->width = 0;
char path[256];
snprintf(path, sizeof(path), "logos/%s%s.txt", os_id, small ? "_small" : "");
FILE *f = fopen(path, "r");
if (!f) return new_cache;
char line[MAX_LOGO_WIDTH];
while(fgets(line, sizeof(line), f) && new_cache->count < MAX_LOGO_LINES) {
line[strcspn(line, "\n")] = 0;
snprintf(new_cache->lines[new_cache->count], MAX_LOGO_WIDTH, "%s", line);
int w = 0;
for(int j=0; j<strlen(line); j++) {
if((line[j] & 0xC0) != 0x80) w++;
}
if(w > new_cache->width) new_cache->width = w;
new_cache->count++;
}
fclose(f);
return new_cache;
}
void get_logo_line(const char* os_id, int small, int idx, char* out, size_t size) {
LogoCache* c = load_logo(os_id, small);
if(!c) {
out[0] = '\0';
return;
}
if(idx < c->count) {
snprintf(out, size, "%s", c->lines[idx]);
// CORRECTION : On pad la ligne avec des espaces pour que toutes les lignes du logo
// fassent exactement la même largeur visuelle. C'est vital pour l'alignement.
int current_w = 0;
for(int j=0; j<strlen(out); j++) {
if((out[j] & 0xC0) != 0x80) current_w++;
}
int pad = c->width - current_w;
if(pad > 0) {
int len = strlen(out);
if (len + pad + 1 < (int)size) {
for(int i=0; i<pad; i++) out[len + i] = ' ';
out[len + pad] = '\0';
}
}
} else {
// Lignes en dessous du logo : on remplit par des espaces
if (c->width > 0 && size > (size_t)c->width) {
for(int i=0; i<c->width; i++) out[i] = ' ';
out[c->width] = '\0';
} else {
out[0] = '\0';
}
}
}
int get_logo_height(const char* os_id, int small) {
LogoCache* c = load_logo(os_id, small);
return c ? c->count : 0;
}