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