Blame gdk/win32/bdfcursor.c

Packit Service fb6fa5
/* GDK - The GIMP Drawing Kit
Packit Service fb6fa5
 * Copyright (C) 2001 Stefan Ondrejicka
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is free software; you can redistribute it and/or
Packit Service fb6fa5
 * modify it under the terms of the GNU Lesser General Public
Packit Service fb6fa5
 * License as published by the Free Software Foundation; either
Packit Service fb6fa5
 * version 2 of the License, or (at your option) any later version.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * This library is distributed in the hope that it will be useful,
Packit Service fb6fa5
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service fb6fa5
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit Service fb6fa5
 * Lesser General Public License for more details.
Packit Service fb6fa5
 *
Packit Service fb6fa5
 * You should have received a copy of the GNU Lesser General Public
Packit Service fb6fa5
 * License along with this library; if not, write to the
Packit Service fb6fa5
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit Service fb6fa5
 * Boston, MA 02111-1307, USA.
Packit Service fb6fa5
 */
Packit Service fb6fa5
Packit Service fb6fa5
#include "config.h"
Packit Service fb6fa5
#include <string.h>
Packit Service fb6fa5
#include <stdio.h>
Packit Service fb6fa5
#include <errno.h>
Packit Service fb6fa5
#include <ctype.h>
Packit Service fb6fa5
#include <stdlib.h>
Packit Service fb6fa5
Packit Service fb6fa5
#include <glib.h>
Packit Service fb6fa5
Packit Service fb6fa5
typedef struct {
Packit Service fb6fa5
	gchar	*name;
Packit Service fb6fa5
	gint	id;
Packit Service fb6fa5
	gchar	*bitmap;
Packit Service fb6fa5
	gint	hotx;
Packit Service fb6fa5
	gint	hoty;
Packit Service fb6fa5
} font_info_t;
Packit Service fb6fa5
Packit Service fb6fa5
typedef struct {
Packit Service fb6fa5
	gchar	*name;
Packit Service fb6fa5
	gint	id;
Packit Service fb6fa5
	gint	width;
Packit Service fb6fa5
	gint	height;
Packit Service fb6fa5
	gint	hotx;
Packit Service fb6fa5
	gint	hoty;
Packit Service fb6fa5
	gchar	*data;
Packit Service fb6fa5
} cursor_info_t;
Packit Service fb6fa5
Packit Service fb6fa5
static GSList *fonts = NULL;
Packit Service fb6fa5
static GSList *cursors = NULL;
Packit Service fb6fa5
Packit Service fb6fa5
static gint dw,dh;
Packit Service fb6fa5
Packit Service fb6fa5
static gboolean debug = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
#define HEX(c) (((c) >= '0' && (c) <= '9') ? \
Packit Service fb6fa5
	((c) - '0') : (toupper(c) - 'A' + 10))
