27 static GSList *fonts = NULL;
28 static GSList *cursors = NULL;
32 #define HEX(c) (((c) >= '0' && (c) <= '9') ? \
33 ((c) - '0') : (toupper(c) - 'A' + 10))
35 static void print_font(fi)
40 for (y = 0; y < dh; y++)
42 for (x = 0; x < dw; x++)
44 printf(fi->bitmap[y*dw+x]? "X" : " ");
50 static void print_cursor(ci)
55 for (y = 0; y < ci->height; y++)
57 for (x = 0; x < ci->width; x++)
59 if (ci->hotx == x && ci->hoty == y)
62 switch (ci->data[y*ci->width+x])
79 static gint read_bdf_font(fname)
85 gboolean startchar = FALSE, startbitmap = FALSE;
86 gchar *charname,*p,*bitmap;
94 if (!(f = fopen(fname, "r")))
100 if (fgets(line, sizeof(line), f) && strncasecmp("STARTFONT ", line, 10))
102 printf("!BDF font file\n");
108 while (fgets(line, sizeof(line), f))
112 if (!strncasecmp("STARTCHAR ", line, 10))
115 charname = g_strndup(p + 10,
116 strcspn(p+10, "\r\n"));
118 else if (!strncasecmp("FONTBOUNDINGBOX ", line, 16))
119 sscanf(p+16, "%d %d %d %d", &dw, &dh, &dx, &dy);
123 if (!strncasecmp("ENDCHAR", line, 7))
130 nfi = g_malloc(sizeof(font_info_t));
131 memset(nfi, '\0', sizeof(font_info_t));
133 nfi->name = charname;
135 nfi->bitmap = bitmap;
139 fonts = g_slist_append(fonts, nfi);
141 else if (startbitmap)
146 px = x - dx + py * dw;
147 for (cx = 0; cx < w; cx++)
149 mask = 1 << (3 - (cx % 4));
152 (mask & HEX(line[cx/4])) != 0;
154 /*printf(bitmap[px+cx] ? "X" : " ");*/
159 else if (!strncasecmp("BBX ", line, 4))
160 sscanf(p+4, "%d %d %d %d", &w, &h, &x, &y);
161 else if (!strncasecmp("ENCODING ", line, 9))
163 if (sscanf(p+9, "%d %d", &tmp, &id) != 2)
166 else if (!strncasecmp("BITMAP", line, 6))
170 bitmap = g_malloc(dw*dh);
171 memset(bitmap, '\0', dw*dh);
176 if (strncasecmp("ENDFONT", line, 7))
184 static gint font_info_compare(fi, name)
188 return strcmp(name, fi->name);
191 static cursor_info_t *gen_cursor(bmap, mask)
196 int bx = dw,by = dh,ex = 0,ey = 0;
199 for (j = 0; j < dh; j++)
201 gboolean havep = FALSE;
203 for (i = 0; i < dw; i++)
205 if (bmap->bitmap[j*dw+i] || mask->bitmap[j*dw+i])
220 ci = g_malloc(sizeof(cursor_info_t));
221 ci->name = g_strdup(bmap->name);
225 ci->height = ey - by;
227 ci->hotx = bmap->hotx - bx;
228 ci->hoty = ci->height - (bmap->hoty - by);
230 ci->data = g_malloc(ci->width * ci->height);
231 memset(ci->data, '\0', ci->width * ci->height);
233 for (j = 0; j < ci->height; j++)
235 for (i = 0; i < ci->width; i++)
237 int ofs = (by + j) * dw + bx + i;
239 ci->data[j*ci->width + i] = mask->bitmap[ofs] *
240 (1 + bmap->bitmap[ofs]);
247 static void compose_cursors_from_fonts()
251 for (l = g_slist_copy(fonts); l; l = g_slist_remove_link(l,l))
253 font_info_t *fi = l->data;
257 name = g_strconcat(fi->name, "_mask", NULL);
259 if ((ml = g_slist_find_custom(fonts, name,
260 (GCompareFunc) font_info_compare)))
262 cursors = g_slist_append(cursors, gen_cursor(l->data, ml->data));
263 fonts = g_slist_remove(fonts, l->data);
264 fonts = g_slist_remove(fonts, ml->data);
271 static char *dump_cursor(ci, id)
275 static gchar cdata[8192];
281 sprintf(cdata, " { \"%s\", %d, %d, %d, %d, %d, \n \"",
282 ci->name, ci->id, ci->width, ci->height, ci->hotx, ci->hoty);
283 p = cdata + strlen(cdata);
285 for (i = 0; i < ci->width * ci->height; i++)
299 sprintf(p, "\\%03o", c);
303 if (i > 0 && !(i % 64))
305 strcpy(p ,"\"\n \"");
311 sprintf(p, "\\%03o", c);
320 static int dump_cursors()
325 fprintf(f, "static const struct { const gchar *name; gint type; guchar width; guchar height; guchar hotx; guchar hoty; guchar *data; } cursors[] = {\n");
327 for (ptr = cursors; ptr; ptr = ptr->next)
329 /* print_cursor(ptr->data); */
330 fprintf(f, "%s, \n", dump_cursor(ptr->data));
333 fprintf(f, " { NULL, 0, 0, 0, 0, 0, NULL },\n};\n");
338 gint main(argc, argv)
344 printf("missing parameters !\n");
345 printf("Usage: %s [BDF cursor file]\n", argv[0]);
349 if (read_bdf_font(argv[1]) || !fonts)
351 printf("Error reading font\n");
355 compose_cursors_from_fonts();
359 printf("failed to generate cursors from font!\n");
367 printf("some fonts remained unconverted!\n");