]> Pileus Git - ~andy/gtk/blob - gdk/win32/bdfcursor.c
Updated Azeri and Walloon files
[~andy/gtk] / gdk / win32 / bdfcursor.c
1 #include <string.h>
2 #include <stdio.h>
3 #include <errno.h>
4 #include <ctype.h>
5 #include <stdlib.h>
6
7 #include <glib.h>
8
9 typedef struct {
10         gchar   *name;
11         gint    id;
12         gchar   *bitmap;
13         gint    hotx;
14         gint    hoty;
15 } font_info_t;
16
17 typedef struct {
18         gchar   *name;
19         gint    id;
20         gint    width;
21         gint    height;
22         gint    hotx;
23         gint    hoty;
24         gchar   *data;
25 } cursor_info_t;
26
27 static GSList *fonts = NULL;
28 static GSList *cursors = NULL;
29
30 gint dw,dh;
31
32 #define HEX(c) (((c) >= '0' && (c) <= '9') ? \
33         ((c) - '0') : (toupper(c) - 'A' + 10))
34
35 static void print_font(fi)
36 font_info_t *fi;
37 {
38         int x,y;
39
40         for (y = 0; y < dh; y++)
41         {
42                 for (x = 0; x < dw; x++)
43                 {
44                         printf(fi->bitmap[y*dw+x]? "X" : " ");
45                 }
46                 printf("\n");
47         }
48 }
49
50 static void print_cursor(ci)
51 cursor_info_t *ci;
52 {
53         int x,y;
54
55         for (y = 0; y < ci->height; y++)
56         {
57                 for (x = 0; x < ci->width; x++)
58                 {
59                         if (ci->hotx == x && ci->hoty == y)
60                                 printf ("o");
61                         else
62                                 switch (ci->data[y*ci->width+x])
63                                 {
64                                         case 0:
65                                                 printf(" ");
66                                         break;
67                                         case 1:
68                                                 printf(".");
69                                         break;
70                                         case 2:
71                                                 printf("X");
72                                         break;
73                                 }
74                 }
75                 printf("\n");
76         }
77 }
78
79 static gint read_bdf_font(fname)
80 gchar *fname;
81 {
82         FILE *f;
83         gchar line[2048];
84         gint rv = 0;
85         gboolean startchar = FALSE, startbitmap = FALSE;
86         gchar *charname,*p,*bitmap;
87         gint dx = 0,dy = 0;
88         gint w,h,x,y,py;
89         gint id,tmp;
90
91         dw = 0;
92         dh = 0;
93
94         if (!(f = fopen(fname, "r")))
95         {
96                 perror(fname);
97                 return -1;
98         }
99
100         if (fgets(line, sizeof(line), f) && strncasecmp("STARTFONT ", line, 10))
101         {
102                 printf("!BDF font file\n");
103                 fclose(f);
104                 return -1;
105         }
106         
107         p = line;
108         while (fgets(line, sizeof(line), f))
109         {
110                 if (!startchar)
111                 {
112                         if (!strncasecmp("STARTCHAR ", line, 10))
113                         {
114                                 startchar = TRUE;
115                                 charname = g_strndup(p + 10,
116                                         strcspn(p+10, "\r\n"));
117                         }
118                         else if (!strncasecmp("FONTBOUNDINGBOX ", line, 16))
119                                 sscanf(p+16, "%d %d %d %d", &dw, &dh, &dx, &dy);
120                 }
121                 else
122                 {
123                         if (!strncasecmp("ENDCHAR", line, 7))
124                         {
125                                 font_info_t *nfi;
126
127                                 startchar = FALSE;
128                                 startbitmap = FALSE;
129
130                                 nfi = g_malloc(sizeof(font_info_t));
131                                 memset(nfi, '\0', sizeof(font_info_t));
132
133                                 nfi->name = charname;
134                                 nfi->id = id;
135                                 nfi->bitmap = bitmap;
136                                 nfi->hotx = 0 - dx;
137                                 nfi->hoty = 0 - dy;
138
139                                 fonts = g_slist_append(fonts, nfi);
140                         }
141                         else if (startbitmap)
142                         {
143                                 int px,cx;
144                                 guchar mask;
145
146                                 px = x - dx + py * dw;
147                                 for (cx = 0; cx < w; cx++)
148                                 {
149                                         mask = 1 << (3 - (cx % 4));
150
151                                         bitmap[px+cx] =
152                                                 (mask & HEX(line[cx/4])) != 0;
153
154                                         /*printf(bitmap[px+cx] ? "X" : " ");*/
155                                 }
156                                 py++;
157                                 /*printf("\n");*/
158                         }
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))
162                         {
163                                 if (sscanf(p+9, "%d %d", &tmp, &id) != 2)
164                                         id = tmp;
165                         }
166                         else if (!strncasecmp("BITMAP", line, 6))
167                         {
168                                 py = y - dy;
169                                 startbitmap = TRUE;
170                                 bitmap = g_malloc(dw*dh);
171                                 memset(bitmap, '\0', dw*dh);
172                         }
173                 }
174         }
175
176         if (strncasecmp("ENDFONT", line, 7))
177                 rv = -1;
178
179         fclose(f);
180
181         return rv;
182 }
183
184 static gint font_info_compare(fi, name)
185 font_info_t *fi;
186 char *name;
187 {
188         return strcmp(name, fi->name);
189 }
190
191 static cursor_info_t *gen_cursor(bmap, mask)
192 font_info_t *bmap;
193 font_info_t *mask;
194 {
195         cursor_info_t *ci;
196         int bx = dw,by = dh,ex = 0,ey = 0;
197         int i,j;
198
199         for (j = 0; j < dh; j++)
200         {
201                 gboolean havep = FALSE;
202
203                 for (i = 0; i < dw; i++)
204                 {
205                         if (bmap->bitmap[j*dw+i] || mask->bitmap[j*dw+i])
206                         {
207                                 havep = TRUE;
208                                 bx = MIN(bx, i);
209                                 ex = MAX(i+1, ex);
210                         }
211                 }
212
213                 if (havep)
214                 {
215                         by = MIN(by, j);
216                         ey = MAX(ey, j+1);
217                 }
218         }
219
220         ci = g_malloc(sizeof(cursor_info_t));
221         ci->name = g_strdup(bmap->name);
222         ci->id = bmap->id;
223
224         ci->width = ex - bx;
225         ci->height = ey - by;
226
227         ci->hotx = bmap->hotx - bx;
228         ci->hoty = ci->height - (bmap->hoty - by);
229
230         ci->data = g_malloc(ci->width * ci->height);
231         memset(ci->data, '\0', ci->width * ci->height);
232
233         for (j = 0; j < ci->height; j++)
234         {
235                 for (i = 0; i < ci->width; i++)
236                 {
237                         int ofs = (by + j) * dw + bx + i;
238
239                         ci->data[j*ci->width + i] = mask->bitmap[ofs] *
240                                 (1 + bmap->bitmap[ofs]);
241                 }
242         }
243
244         return ci;
245 }
246
247 static void compose_cursors_from_fonts()
248 {
249         GSList *l;
250
251         for (l = g_slist_copy(fonts); l; l = g_slist_remove_link(l,l))
252         {
253                 font_info_t *fi = l->data;
254                 gchar *name;
255                 GSList *ml;
256
257                 name = g_strconcat(fi->name, "_mask", NULL);
258
259                 if ((ml = g_slist_find_custom(fonts, name,
260                         (GCompareFunc) font_info_compare)))
261                 {
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);
265                 }
266
267                 g_free(name);
268         }
269 }
270
271 static char *dump_cursor(ci, id)
272 cursor_info_t *ci;
273 int id;
274 {
275         static gchar cdata[8192];
276         gchar *p;
277         gint i;
278         gint c;
279         gboolean flushed;
280
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);
284
285         for (i = 0; i < ci->width * ci->height; i++)
286         {
287                 flushed = FALSE;
288
289                 if (!(i%4))
290                         c = 0;
291
292                 c = c << 2;
293
294                 c += ci->data[i];
295
296                 if ((i % 4) == 3)
297                 {
298                         flushed = TRUE;
299                         sprintf(p, "\\%03o", c);
300                         p += strlen(p);
301                 }
302
303                 if (i > 0 && !(i % 64))
304                 {
305                         strcpy(p ,"\"\n    \"");
306                         p += strlen(p);
307                 }
308         }
309         if (!flushed)
310         {
311                 sprintf(p, "\\%03o", c);
312                 p += strlen(p);
313         }
314
315         strcpy(p, "\" }");
316
317         return cdata;
318 }
319
320 static int dump_cursors()
321 {
322         GSList *ptr;
323         FILE *f = stdout;
324
325         fprintf(f, "static const struct { const gchar *name; gint type; guchar width; guchar height; guchar hotx; guchar hoty; guchar *data; } cursors[] = {\n");
326
327         for (ptr = cursors; ptr; ptr = ptr->next)
328         {
329                 /* print_cursor(ptr->data); */
330                 fprintf(f, "%s, \n", dump_cursor(ptr->data));
331         }
332
333         fprintf(f, "  { NULL, 0, 0, 0, 0, 0, NULL },\n};\n");
334
335         return 0;
336 }
337
338 gint main(argc, argv)
339 gint argc;
340 gchar **argv;
341 {
342         if (argc != 2)
343         {
344                 printf("missing parameters !\n");
345                 printf("Usage: %s [BDF cursor file]\n", argv[0]);
346                 return -1;
347         }
348
349         if (read_bdf_font(argv[1]) || !fonts)
350         {
351                 printf("Error reading font\n");
352                 return 1;
353         }
354
355         compose_cursors_from_fonts();
356
357         if (!cursors)
358         {
359                 printf("failed to generate cursors from font!\n");
360                 return 1;
361         }
362
363         dump_cursors();
364
365         if (fonts)
366         {
367                 printf("some fonts remained unconverted!\n");
368                 return 1;
369         }
370
371         return 0;
372 }
373