1 #include <stdlib.h>
2 #include <stdio.h>
3 
4 #include "blocks/blocktypes.h"
5 #include "action.h"
6 
7 #define error(x)	{puts(x); exit(1);}
8 #define print(x)	{fputs(x,stdout);}
9 #define println(x)	{fputs(indent(),stdout);fputs(x,stdout);putchar('\n');}
10 
11 int fileOffset = 0;
12 
13 int gIndent = 0;
14 char indentBuf[256];
15 int lastIndent = 0;
16 
17 typedef unsigned char boolean;
18 #define true (boolean)1
19 #define false (boolean)0
20 
21 //char *blockName(Blocktype type);
22 
indent()23 char *indent()
24 {
25   int i;
26 
27   if(gIndent>63)
28     error("indent level > 63!");
29 
30   if(lastIndent != gIndent)
31   {
32     for(i=0; i<3*gIndent; ++i)
33       indentBuf[i] = ' ';
34 
35     indentBuf[i] = '\0';
36 
37     lastIndent = gIndent;
38   }
39 
40   return indentBuf;
41 }
42 
43 int buffer;
44 int bufbits = 0; /* # of bits in buffer */
45 
byteAlign()46 void byteAlign()
47 {
48   if(bufbits > 0)
49   {
50     bufbits = 0;
51     buffer = 0;
52   }
53 }
54 
readBits(FILE * f,int number)55 int readBits(FILE *f, int number)
56 {
57   int ret = buffer;
58 
59   if(number == bufbits)
60   {
61     bufbits = 0;
62     buffer = 0;
63     return ret;
64   }
65 
66   if(number > bufbits)
67   {
68     number -= bufbits;
69 
70     while(number>8)
71     {
72       ret <<= 8;
73       ret += fgetc(f);
74       if (feof(f))
75       {
76         fprintf(stderr, "truncated file\n");
77         exit(-1);
78       }
79 
80       ++fileOffset;
81       number -= 8;
82     }
83 
84     ++fileOffset;
85     buffer = fgetc(f);
86     if (feof(f))
87     {
88       fprintf(stderr, "truncated file\n");
89       exit(-1);
90     }
91 
92 
93     if(number>0)
94     {
95       ret <<= number;
96       bufbits = 8-number;
97       ret += buffer >> (8-number);
98       buffer &= (1<<bufbits)-1;
99     }
100 
101     return ret;
102   }
103 
104   ret = buffer >> (bufbits-number);
105   bufbits -= number;
106   buffer &= (1<<bufbits)-1;
107 
108   return ret;
109 }
110 
readSBits(FILE * f,int number)111 int readSBits(FILE *f, int number)
112 {
113   int num = readBits(f, number);
114 
115   if(num & (1<<(number-1)))
116     return num - (1<<number);
117   else
118     return num;
119 }
120 
readUInt8(FILE * f)121 int readUInt8(FILE *f)
122 {
123   int tmp_char = fgetc(f);
124   // the rest of the code does not handle errors and use EOF as a valid unsigned char value
125   if (tmp_char == EOF)
126   {
127     // exit here instead of crashing elswhere
128     fprintf(stderr, "truncated file\n");
129     exit(-1);
130   }
131 
132   bufbits = 0;
133   ++fileOffset;
134 
135   return tmp_char;
136 }
137 
readSInt8(FILE * f)138 int readSInt8(FILE *f)
139 {
140   return (signed char)readUInt8(f);
141 }
142 
readSInt16(FILE * f)143 int readSInt16(FILE *f)
144 {
145   return readUInt8(f) + readSInt8(f)*256;
146 }
147 
readUInt16(FILE * f)148 int readUInt16(FILE *f)
149 {
150   return readUInt8(f) + (readUInt8(f)<<8);
151 }
152 
readSInt32(FILE * f)153 long readSInt32(FILE *f)
154 {
155   return (long)readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24);
156 }
157 
readUInt32(FILE * f)158 unsigned long readUInt32(FILE *f)
159 {
160   return (unsigned long)(readUInt8(f) + (readUInt8(f)<<8) + (readUInt8(f)<<16) + (readUInt8(f)<<24));
161 }
162 
readString(FILE * f)163 char *readString(FILE *f)
164 {
165   int len = 0, buflen = 256;
166   char c, *buf, *p;
167 
168   buf = (char *)malloc(sizeof(char)*256);
169   p = buf;
170 
171   while((c=(char)readUInt8(f)) != '\0')
172   {
173     if(len==buflen)
174     {
175       buf = (char *)realloc(buf, sizeof(char)*(buflen+256));
176       buflen += 256;
177       p = buf+len;
178     }
179 
180     *(p++) = c;
181     ++len;
182   }
183 
184   *p = 0;
185 
186   return buf;
187 }
188 
dumpBytes(FILE * f,int length)189 void dumpBytes(FILE *f, int length)
190 {
191   int j=0, i, k;
192   unsigned char buf[16];
193 
194   if(length<=0)
195     return;
196 
197   putchar('\n');
198 
199   for(;;)
200   {
201     for(i=0; i<16; ++i)
202     {
203       if(i==8) putchar(' ');
204 
205       printf("%02x ", buf[i] = readUInt8(f));
206       ++j;
207 
208       if(j==length)
209 		break;
210     }
211 
212     if(j==length)
213     {
214       for(k=i+1; k<16; ++k)
215 	print("   ");
216 
217       if(k==8) putchar(' ');
218 
219       ++i;
220     }
221 
222     print("   ");
223 
224     for(k=0; k<i; ++k)
225     {
226       if(k==8) putchar(' ');
227 
228       if((buf[k] > 31) && (buf[k] < 128))
229 	putchar(buf[k]);
230       else
231 	putchar('.');
232     }
233 
234     putchar('\n');
235 
236     if(j==length)
237       break;
238   }
239   putchar('\n');
240   putchar('\n');
241 }
242 
printMatrix(FILE * f)243 void printMatrix(FILE *f)
244 {
245   int nBits;
246   float num;
247 
248   byteAlign();
249 
250   if(readBits(f, 1)) /* has scale */
251   {
252     nBits = readBits(f, 5);
253     num = (float)readSBits(f, nBits)/0x10000;
254     printf("%sxScale: %f\n", indent(), num);
255     num = (float)readSBits(f, nBits)/0x10000;
256     printf("%syScale: %f\n", indent(), num);
257   }
258   if(readBits(f, 1)) /* has rotate */
259   {
260     nBits = readBits(f, 5);
261     num = (float)readSBits(f, nBits)/0x10000;
262     printf("%srotate0: %f\n", indent(), num);
263     num = (float)readSBits(f, nBits)/0x10000;
264     printf("%srotate1: %f\n", indent(), num);
265   }
266 
267   nBits = readBits(f, 5);
268   printf("%sx: %i\n", indent(), readSBits(f, nBits));
269   printf("%sy: %i\n", indent(), readSBits(f, nBits));
270 }
271 
printRect(FILE * f)272 void printRect(FILE *f)
273 {
274   int nBits, xMin, xMax, yMin, yMax;
275 
276   byteAlign();
277 
278   nBits = readBits(f, 5);
279   xMin = readSBits(f, nBits);
280   xMax = readSBits(f, nBits);
281   yMin = readSBits(f, nBits);
282   yMax = readSBits(f, nBits);
283 
284   printf("(%i,%i)x(%i,%i)", xMin, xMax, yMin, yMax);
285 }
286 
printShapeRec(FILE * f,int * lineBits,int * fillBits,int shapeType)287 int printShapeRec(FILE *f, int *lineBits, int *fillBits, int shapeType)
288 {
289   int type;
290 
291   printf("(%i:%i)",fileOffset,bufbits);
292 
293   type = readBits(f, 1);
294 
295   if(type==0) /* state change */
296   {
297     int newStyles = readBits(f, 1);
298     int lineStyle = readBits(f, 1);
299     int fillStyle1 = readBits(f, 1);
300     int fillStyle0 = readBits(f, 1);
301     int moveTo = readBits(f, 1);
302 
303     if(newStyles==0 && lineStyle==0 && fillStyle1==0 && fillStyle0==0 && moveTo==0)
304     {
305       println("EndShape");
306       return 0;
307     }
308 
309     if(moveTo==1)
310     {
311       int moveBits = readBits(f, 5);
312       int x = readSBits(f, moveBits);
313       int y = readSBits(f, moveBits);
314 
315       printf("%sMoveTo (%i) - (%i,%i)\n", indent(), moveBits, x, y);
316     }
317 
318     if(fillStyle0==1)
319       printf("%sFillStyle0: %i\n", indent(), readBits(f, *fillBits));
320 
321     if(fillStyle1==1)
322       printf("%sFillStyle1: %i\n", indent(), readBits(f, *fillBits));
323 
324     if(lineStyle==1)
325       printf("%sLineStyle1: %i\n", indent(), readBits(f, *lineBits));
326   }
327   else /* it's an edge record */
328   {
329     int straight = readBits(f, 1);
330     int numBits = readBits(f, 4)+2;
331 
332     if(straight==1)
333     {
334       if(readBits(f, 1)) /* general line */
335       {
336 	int x = readSBits(f, numBits);
337 	int y = readSBits(f, numBits);
338 
339 	printf("%sStraightEdge: (%i) - (%i,%i)\n", indent(), numBits, x, y);
340       }
341       else
342 	if(readBits(f, 1)) /* vert = 1 */
343 	  printf("%sStraightEdge: (%i) - (0,%i)\n", indent(), numBits, readSBits(f, numBits));
344 	else
345 	  printf("%sStraightEdge: (%i) - (%i,0)\n", indent(), numBits, readSBits(f, numBits));
346     }
347     else
348     {
349       int controlX = readSBits(f, numBits);
350       int controlY = readSBits(f, numBits);
351       int anchorX = readSBits(f, numBits);
352       int anchorY = readSBits(f, numBits);
353       printf("%sCurvedEdge: (%i) - (%i,%i)->(%i,%i)\n", indent(), numBits, controlX, controlY, anchorX, anchorY);
354     }
355   }
356 
357   return 1;
358 }
359 
360 #define FONTINFO2_HASLAYOUT		(1<<7)
361 #define FONTINFO2_SHIFTJIS		(1<<6)
362 #define FONTINFO2_UNICODE		(1<<5)
363 #define FONTINFO2_ANSI			(1<<4)
364 #define FONTINFO2_WIDEOFFSETS	        (1<<3)
365 #define FONTINFO2_WIDECODES		(1<<2)
366 #define FONTINFO2_ITALIC		(1<<1)
367 #define FONTINFO2_BOLD			(1<<0)
368 
printDefineFont2(FILE * f)369 void printDefineFont2(FILE *f)
370 {
371   int flags, nGlyphs, namelen, off, i, fillBits, lineBits;
372   int here = fileOffset;
373   unsigned int *offset;
374 
375   flags = readUInt8(f);
376 
377   readUInt8(f); /* "reserved" */
378 
379   namelen = readUInt8(f);
380 
381   printf("%sFont Name: ", indent());
382 
383   for(; namelen>0; --namelen)
384     putchar((unsigned char)readUInt8(f));
385 
386   putchar('\n');
387 
388   nGlyphs = readUInt16(f);
389   printf("%snumber of glyphs: %i\n\n", indent(), nGlyphs);
390 
391   offset = (unsigned int *)malloc(nGlyphs*sizeof(int));
392 
393   /* offset table */
394 
395   here = fileOffset;
396 
397   for(i=0; i<=nGlyphs; ++i)
398   {
399     if(flags & FONTINFO2_WIDEOFFSETS)
400       off = readUInt32(f);
401     else
402       off = readUInt16(f);
403 
404     offset[i] = off-nGlyphs*4-4;
405     printf("%sOffset%i: %i\n", indent(), i, offset[i]);
406   }
407 
408   here = fileOffset;
409 
410   /* shape table */
411   for(i=0; i<nGlyphs; ++i)
412   {
413     byteAlign();
414     printf("%sGlyph %i:\n", indent(), i);
415 
416     fillBits = readBits(f, 4);
417     lineBits = readBits(f, 4);
418 
419     byteAlign();
420     while(printShapeRec(f, &fillBits, &lineBits, 2)) ;
421 
422     putchar('\n');
423   }
424 
425   /* code table */
426   for(i=0; i<nGlyphs; ++i)
427   {
428     if(flags & FONTINFO2_WIDECODES)
429       printf("%sglyph code %i: %i\n", indent(), i, readUInt16(f));
430     else
431       printf("%sglyph code %i: %i\n", indent(), i, readUInt8(f));
432   }
433 
434   if(flags & FONTINFO2_HASLAYOUT)
435   {
436     int kernCount, code1, code2;
437 
438     printf("%sascender height: %i\n", indent(), readSInt16(f));
439     printf("%sdescender height: %i\n", indent(), readSInt16(f));
440     printf("%sleading height: %i\n", indent(), readSInt16(f));
441 
442     for(i=0; i<nGlyphs; ++i)
443       printf("\tadvance %i: %i\n", i, readSInt16(f));
444 
445     for(i=0; i<nGlyphs; ++i)
446     {
447       printf("%sbounds %i: ", indent(), i);
448       printRect(f);
449       putchar('\n');
450     }
451 
452     kernCount = readUInt16(f);
453 
454     for(i=0; i<kernCount; ++i)
455     {
456       code1 = (flags & FONTINFO2_WIDECODES) ? readUInt16(f) : readUInt8(f);
457       code2 = (flags & FONTINFO2_WIDECODES) ? readUInt16(f) : readUInt8(f);
458       printf("%s(%i,%i): adjustment = %i\n", indent(), code1, code2, readSInt16(f));
459     }
460   }
461 
462   putchar('\n');
463 }
464 
main(int argc,char * argv[])465 int main(int argc, char *argv[])
466 {
467   FILE *f;
468 
469   if(argc<2)
470     error("Give me a filename.\n");
471 
472   if(!(f = fopen(argv[1],"rb")))
473     error("Sorry, can't seem to read that file.\n");
474 
475   if(!(readUInt8(f)=='f' && readUInt8(f)=='d' && readUInt8(f)=='b'))
476     error("Doesn't look like an fdb file to me..\n");
477 
478   readUInt8(f); /* version */
479 
480   printDefineFont2(f);
481 
482   putchar('\n');
483 
484   return 0;
485 }
486