Packit Service fb6fa5
Packit Service fb6fa5
static void print_font(fi)
Packit Service fb6fa5
font_info_t *fi;
Packit Service fb6fa5
{
Packit Service fb6fa5
	int x,y;
Packit Service fb6fa5
Packit Service fb6fa5
	for (y = 0; y < dh; y++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		for (x = 0; x < dw; x++)
Packit Service fb6fa5
		{
Packit Service fb6fa5
			printf(fi->bitmap[y*dw+x]? "X" : " ");
Packit Service fb6fa5
		}
Packit Service fb6fa5
		printf("\n");
Packit Service fb6fa5
	}
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void print_cursor(ci)
Packit Service fb6fa5
cursor_info_t *ci;
Packit Service fb6fa5
{
Packit Service fb6fa5
	int x,y;
Packit Service fb6fa5
Packit Service fb6fa5
	for (y = 0; y < ci->height; y++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		printf("/* ");
Packit Service fb6fa5
		for (x = 0; x < ci->width; x++)
Packit Service fb6fa5
		{
Packit Service fb6fa5
			if (ci->hotx == x && ci->hoty == y)
Packit Service fb6fa5
				printf("o");
Packit Service fb6fa5
			else
Packit Service fb6fa5
				switch (ci->data[y*ci->width+x])
Packit Service fb6fa5
				{
Packit Service fb6fa5
					case 0:
Packit Service fb6fa5
						printf(" ");
Packit Service fb6fa5
					break;
Packit Service fb6fa5
					case 1:
Packit Service fb6fa5
						printf(".");
Packit Service fb6fa5
					break;
Packit Service fb6fa5
					case 2:
Packit Service fb6fa5
						printf("X");
Packit Service fb6fa5
					break;
Packit Service fb6fa5
				}
Packit Service fb6fa5
		}
Packit Service fb6fa5
		printf(" */\n");
Packit Service fb6fa5
	}
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint read_bdf_font(fname)
Packit Service fb6fa5
gchar *fname;
Packit Service fb6fa5
{
Packit Service fb6fa5
	FILE *f;
Packit Service fb6fa5
	gchar line[2048];
Packit Service fb6fa5
	gint rv = 0;
Packit Service fb6fa5
	gboolean startchar = FALSE, startbitmap = FALSE;
Packit Service fb6fa5
	gchar *charname,*p,*bitmap;
Packit Service fb6fa5
	gint dx = 0,dy = 0;
Packit Service fb6fa5
	gint w,h,x,y,py;
Packit Service fb6fa5
	gint id,tmp;
Packit Service fb6fa5
Packit Service fb6fa5
	dw = 0;
Packit Service fb6fa5
	dh = 0;
Packit Service fb6fa5
Packit Service fb6fa5
	if (!(f = fopen(fname, "r")))
Packit Service fb6fa5
	{
Packit Service fb6fa5
		perror(fname);
Packit Service fb6fa5
		return -1;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	if (fgets(line, sizeof(line), f) && strncasecmp("STARTFONT ", line, 10))
Packit Service fb6fa5
	{
Packit Service fb6fa5
		printf("!BDF font file\n");
Packit Service fb6fa5
		fclose(f);
Packit Service fb6fa5
		return -1;
Packit Service fb6fa5
	}
Packit Service fb6fa5
	
Packit Service fb6fa5
	p = line;
Packit Service fb6fa5
	while (fgets(line, sizeof(line), f))
Packit Service fb6fa5
	{
Packit Service fb6fa5
		if (!startchar)
Packit Service fb6fa5
		{
Packit Service fb6fa5
			if (!strncasecmp("STARTCHAR ", line, 10))
Packit Service fb6fa5
			{
Packit Service fb6fa5
				startchar = TRUE;
Packit Service fb6fa5
				charname = g_strndup(p + 10,
Packit Service fb6fa5
					strcspn(p+10, "\r\n"));
Packit Service fb6fa5
			}
Packit Service fb6fa5
			else if (!strncasecmp("FONTBOUNDINGBOX ", line, 16))
Packit Service fb6fa5
				sscanf(p+16, "%d %d %d %d", &dw, &dh, &dx, &dy;;
Packit Service fb6fa5
		}
Packit Service fb6fa5
		else
Packit Service fb6fa5
		{
Packit Service fb6fa5
			if (!strncasecmp("ENDCHAR", line, 7))
Packit Service fb6fa5
			{
Packit Service fb6fa5
				font_info_t *nfi;
Packit Service fb6fa5
Packit Service fb6fa5
				if (debug)
Packit Service fb6fa5
					printf(" %*s*/\n", dw, "");
Packit Service fb6fa5
				startchar = FALSE;
Packit Service fb6fa5
				startbitmap = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
				nfi = g_malloc(sizeof(font_info_t));
Packit Service fb6fa5
				memset(nfi, '\0', sizeof(font_info_t));
Packit Service fb6fa5
Packit Service fb6fa5
				nfi->name = charname;
Packit Service fb6fa5
				nfi->id = id;
Packit Service fb6fa5
				nfi->bitmap = bitmap;
Packit Service fb6fa5
				nfi->hotx = 0 - dx;
Packit Service fb6fa5
				nfi->hoty = 0 - dy;
Packit Service fb6fa5
Packit Service fb6fa5
				fonts = g_slist_append(fonts, nfi);
Packit Service fb6fa5
			}
Packit Service fb6fa5
			else if (startbitmap)
Packit Service fb6fa5
			{
Packit Service fb6fa5
				int px,cx;
Packit Service fb6fa5
				guchar mask;
Packit Service fb6fa5
Packit Service fb6fa5
				px = x - dx + py * dw;
Packit Service fb6fa5
				for (cx = 0; cx < w; cx++)
Packit Service fb6fa5
				{
Packit Service fb6fa5
					mask = 1 << (3 - (cx % 4));
Packit Service fb6fa5
Packit Service fb6fa5
					bitmap[px+cx] =
Packit Service fb6fa5
						(mask & HEX(line[cx/4])) != 0;
Packit Service fb6fa5
Packit Service fb6fa5
					if (debug)
Packit Service fb6fa5
						printf(bitmap[px+cx] ? "X" : " ");
Packit Service fb6fa5
				}
Packit Service fb6fa5
				py++;
Packit Service fb6fa5
				if (debug)
Packit Service fb6fa5
					printf(" %*s*/\n/* %*s", dw-w, "", dw+dx, "");
Packit Service fb6fa5
			}
Packit Service fb6fa5
			else if (!strncasecmp("BBX ", line, 4))
Packit Service fb6fa5
			{
Packit Service fb6fa5
				sscanf(p+4, "%d %d %d %d", &w, &h, &x, &y);
Packit Service fb6fa5
				if (debug)
Packit Service fb6fa5
					printf("/* %s: */\n/* %*s", charname, dw+dx, "");
Packit Service fb6fa5
			}
Packit Service fb6fa5
			else if (!strncasecmp("ENCODING ", line, 9))
Packit Service fb6fa5
			{
Packit Service fb6fa5
				if (sscanf(p+9, "%d %d", &tmp, &id) != 2)
Packit Service fb6fa5
					id = tmp;
Packit Service fb6fa5
			}
Packit Service fb6fa5
			else if (!strncasecmp("BITMAP", line, 6))
Packit Service fb6fa5
			{
Packit Service fb6fa5
				py = y - dy;
Packit Service fb6fa5
				startbitmap = TRUE;
Packit Service fb6fa5
				bitmap = g_malloc(dw*dh);
Packit Service fb6fa5
				memset(bitmap, '\0', dw*dh);
Packit Service fb6fa5
			}
Packit Service fb6fa5
		}
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	if (strncasecmp("ENDFONT", line, 7))
Packit Service fb6fa5
		rv = -1;
Packit Service fb6fa5
Packit Service fb6fa5
	fclose(f);
Packit Service fb6fa5
Packit Service fb6fa5
	return rv;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static gint font_info_compare(fi, name)
Packit Service fb6fa5
font_info_t *fi;
Packit Service fb6fa5
char *name;
Packit Service fb6fa5
{
Packit Service fb6fa5
	return strcmp(name, fi->name);
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static cursor_info_t *gen_cursor(bmap, mask)
Packit Service fb6fa5
font_info_t *bmap;
Packit Service fb6fa5
font_info_t *mask;
Packit Service fb6fa5
{
Packit Service fb6fa5
	cursor_info_t *ci;
Packit Service fb6fa5
	int bx = dw,by = dh,ex = 0,ey = 0;
Packit Service fb6fa5
	int i,j;
Packit Service fb6fa5
Packit Service fb6fa5
	for (j = 0; j < dh; j++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		gboolean havep = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
		for (i = 0; i < dw; i++)
Packit Service fb6fa5
		{
Packit Service fb6fa5
			if (bmap->bitmap[j*dw+i] || mask->bitmap[j*dw+i])
Packit Service fb6fa5
			{
Packit Service fb6fa5
				havep = TRUE;
Packit Service fb6fa5
				bx = MIN(bx, i);
Packit Service fb6fa5
				ex = MAX(i+1, ex);
Packit Service fb6fa5
			}
Packit Service fb6fa5
		}
Packit Service fb6fa5
Packit Service fb6fa5
		if (havep)
Packit Service fb6fa5
		{
Packit Service fb6fa5
			by = MIN(by, j);
Packit Service fb6fa5
			ey = MAX(ey, j+1);
Packit Service fb6fa5
		}
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	ci = g_malloc(sizeof(cursor_info_t));
Packit Service fb6fa5
	ci->name = g_strdup(bmap->name);
Packit Service fb6fa5
	ci->id = bmap->id;
Packit Service fb6fa5
Packit Service fb6fa5
	ci->width = ex - bx;
Packit Service fb6fa5
	ci->height = ey - by;
Packit Service fb6fa5
Packit Service fb6fa5
	ci->hotx = bmap->hotx - bx;
Packit Service fb6fa5
	ci->hoty = ci->height - (bmap->hoty - by);
Packit Service fb6fa5
Packit Service fb6fa5
	ci->data = g_malloc(ci->width * ci->height);
Packit Service fb6fa5
	memset(ci->data, '\0', ci->width * ci->height);
Packit Service fb6fa5
Packit Service fb6fa5
	for (j = 0; j < ci->height; j++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		for (i = 0; i < ci->width; i++)
Packit Service fb6fa5
		{
Packit Service fb6fa5
			int ofs = (by + j) * dw + bx + i;
Packit Service fb6fa5
Packit Service fb6fa5
			ci->data[j*ci->width + i] = mask->bitmap[ofs] *
Packit Service fb6fa5
				(1 + bmap->bitmap[ofs]);
Packit Service fb6fa5
		}
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	return ci;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static void compose_cursors_from_fonts()
Packit Service fb6fa5
{
Packit Service fb6fa5
	GSList *l;
Packit Service fb6fa5
Packit Service fb6fa5
	for (l = g_slist_copy (fonts); l; l = g_slist_delete_link (l,l))
Packit Service fb6fa5
	{
Packit Service fb6fa5
		font_info_t *fi = l->data;
Packit Service fb6fa5
		gchar *name;
Packit Service fb6fa5
		GSList *ml;
Packit Service fb6fa5
Packit Service fb6fa5
		name = g_strconcat(fi->name, "_mask", NULL);
Packit Service fb6fa5
Packit Service fb6fa5
		if ((ml = g_slist_find_custom(fonts, name,
Packit Service fb6fa5
			(GCompareFunc) font_info_compare)))
Packit Service fb6fa5
		{
Packit Service fb6fa5
			cursors = g_slist_append(cursors, gen_cursor(l->data, ml->data));
Packit Service fb6fa5
			fonts = g_slist_remove(fonts, l->data);
Packit Service fb6fa5
			fonts = g_slist_remove(fonts, ml->data);
Packit Service fb6fa5
		}
Packit Service fb6fa5
Packit Service fb6fa5
		g_free(name);
Packit Service fb6fa5
	}
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static char *dump_cursor(ci, id)
Packit Service fb6fa5
cursor_info_t *ci;
Packit Service fb6fa5
int id;
Packit Service fb6fa5
{
Packit Service fb6fa5
	static gchar cdata[8192];
Packit Service fb6fa5
	gchar *p;
Packit Service fb6fa5
	gint i;
Packit Service fb6fa5
	gint c;
Packit Service fb6fa5
	gboolean flushed;
Packit Service fb6fa5
Packit Service fb6fa5
	sprintf(cdata, "  { \"%s\", %d, %d, %d, %d, %d, \n    \"",
Packit Service fb6fa5
		ci->name, ci->id, ci->width, ci->height, ci->hotx, ci->hoty);
Packit Service fb6fa5
	p = cdata + strlen(cdata);
Packit Service fb6fa5
Packit Service fb6fa5
	for (i = 0; i < ci->width * ci->height; i++)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		flushed = FALSE;
Packit Service fb6fa5
Packit Service fb6fa5
		if (!(i%4))
Packit Service fb6fa5
			c = 0;
Packit Service fb6fa5
Packit Service fb6fa5
		c = c << 2;
Packit Service fb6fa5
Packit Service fb6fa5
		c += ci->data[i];
Packit Service fb6fa5
Packit Service fb6fa5
		if ((i % 4) == 3)
Packit Service fb6fa5
		{
Packit Service fb6fa5
			flushed = TRUE;
Packit Service fb6fa5
			sprintf(p, "\\%03o", c);
Packit Service fb6fa5
			p += strlen(p);
Packit Service fb6fa5
		}
Packit Service fb6fa5
Packit Service fb6fa5
		if (i > 0 && !(i % 64))
Packit Service fb6fa5
		{
Packit Service fb6fa5
			strcpy(p ,"\"\n    \"");
Packit Service fb6fa5
			p += strlen(p);
Packit Service fb6fa5
		}
Packit Service fb6fa5
	}
Packit Service fb6fa5
	if (!flushed)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		sprintf(p, "\\%03o", c);
Packit Service fb6fa5
		p += strlen(p);
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	strcpy(p, "\" }");
Packit Service fb6fa5
Packit Service fb6fa5
	return cdata;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
static int dump_cursors()
Packit Service fb6fa5
{
Packit Service fb6fa5
	GSList *ptr;
Packit Service fb6fa5
	FILE *f = stdout;
Packit Service fb6fa5
Packit Service fb6fa5
	fprintf(f, "static const struct { const gchar *name; gint type; guchar width; guchar height; guchar hotx; guchar hoty; guchar *data; } cursors[] = {\n");
Packit Service fb6fa5
Packit Service fb6fa5
	for (ptr = cursors; ptr; ptr = ptr->next)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		if (debug)
Packit Service fb6fa5
			print_cursor(ptr->data);
Packit Service fb6fa5
		fprintf(f, "%s, \n", dump_cursor(ptr->data));
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	fprintf(f, "  { NULL, 0, 0, 0, 0, 0, NULL },\n};\n");
Packit Service fb6fa5
Packit Service fb6fa5
	return 0;
Packit Service fb6fa5
}
Packit Service fb6fa5
Packit Service fb6fa5
gint main(argc, argv)
Packit Service fb6fa5
gint argc;
Packit Service fb6fa5
gchar **argv;
Packit Service fb6fa5
{
Packit Service fb6fa5
	if (argc != 2)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		printf("missing parameters !\n");
Packit Service fb6fa5
		printf("Usage: %s [BDF cursor file]\n", argv[0]);
Packit Service fb6fa5
		return -1;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	if (g_getenv ("BDFCURSOR_DEBUG") != NULL)
Packit Service fb6fa5
	  debug = TRUE;
Packit Service fb6fa5
Packit Service fb6fa5
	if (read_bdf_font(argv[1]) || !fonts)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		printf("Error reading font\n");
Packit Service fb6fa5
		return 1;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	compose_cursors_from_fonts();
Packit Service fb6fa5
Packit Service fb6fa5
	if (!cursors)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		printf("failed to generate cursors from font!\n");
Packit Service fb6fa5
		return 1;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	dump_cursors();
Packit Service fb6fa5
Packit Service fb6fa5
	if (fonts)
Packit Service fb6fa5
	{
Packit Service fb6fa5
		printf("some fonts remained unconverted!\n");
Packit Service fb6fa5
		return 1;
Packit Service fb6fa5
	}
Packit Service fb6fa5
Packit Service fb6fa5
	return 0;
Packit Service fb6fa5
}
Packit Service fb6fa5