Blob Blame Raw

#include <glib.h>

#include "private.h"


cairo_t *heliCairo;
int heliInitialized;
HeliArray heliObjectsSet;


struct _Directory {
	HeliArray files;
};


static char *colors[] = {
	"transparent", "0 0 0 0",
	
	"black",       "0 0 0 1",
	"white",       "1 1 1 1",
	"gray",        "0.5 0.5 0.5 1",
	
	"red",         "1 0 0 1",
	"green"        "0 1 0 1",
	"blue"         "0 0 1 1",
	
	"yellow",      "1 1 0 1",
	"magenta",     "1 0 1 1",
	"cyan",        "0 1 1 1",

	"yellow",      "1 1 0 1",
	"magenta",     "1 0 1 1",
	"cyan",        "0 1 1 1",
	
	"brown",       "0.5 0.5 0 1",
};


int randomNumber(int min, int max)
	{ return max <= min ? min : rand()%(max - min + 1) + min; }

double randomFloat()
	{ return (double)rand()/(double)RAND_MAX; }


Directory openDirectory(const char *path) {
	if (!heliInitialized) return NULL;

	GDir *dir = g_dir_open(path, 0, NULL);
	if (!dir) return NULL;
	
	Directory d = calloc(1, sizeof(Directory));
	while(TRUE) {
		const char* name = g_dir_read_name(dir);
		if (!name) break;
		if (strcmp(name, ".") == 0 || strcmp(name, "..") == 0) continue;
		heliStringmapAdd(&d->files, name, NULL, NULL);
	}
	g_dir_close(dir);
	
	heliObjectRegister(d, (HeliFreeCallback)&closeDirectory);
	return d;
}

void closeDirectory(Directory directory) {
	if (!directory) return;
	heliObjectUnregister(directory);
	heliArrayDestroy(&directory->files);
	free(directory);
}

int directoryGetCount(Directory directory)
	{ return directory->files.count; }

const char* directoryGet(Directory directory, int i)
	{ return (const char*)heliArrayGetKey(&directory->files, i); }


int fileExists(const char *path)
	{ return g_file_test(path, G_FILE_TEST_IS_REGULAR) ? TRUE : FALSE; }
int directoryExists(const char *path)
	{ return g_file_test(path, G_FILE_TEST_IS_DIR) ? TRUE : FALSE; }


char* heliStringCopy(const char *x) {
	int len = strlen(x) + 1;
	char *cp = malloc(len + 1);
	memcpy(cp, x, len);
	return cp;
}

char* heliStringConcat3(const char *a, const char *b, const char *c) {
	int la = strlen(a);
	int lb = strlen(b);
	int lc = strlen(c);
	char *s = malloc(la + lb + lc + 1);
	memcpy(s, a, la);
	memcpy(s + la, b, lb);
	memcpy(s + la + lb, c, lc);
	s[la + lb + lc] = 0;
	return s;
}

int heliStringEndsWithLowcase(const char *s, const char *tail) {
	int ls = strlen(s);
	int lt = strlen(tail);
	if (lt > ls) return FALSE;
	for(int i = 0; i < lt; ++i)
		if (tolower(s[ls - i]) != tolower(tail[lt - i]))
			return FALSE;
	return TRUE;
}

void heliLowercase(char *x)
	{ while(*x) { *x = tolower(*x); ++x; } }


void heliParseColor(const char *x, double *color) {
	color[0] = color[1] = color[2] = 0;
	color[3] = 1;
	
	if (*x == '#') {
		++x;
		int hex[8] = { 0, 0, 0, 0, 0, 0, 15, 15 };
		for(int i = 0; *x && i < 8; ++i) {
			char c = tolower(*x);
			if (c >= '0' && c <= '9') hex[i] = c - '0';
			if (c >= 'a' && c <= 'f') hex[i] = c - 'a' + 10;
		}
		for(int i = 0; i < 4; ++i)
			color[i] = (hex[i*2]*16 + hex[i*2 + 1])/255.0;
	} else
	if (isalpha(*x)) {
		int count = (int)(sizeof(colors)/sizeof(*colors)/2);
		for(int i = 0; i < count; ++i)
			if (strcmp(x, colors[i*2]) == 0)
				{ heliParseColor(colors[i*2 + 1], color); return; }
	} else {
		sscanf(x, "%lf %lf %lf %lf", &color[0], &color[1], &color[2], &color[3]);
	}
}


static int objectsCompare(const void *a, const void *b)
	{ return a < b ? -1 : b < a ? 1 : 0; }

static void* objectsKeyClone(void *k)
	{ return k; }

void heliObjectRegister(void *o, HeliFreeCallback fo)
	{ heliMapAdd(&heliObjectsSet, o, &objectsCompare, (HeliCloneCallback)objectsKeyClone, fo, NULL, NULL); }

void heliObjectUnregister(void *o) {
	int i;
	HeliPair *item = heliMapFind(&heliObjectsSet, o, &objectsCompare, &i);
	if (item) {
		item->freeKey = NULL;
		heliArrayRemove(&heliObjectsSet, i);
	}
}