diff options
author | Alexander Levin <al.le@rockbox.org> | 2009-03-06 22:50:47 +0000 |
---|---|---|
committer | Alexander Levin <al.le@rockbox.org> | 2009-03-06 22:50:47 +0000 |
commit | cbcef6700cb000b7b5216434eed296254dffc2d8 (patch) | |
tree | a03293fc01e619ba277ac7f02b659039184d7a75 /tools/convbdf.c | |
parent | c8a60784d09cc2807a674fe586887aff0b56da59 (diff) | |
download | rockbox-cbcef6700cb000b7b5216434eed296254dffc2d8.tar.gz rockbox-cbcef6700cb000b7b5216434eed296254dffc2d8.zip |
Revamp of the bitmap allocation for the fonts. Implements the idea from FS#9907 (reallocate when maxwidth grows), but does it correctly. Also gets rid of the warning "DWIDTH spec > ..." which is irritating since the bounding box header of the font is not required to specify the MAX width.
Also replaced TABs with spaces.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20219 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'tools/convbdf.c')
-rw-r--r-- | tools/convbdf.c | 258 |
1 files changed, 131 insertions, 127 deletions
diff --git a/tools/convbdf.c b/tools/convbdf.c index 437281c14a..4dfc0595bb 100644 --- a/tools/convbdf.c +++ b/tools/convbdf.c | |||
@@ -5,7 +5,7 @@ | |||
5 | * | 5 | * |
6 | * What fun it is converting font data... | 6 | * What fun it is converting font data... |
7 | * | 7 | * |
8 | * 09/17/02 Version 1.0 | 8 | * 09/17/02 Version 1.0 |
9 | */ | 9 | */ |
10 | #include <stdio.h> | 10 | #include <stdio.h> |
11 | #include <stdlib.h> | 11 | #include <stdlib.h> |
@@ -17,45 +17,49 @@ | |||
17 | /* BEGIN font.h*/ | 17 | /* BEGIN font.h*/ |
18 | /* loadable font magic and version #*/ | 18 | /* loadable font magic and version #*/ |
19 | #ifdef ROTATE | 19 | #ifdef ROTATE |
20 | #define VERSION "RB12" /* newer version */ | 20 | #define VERSION "RB12" /* newer version */ |
21 | #else | 21 | #else |
22 | #define VERSION "RB11" | 22 | #define VERSION "RB11" |
23 | #endif | 23 | #endif |
24 | 24 | ||
25 | /* bitmap_t helper macros*/ | 25 | /* |
26 | #define BITMAP_WORDS(x) (((x)+15)/16) /* image size in words*/ | 26 | * bitmap_t helper macros |
27 | */ | ||
28 | typedef unsigned short bitmap_t; /* bitmap image unit size*/ | ||
29 | |||
30 | /* Number of words to hold a pixel line of width x pixels */ | ||
31 | #define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8) | ||
32 | #define BITMAP_WORDS(x) (((x)+BITMAP_BITSPERIMAGE-1)/BITMAP_BITSPERIMAGE) | ||
27 | #define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t)) | 33 | #define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t)) |
28 | #define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8) | 34 | #define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n))) |
29 | #define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n))) | 35 | #define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1)) |
30 | #define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1)) | 36 | #define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT) |
31 | #define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT) | 37 | #define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1)) |
32 | #define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1)) | ||
33 | 38 | ||
34 | typedef unsigned short bitmap_t; /* bitmap image unit size*/ | ||
35 | 39 | ||
36 | /* builtin C-based proportional/fixed font structure */ | 40 | /* builtin C-based proportional/fixed font structure */ |
37 | /* based on The Microwindows Project http://microwindows.org */ | 41 | /* based on The Microwindows Project http://microwindows.org */ |
38 | struct font { | 42 | struct font { |
39 | int maxwidth; /* max width in pixels*/ | 43 | int maxwidth; /* max width in pixels */ |
40 | int height; /* height in pixels*/ | 44 | int height; /* height in pixels */ |
41 | int ascent; /* ascent (baseline) height*/ | 45 | int ascent; /* ascent (baseline) height */ |
42 | int firstchar; /* first character in bitmap*/ | 46 | int firstchar; /* first character in bitmap */ |
43 | int size; /* font size in glyphs ('holes' included) */ | 47 | int size; /* font size in glyphs ('holes' included) */ |
44 | bitmap_t* bits; /* 16-bit right-padded bitmap data*/ | 48 | bitmap_t* bits; /* 16-bit right-padded bitmap data */ |
45 | unsigned int* offset; /* offsets into bitmap data*/ | 49 | int* offset; /* offsets into bitmap data */ |
46 | unsigned char* width; /* character widths or NULL if fixed*/ | 50 | unsigned char* width; /* character widths or NULL if fixed */ |
47 | int defaultchar; /* default char (not glyph index)*/ | 51 | int defaultchar; /* default char (not glyph index) */ |
48 | int bits_size; /* # words of bitmap_t bits*/ | 52 | int bits_size; /* # words of bitmap_t bits */ |
49 | 53 | ||
50 | /* unused by runtime system, read in by convbdf */ | 54 | /* unused by runtime system, read in by convbdf */ |
51 | int nchars; /* number of different glyphs */ | 55 | int nchars; /* number of different glyphs */ |
52 | unsigned int* offrot; /* offsets into rotated bitmap data*/ | 56 | unsigned int* offrot; /* offsets into rotated bitmap data */ |
53 | char * name; /* font name*/ | 57 | char* name; /* font name */ |
54 | char * facename; /* facename of font*/ | 58 | char* facename; /* facename of font */ |
55 | char * copyright; /* copyright info for loadable fonts*/ | 59 | char* copyright; /* copyright info for loadable fonts */ |
56 | int pixel_size; | 60 | int pixel_size; |
57 | int descent; | 61 | int descent; |
58 | int fbbw, fbbh, fbbx, fbby; | 62 | int fbbw, fbbh, fbbx, fbby; |
59 | 63 | ||
60 | /* Max 'overflow' of a char's ascent (descent) over the font's one */ | 64 | /* Max 'overflow' of a char's ascent (descent) over the font's one */ |
61 | int max_over_ascent, max_over_descent; | 65 | int max_over_ascent, max_over_descent; |
@@ -65,14 +69,12 @@ struct font { | |||
65 | }; | 69 | }; |
66 | /* END font.h*/ | 70 | /* END font.h*/ |
67 | 71 | ||
68 | #define isprefix(buf,str) (!strncmp(buf, str, strlen(str))) | 72 | #define isprefix(buf,str) (!strncmp(buf, str, strlen(str))) |
69 | #define strequal(s1,s2) (!strcmp(s1, s2)) | 73 | #define strequal(s1,s2) (!strcmp(s1, s2)) |
70 | 74 | ||
71 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) | 75 | #define MAX(a,b) ((a) > (b) ? (a) : (b)) |
72 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) | 76 | #define MIN(a,b) ((a) < (b) ? (a) : (b)) |
73 | 77 | ||
74 | #define EXTRA 300 /* # bytes extra allocation for buggy .bdf files*/ | ||
75 | |||
76 | int gen_c = 0; | 78 | int gen_c = 0; |
77 | int gen_h = 0; | 79 | int gen_h = 0; |
78 | int gen_fnt = 0; | 80 | int gen_fnt = 0; |
@@ -92,6 +94,7 @@ int bdf_read_header(FILE *fp, struct font* pf); | |||
92 | int bdf_read_bitmaps(FILE *fp, struct font* pf); | 94 | int bdf_read_bitmaps(FILE *fp, struct font* pf); |
93 | char * bdf_getline(FILE *fp, char *buf, int len); | 95 | char * bdf_getline(FILE *fp, char *buf, int len); |
94 | bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2); | 96 | bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2); |
97 | void bitmap_buf_alloc(struct font* pf); | ||
95 | 98 | ||
96 | int gen_c_source(struct font* pf, char *path); | 99 | int gen_c_source(struct font* pf, char *path); |
97 | int gen_h_header(struct font* pf, char *path); | 100 | int gen_h_header(struct font* pf, char *path); |
@@ -101,16 +104,16 @@ void | |||
101 | usage(void) | 104 | usage(void) |
102 | { | 105 | { |
103 | char help[] = { | 106 | char help[] = { |
104 | "Usage: convbdf [options] [input-files]\n" | 107 | "Usage: convbdf [options] [input-files]\n" |
105 | " convbdf [options] [-o output-file] [single-input-file]\n" | 108 | " convbdf [options] [-o output-file] [single-input-file]\n" |
106 | "Options:\n" | 109 | "Options:\n" |
107 | " -c Convert .bdf to .c source file\n" | 110 | " -c Convert .bdf to .c source file\n" |
108 | " -h Convert .bdf to .h header file (to create sysfont.h)\n" | 111 | " -h Convert .bdf to .h header file (to create sysfont.h)\n" |
109 | " -f Convert .bdf to .fnt font file\n" | 112 | " -f Convert .bdf to .fnt font file\n" |
110 | " -s N Start output at character encodings >= N\n" | 113 | " -s N Start output at character encodings >= N\n" |
111 | " -l N Limit output to character encodings <= N\n" | 114 | " -l N Limit output to character encodings <= N\n" |
112 | " -n Don't generate bitmaps as comments in .c file\n" | 115 | " -n Don't generate bitmaps as comments in .c file\n" |
113 | }; | 116 | }; |
114 | 117 | ||
115 | fprintf(stderr, "%s", help); | 118 | fprintf(stderr, "%s", help); |
116 | } | 119 | } |
@@ -128,25 +131,25 @@ void getopts(int *pac, char ***pav) | |||
128 | p = &av[0][1]; | 131 | p = &av[0][1]; |
129 | while( *p) | 132 | while( *p) |
130 | switch(*p++) { | 133 | switch(*p++) { |
131 | case ' ': /* multiple -args on av[]*/ | 134 | case ' ': /* multiple -args on av[]*/ |
132 | while( *p && *p == ' ') | 135 | while( *p && *p == ' ') |
133 | p++; | 136 | p++; |
134 | if( *p++ != '-') /* next option must have dash*/ | 137 | if( *p++ != '-') /* next option must have dash*/ |
135 | p = ""; | 138 | p = ""; |
136 | break; /* proceed to next option*/ | 139 | break; /* proceed to next option*/ |
137 | case 'c': /* generate .c output*/ | 140 | case 'c': /* generate .c output*/ |
138 | gen_c = 1; | 141 | gen_c = 1; |
139 | break; | 142 | break; |
140 | case 'h': /* generate .h output*/ | 143 | case 'h': /* generate .h output*/ |
141 | gen_h = 1; | 144 | gen_h = 1; |
142 | break; | 145 | break; |
143 | case 'f': /* generate .fnt output*/ | 146 | case 'f': /* generate .fnt output*/ |
144 | gen_fnt = 1; | 147 | gen_fnt = 1; |
145 | break; | 148 | break; |
146 | case 'n': /* don't gen bitmap comments*/ | 149 | case 'n': /* don't gen bitmap comments*/ |
147 | gen_map = 0; | 150 | gen_map = 0; |
148 | break; | 151 | break; |
149 | case 'o': /* set output file*/ | 152 | case 'o': /* set output file*/ |
150 | oflag = 1; | 153 | oflag = 1; |
151 | if (*p) { | 154 | if (*p) { |
152 | strcpy(outfile, p); | 155 | strcpy(outfile, p); |
@@ -159,7 +162,7 @@ void getopts(int *pac, char ***pav) | |||
159 | strcpy(outfile, av[0]); | 162 | strcpy(outfile, av[0]); |
160 | } | 163 | } |
161 | break; | 164 | break; |
162 | case 'l': /* set encoding limit*/ | 165 | case 'l': /* set encoding limit*/ |
163 | if (*p) { | 166 | if (*p) { |
164 | limit_char = atoi(p); | 167 | limit_char = atoi(p); |
165 | while (*p && *p != ' ') | 168 | while (*p && *p != ' ') |
@@ -171,7 +174,7 @@ void getopts(int *pac, char ***pav) | |||
171 | limit_char = atoi(av[0]); | 174 | limit_char = atoi(av[0]); |
172 | } | 175 | } |
173 | break; | 176 | break; |
174 | case 's': /* set encoding start*/ | 177 | case 's': /* set encoding start*/ |
175 | if (*p) { | 178 | if (*p) { |
176 | start_char = atoi(p); | 179 | start_char = atoi(p); |
177 | while (*p && *p != ' ') | 180 | while (*p && *p != ' ') |
@@ -192,13 +195,13 @@ void getopts(int *pac, char ***pav) | |||
192 | *pav = av; | 195 | *pav = av; |
193 | } | 196 | } |
194 | 197 | ||
195 | /* remove directory prefix and file suffix from full path*/ | 198 | /* remove directory prefix and file suffix from full path */ |
196 | char *basename(char *path) | 199 | char *basename(char *path) |
197 | { | 200 | { |
198 | char *p, *b; | 201 | char *p, *b; |
199 | static char base[256]; | 202 | static char base[256]; |
200 | 203 | ||
201 | /* remove prepended path and extension*/ | 204 | /* remove prepended path and extension */ |
202 | b = path; | 205 | b = path; |
203 | for (p=path; *p; ++p) { | 206 | for (p=path; *p; ++p) { |
204 | if (*p == '/') | 207 | if (*p == '/') |
@@ -255,8 +258,8 @@ int main(int ac, char **av) | |||
255 | { | 258 | { |
256 | int ret = 0; | 259 | int ret = 0; |
257 | 260 | ||
258 | ++av; --ac; /* skip av[0]*/ | 261 | ++av; --ac; /* skip av[0] */ |
259 | getopts(&ac, &av); /* read command line options*/ | 262 | getopts(&ac, &av); /* read command line options */ |
260 | 263 | ||
261 | if (ac < 1 || (!gen_c && !gen_h && !gen_fnt)) { | 264 | if (ac < 1 || (!gen_c && !gen_h && !gen_fnt)) { |
262 | usage(); | 265 | usage(); |
@@ -277,7 +280,7 @@ int main(int ac, char **av) | |||
277 | exit(ret); | 280 | exit(ret); |
278 | } | 281 | } |
279 | 282 | ||
280 | /* free font structure*/ | 283 | /* free font structure */ |
281 | void free_font(struct font* pf) | 284 | void free_font(struct font* pf) |
282 | { | 285 | { |
283 | if (!pf) | 286 | if (!pf) |
@@ -297,7 +300,7 @@ void free_font(struct font* pf) | |||
297 | free(pf); | 300 | free(pf); |
298 | } | 301 | } |
299 | 302 | ||
300 | /* build incore structure from .bdf file*/ | 303 | /* build incore structure from .bdf file */ |
301 | struct font* bdf_read_font(char *path) | 304 | struct font* bdf_read_font(char *path) |
302 | { | 305 | { |
303 | FILE *fp; | 306 | FILE *fp; |
@@ -312,7 +315,8 @@ struct font* bdf_read_font(char *path) | |||
312 | pf = (struct font*)calloc(1, sizeof(struct font)); | 315 | pf = (struct font*)calloc(1, sizeof(struct font)); |
313 | if (!pf) | 316 | if (!pf) |
314 | goto errout; | 317 | goto errout; |
315 | 318 | memset(pf, 0, sizeof(struct font)); | |
319 | |||
316 | pf->name = strdup(basename(path)); | 320 | pf->name = strdup(basename(path)); |
317 | 321 | ||
318 | if (!bdf_read_header(fp, pf)) { | 322 | if (!bdf_read_header(fp, pf)) { |
@@ -346,18 +350,17 @@ struct font* bdf_read_font(char *path) | |||
346 | return NULL; | 350 | return NULL; |
347 | } | 351 | } |
348 | 352 | ||
349 | /* read bdf font header information, return 0 on error*/ | 353 | /* read bdf font header information, return 0 on error */ |
350 | int bdf_read_header(FILE *fp, struct font* pf) | 354 | int bdf_read_header(FILE *fp, struct font* pf) |
351 | { | 355 | { |
352 | int encoding; | 356 | int encoding; |
353 | int maxwidth; | ||
354 | int firstchar = 65535; | 357 | int firstchar = 65535; |
355 | int lastchar = -1; | 358 | int lastchar = -1; |
356 | char buf[256]; | 359 | char buf[256]; |
357 | char facename[256]; | 360 | char facename[256]; |
358 | char copyright[256]; | 361 | char copyright[256]; |
359 | 362 | ||
360 | /* set certain values to errors for later error checking*/ | 363 | /* set certain values to errors for later error checking */ |
361 | pf->defaultchar = -1; | 364 | pf->defaultchar = -1; |
362 | pf->ascent = -1; | 365 | pf->ascent = -1; |
363 | pf->descent = -1; | 366 | pf->descent = -1; |
@@ -367,7 +370,7 @@ int bdf_read_header(FILE *fp, struct font* pf) | |||
367 | fprintf(stderr, "Error: EOF on file\n"); | 370 | fprintf(stderr, "Error: EOF on file\n"); |
368 | return 0; | 371 | return 0; |
369 | } | 372 | } |
370 | if (isprefix(buf, "FONT ")) { /* not required*/ | 373 | if (isprefix(buf, "FONT ")) { /* not required */ |
371 | if (sscanf(buf, "FONT %[^\n]", facename) != 1) { | 374 | if (sscanf(buf, "FONT %[^\n]", facename) != 1) { |
372 | fprintf(stderr, "Error: bad 'FONT'\n"); | 375 | fprintf(stderr, "Error: bad 'FONT'\n"); |
373 | return 0; | 376 | return 0; |
@@ -375,7 +378,7 @@ int bdf_read_header(FILE *fp, struct font* pf) | |||
375 | pf->facename = strdup(facename); | 378 | pf->facename = strdup(facename); |
376 | continue; | 379 | continue; |
377 | } | 380 | } |
378 | if (isprefix(buf, "COPYRIGHT ")) { /* not required*/ | 381 | if (isprefix(buf, "COPYRIGHT ")) { /* not required */ |
379 | if (sscanf(buf, "COPYRIGHT \"%[^\"]", copyright) != 1) { | 382 | if (sscanf(buf, "COPYRIGHT \"%[^\"]", copyright) != 1) { |
380 | fprintf(stderr, "Error: bad 'COPYRIGHT'\n"); | 383 | fprintf(stderr, "Error: bad 'COPYRIGHT'\n"); |
381 | return 0; | 384 | return 0; |
@@ -383,7 +386,7 @@ int bdf_read_header(FILE *fp, struct font* pf) | |||
383 | pf->copyright = strdup(copyright); | 386 | pf->copyright = strdup(copyright); |
384 | continue; | 387 | continue; |
385 | } | 388 | } |
386 | if (isprefix(buf, "DEFAULT_CHAR ")) { /* not required*/ | 389 | if (isprefix(buf, "DEFAULT_CHAR ")) { /* not required */ |
387 | if (sscanf(buf, "DEFAULT_CHAR %d", &pf->defaultchar) != 1) { | 390 | if (sscanf(buf, "DEFAULT_CHAR %d", &pf->defaultchar) != 1) { |
388 | fprintf(stderr, "Error: bad 'DEFAULT_CHAR'\n"); | 391 | fprintf(stderr, "Error: bad 'DEFAULT_CHAR'\n"); |
389 | return 0; | 392 | return 0; |
@@ -451,30 +454,30 @@ int bdf_read_header(FILE *fp, struct font* pf) | |||
451 | } | 454 | } |
452 | pf->height = pf->ascent + pf->descent; | 455 | pf->height = pf->ascent + pf->descent; |
453 | 456 | ||
454 | /* calc default char*/ | 457 | /* calc default char */ |
455 | if (pf->defaultchar < 0 || | 458 | if (pf->defaultchar < 0 || |
456 | pf->defaultchar < firstchar || | 459 | pf->defaultchar < firstchar || |
457 | pf->defaultchar > limit_char || | 460 | pf->defaultchar > limit_char || |
458 | pf->defaultchar > lastchar) | 461 | pf->defaultchar > lastchar) |
459 | pf->defaultchar = firstchar; | 462 | pf->defaultchar = firstchar; |
460 | 463 | ||
461 | /* calc font size (offset/width entries)*/ | 464 | /* calc font size (offset/width entries) */ |
462 | pf->firstchar = firstchar; | 465 | pf->firstchar = firstchar; |
463 | pf->size = lastchar - firstchar + 1; | 466 | pf->size = lastchar - firstchar + 1; |
464 | 467 | if (pf->size < pf->nchars) { | |
465 | /* use the font boundingbox to get initial maxwidth*/ | 468 | fprintf(stderr, "Error: NCHARS and max code mismatch\n"); |
469 | return 0; | ||
470 | } | ||
471 | |||
472 | /* use the font boundingbox to get initial maxwidth */ | ||
466 | /*maxwidth = pf->fbbw - pf->fbbx;*/ | 473 | /*maxwidth = pf->fbbw - pf->fbbx;*/ |
467 | maxwidth = pf->fbbw; | 474 | pf->maxwidth = pf->fbbw; |
475 | bitmap_buf_alloc(pf); /* Allocate bitmaps */ | ||
468 | 476 | ||
469 | /* initially use font maxwidth * height for bits allocation*/ | 477 | pf->offset = (int *)malloc(pf->size * sizeof(int)); |
470 | pf->bits_size = pf->nchars * BITMAP_WORDS(maxwidth) * pf->height; | ||
471 | |||
472 | /* allocate bits, offset, and width arrays*/ | ||
473 | pf->bits = (bitmap_t *)malloc(pf->bits_size * sizeof(bitmap_t) + EXTRA); | ||
474 | pf->offset = (unsigned int *)malloc(pf->size * sizeof(unsigned int)); | ||
475 | pf->offrot = (unsigned int *)malloc(pf->size * sizeof(unsigned int)); | 478 | pf->offrot = (unsigned int *)malloc(pf->size * sizeof(unsigned int)); |
476 | pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char)); | 479 | pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char)); |
477 | 480 | ||
478 | if (!pf->bits || !pf->offset || !pf->offrot || !pf->width) { | 481 | if (!pf->bits || !pf->offset || !pf->offrot || !pf->width) { |
479 | fprintf(stderr, "Error: no memory for font load\n"); | 482 | fprintf(stderr, "Error: no memory for font load\n"); |
480 | return 0; | 483 | return 0; |
@@ -483,23 +486,24 @@ int bdf_read_header(FILE *fp, struct font* pf) | |||
483 | return 1; | 486 | return 1; |
484 | } | 487 | } |
485 | 488 | ||
486 | /* read bdf font bitmaps, return 0 on error*/ | 489 | /* read bdf font bitmaps, return 0 on error */ |
487 | int bdf_read_bitmaps(FILE *fp, struct font* pf) | 490 | int bdf_read_bitmaps(FILE *fp, struct font* pf) |
488 | { | 491 | { |
489 | int ofs = 0; | 492 | int ofs = 0; |
490 | int ofr = 0; | 493 | int ofr = 0; |
491 | int maxwidth = 0; | ||
492 | int i, k, encoding, width; | 494 | int i, k, encoding, width; |
493 | int bbw, bbh, bbx, bby; | 495 | int bbw, bbh, bbx, bby; |
494 | int proportional = 0; | 496 | int proportional = 0; |
495 | int encodetable = 0; | 497 | int encodetable = 0; |
496 | int l; | 498 | int l; |
497 | char buf[256]; | 499 | char buf[256]; |
500 | bitmap_t *ch_bitmap; | ||
501 | int ch_words; | ||
498 | 502 | ||
499 | /* reset file pointer*/ | 503 | /* reset file pointer */ |
500 | fseek(fp, 0L, SEEK_SET); | 504 | fseek(fp, 0L, SEEK_SET); |
501 | 505 | ||
502 | /* initially mark offsets as not used*/ | 506 | /* initially mark offsets as not used */ |
503 | for (i=0; i<pf->size; ++i) | 507 | for (i=0; i<pf->size; ++i) |
504 | pf->offset[i] = -1; | 508 | pf->offset[i] = -1; |
505 | 509 | ||
@@ -530,7 +534,7 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
530 | fprintf(stderr, "Error: bad 'DWIDTH'\n"); | 534 | fprintf(stderr, "Error: bad 'DWIDTH'\n"); |
531 | return 0; | 535 | return 0; |
532 | } | 536 | } |
533 | /* use font boundingbox width if DWIDTH <= 0*/ | 537 | /* use font boundingbox width if DWIDTH <= 0 */ |
534 | if (width <= 0) | 538 | if (width <= 0) |
535 | width = pf->fbbw - pf->fbbx; | 539 | width = pf->fbbw - pf->fbbx; |
536 | continue; | 540 | continue; |
@@ -543,8 +547,6 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
543 | continue; | 547 | continue; |
544 | } | 548 | } |
545 | if (strequal(buf, "BITMAP") || strequal(buf, "BITMAP ")) { | 549 | if (strequal(buf, "BITMAP") || strequal(buf, "BITMAP ")) { |
546 | bitmap_t *ch_bitmap = pf->bits + ofs; | ||
547 | int ch_words; | ||
548 | int overflow_asc, overflow_desc; | 550 | int overflow_asc, overflow_desc; |
549 | int bbh_orig, bby_orig, y; | 551 | int bbh_orig, bby_orig, y; |
550 | 552 | ||
@@ -552,7 +554,7 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
552 | continue; | 554 | continue; |
553 | 555 | ||
554 | /* set bits offset in encode map*/ | 556 | /* set bits offset in encode map*/ |
555 | if (pf->offset[encoding-pf->firstchar] != (unsigned int)-1) { | 557 | if (pf->offset[encoding-pf->firstchar] != -1) { |
556 | fprintf(stderr, "Error: duplicate encoding for character %d (0x%02x), ignoring duplicate\n", | 558 | fprintf(stderr, "Error: duplicate encoding for character %d (0x%02x), ignoring duplicate\n", |
557 | encoding, encoding); | 559 | encoding, encoding); |
558 | continue; | 560 | continue; |
@@ -560,23 +562,24 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
560 | pf->offset[encoding-pf->firstchar] = ofs; | 562 | pf->offset[encoding-pf->firstchar] = ofs; |
561 | pf->offrot[encoding-pf->firstchar] = ofr; | 563 | pf->offrot[encoding-pf->firstchar] = ofr; |
562 | 564 | ||
563 | /* calc char width*/ | 565 | /* calc char width */ |
564 | if (bbx < 0) { | 566 | if (bbx < 0) { |
567 | /* Rockbox can't render overlapping glyphs */ | ||
565 | width -= bbx; | 568 | width -= bbx; |
566 | /*if (width > maxwidth) | ||
567 | width = maxwidth;*/ | ||
568 | bbx = 0; | 569 | bbx = 0; |
569 | } | 570 | } |
570 | if (width > maxwidth) | 571 | if (width > pf->maxwidth) { |
571 | maxwidth = width; | 572 | pf->maxwidth = width; |
573 | bitmap_buf_alloc(pf); /* Re-allocate bitmaps since the maxwidth has grown */ | ||
574 | } | ||
572 | pf->width[encoding-pf->firstchar] = width; | 575 | pf->width[encoding-pf->firstchar] = width; |
573 | 576 | ||
574 | /* clear bitmap*/ | 577 | ch_bitmap = pf->bits + ofs; |
575 | memset(ch_bitmap, 0, BITMAP_BYTES(width) * pf->height); | ||
576 | |||
577 | ch_words = BITMAP_WORDS(width); | 578 | ch_words = BITMAP_WORDS(width); |
578 | #define BM(row,col) (*(ch_bitmap + ((row)*ch_words) + (col))) | 579 | memset(ch_bitmap, 0, BITMAP_BYTES(width) * pf->height); /* clear bitmap */ |
579 | #define BITMAP_NIBBLES (BITMAP_BITSPERIMAGE/4) | 580 | |
581 | #define BM(row,col) (*(ch_bitmap + ((row)*ch_words) + (col))) | ||
582 | #define BITMAP_NIBBLES (BITMAP_BITSPERIMAGE/4) | ||
580 | 583 | ||
581 | bbh_orig = bbh; | 584 | bbh_orig = bbh; |
582 | bby_orig = bby; | 585 | bby_orig = bby; |
@@ -610,12 +613,13 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
610 | 613 | ||
611 | y = bby_orig + bbh_orig; /* 0-based y within the char */ | 614 | y = bby_orig + bbh_orig; /* 0-based y within the char */ |
612 | 615 | ||
613 | /* read bitmaps*/ | 616 | /* read bitmaps */ |
614 | for (i=0; ; ++i) { | 617 | for (i=0; ; ++i) { |
615 | int hexnibbles; | 618 | int hexnibbles; |
616 | 619 | ||
617 | if (!bdf_getline(fp, buf, sizeof(buf))) { | 620 | if (!bdf_getline(fp, buf, sizeof(buf))) { |
618 | fprintf(stderr, "Error: EOF reading BITMAP data\n"); | 621 | fprintf(stderr, "Error: EOF reading BITMAP data for character %d\n", |
622 | encoding); | ||
619 | return 0; | 623 | return 0; |
620 | } | 624 | } |
621 | if (isprefix(buf, "ENDCHAR")) | 625 | if (isprefix(buf, "ENDCHAR")) |
@@ -633,7 +637,7 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
633 | int ndx = k * BITMAP_NIBBLES; | 637 | int ndx = k * BITMAP_NIBBLES; |
634 | int padnibbles = hexnibbles - ndx; | 638 | int padnibbles = hexnibbles - ndx; |
635 | bitmap_t value; | 639 | bitmap_t value; |
636 | 640 | ||
637 | if (padnibbles <= 0) | 641 | if (padnibbles <= 0) |
638 | break; | 642 | break; |
639 | if (padnibbles >= (int)BITMAP_NIBBLES) | 643 | if (padnibbles >= (int)BITMAP_NIBBLES) |
@@ -645,7 +649,7 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
645 | 649 | ||
646 | BM(pf->height - pf->descent - bby - bbh + i, k) |= | 650 | BM(pf->height - pf->descent - bby - bbh + i, k) |= |
647 | value >> bbx; | 651 | value >> bbx; |
648 | /* handle overflow into next image word*/ | 652 | /* handle overflow into next image word */ |
649 | if (bbx) { | 653 | if (bbx) { |
650 | BM(pf->height - pf->descent - bby - bbh + i, k+1) = | 654 | BM(pf->height - pf->descent - bby - bbh + i, k+1) = |
651 | value << (BITMAP_BITSPERIMAGE - bbx); | 655 | value << (BITMAP_BITSPERIMAGE - bbx); |
@@ -662,18 +666,15 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
662 | break; | 666 | break; |
663 | } | 667 | } |
664 | 668 | ||
665 | /* set max width*/ | 669 | /* change unused width values to default char values */ |
666 | pf->maxwidth = maxwidth; | ||
667 | |||
668 | /* change unused width values to default char values*/ | ||
669 | for (i=0; i<pf->size; ++i) { | 670 | for (i=0; i<pf->size; ++i) { |
670 | int defchar = pf->defaultchar - pf->firstchar; | 671 | int defchar = pf->defaultchar - pf->firstchar; |
671 | 672 | ||
672 | if (pf->offset[i] == (unsigned int)-1) | 673 | if (pf->offset[i] == -1) |
673 | pf->width[i] = pf->width[defchar]; | 674 | pf->width[i] = pf->width[defchar]; |
674 | } | 675 | } |
675 | 676 | ||
676 | /* determine whether font doesn't require encode table*/ | 677 | /* determine whether font doesn't require encode table */ |
677 | #ifdef ROTATE | 678 | #ifdef ROTATE |
678 | l = 0; | 679 | l = 0; |
679 | for (i=0; i<pf->size; ++i) { | 680 | for (i=0; i<pf->size; ++i) { |
@@ -698,9 +699,9 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
698 | pf->offset = NULL; | 699 | pf->offset = NULL; |
699 | } | 700 | } |
700 | 701 | ||
701 | /* determine whether font is fixed-width*/ | 702 | /* determine whether font is fixed-width */ |
702 | for (i=0; i<pf->size; ++i) { | 703 | for (i=0; i<pf->size; ++i) { |
703 | if (pf->width[i] != maxwidth) { | 704 | if (pf->width[i] != pf->maxwidth) { |
704 | proportional = 1; | 705 | proportional = 1; |
705 | break; | 706 | break; |
706 | } | 707 | } |
@@ -710,21 +711,11 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
710 | pf->width = NULL; | 711 | pf->width = NULL; |
711 | } | 712 | } |
712 | 713 | ||
713 | /* reallocate bits array to actual bits used*/ | 714 | /* reallocate bits array to actual bits used */ |
714 | if (ofs < pf->bits_size) { | 715 | if (ofs < pf->bits_size) { |
715 | pf->bits = realloc(pf->bits, ofs * sizeof(bitmap_t)); | 716 | pf->bits = realloc(pf->bits, ofs * sizeof(bitmap_t)); |
716 | pf->bits_size = ofs; | 717 | pf->bits_size = ofs; |
717 | } | 718 | } |
718 | else { | ||
719 | if (ofs > pf->bits_size) { | ||
720 | fprintf(stderr, "Warning: DWIDTH spec > max FONTBOUNDINGBOX\n"); | ||
721 | if (ofs > pf->bits_size+EXTRA) { | ||
722 | fprintf(stderr, "Error: Not enough bits initially allocated\n"); | ||
723 | return 0; | ||
724 | } | ||
725 | pf->bits_size = ofs; | ||
726 | } | ||
727 | } | ||
728 | 719 | ||
729 | #ifdef ROTATE | 720 | #ifdef ROTATE |
730 | pf->bits_size = ofr; /* always update, rotated is smaller */ | 721 | pf->bits_size = ofr; /* always update, rotated is smaller */ |
@@ -733,7 +724,7 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf) | |||
733 | return 1; | 724 | return 1; |
734 | } | 725 | } |
735 | 726 | ||
736 | /* read the next non-comment line, returns buf or NULL if EOF*/ | 727 | /* read the next non-comment line, returns buf or NULL if EOF */ |
737 | char *bdf_getline(FILE *fp, char *buf, int len) | 728 | char *bdf_getline(FILE *fp, char *buf, int len) |
738 | { | 729 | { |
739 | int c; | 730 | int c; |
@@ -758,6 +749,19 @@ char *bdf_getline(FILE *fp, char *buf, int len) | |||
758 | } | 749 | } |
759 | return buf; | 750 | return buf; |
760 | } | 751 | } |
752 | |||
753 | /* | ||
754 | Calculates the necessary size of the bit buffer to hold all the | ||
755 | bitmaps for the glyphs in the font. Shoud be called every time | ||
756 | the max width of the font grows. Font height, the max width and | ||
757 | the number of chars in the font must have been already set. | ||
758 | */ | ||
759 | void bitmap_buf_alloc(struct font* pf) | ||
760 | { | ||
761 | pf->bits_size = pf->size * BITMAP_WORDS(pf->maxwidth) * pf->height; | ||
762 | pf->bits = (bitmap_t *)realloc(pf->bits, pf->bits_size * sizeof(bitmap_t)); | ||
763 | } | ||
764 | |||
761 | 765 | ||
762 | /* return hex value of portion of buffer*/ | 766 | /* return hex value of portion of buffer*/ |
763 | bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2) | 767 | bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2) |
@@ -796,7 +800,7 @@ int rotleft(unsigned char *dst, /* output buffer */ | |||
796 | bitmap_t *src, unsigned int width, unsigned int height) | 800 | bitmap_t *src, unsigned int width, unsigned int height) |
797 | { | 801 | { |
798 | unsigned int i,j; | 802 | unsigned int i,j; |
799 | unsigned int src_words; /* # words of input image*/ | 803 | unsigned int src_words; /* # words of input image */ |
800 | unsigned int dst_mask; /* bit mask for destination */ | 804 | unsigned int dst_mask; /* bit mask for destination */ |
801 | bitmap_t src_mask; /* bit mask for source */ | 805 | bitmap_t src_mask; /* bit mask for source */ |
802 | 806 | ||
@@ -913,7 +917,7 @@ int gen_c_source(struct font* pf, char *path) | |||
913 | bitmap_t bitvalue=0; | 917 | bitmap_t bitvalue=0; |
914 | 918 | ||
915 | /* Skip missing glyphs */ | 919 | /* Skip missing glyphs */ |
916 | if (pf->offset && (pf->offset[i] == (unsigned int)-1)) | 920 | if (pf->offset && (pf->offset[i] == -1)) |
917 | continue; | 921 | continue; |
918 | 922 | ||
919 | bits = pf->bits + (pf->offset? (int)pf->offset[i]: (pf->height * i)); | 923 | bits = pf->bits + (pf->offset? (int)pf->offset[i]: (pf->height * i)); |
@@ -994,7 +998,7 @@ int gen_c_source(struct font* pf, char *path) | |||
994 | "static const unsigned short _sysfont_offset[] = {\n"); | 998 | "static const unsigned short _sysfont_offset[] = {\n"); |
995 | 999 | ||
996 | for (i=0; i<pf->size; ++i) { | 1000 | for (i=0; i<pf->size; ++i) { |
997 | if (pf->offset[i] == (unsigned int)-1) { | 1001 | if (pf->offset[i] == -1) { |
998 | pf->offset[i] = pf->offset[pf->defaultchar - pf->firstchar]; | 1002 | pf->offset[i] = pf->offset[pf->defaultchar - pf->firstchar]; |
999 | pf->offrot[i] = pf->offrot[pf->defaultchar - pf->firstchar]; | 1003 | pf->offrot[i] = pf->offrot[pf->defaultchar - pf->firstchar]; |
1000 | } | 1004 | } |
@@ -1030,7 +1034,7 @@ int gen_c_source(struct font* pf, char *path) | |||
1030 | else | 1034 | else |
1031 | sprintf(buf, "0, /* fixed width */"); | 1035 | sprintf(buf, "0, /* fixed width */"); |
1032 | 1036 | ||
1033 | fprintf(ofp, "/* Exported structure definition. */\n" | 1037 | fprintf(ofp, "/* Exported structure definition. */\n" |
1034 | "const struct font sysfont = {\n" | 1038 | "const struct font sysfont = {\n" |
1035 | " %d, /* maxwidth */\n" | 1039 | " %d, /* maxwidth */\n" |
1036 | " %d, /* height */\n" | 1040 | " %d, /* height */\n" |
@@ -1188,9 +1192,9 @@ int gen_fnt_file(struct font* pf, char *path) | |||
1188 | writeint(ofp, pf->size); | 1192 | writeint(ofp, pf->size); |
1189 | 1193 | ||
1190 | /* variable font data sizes*/ | 1194 | /* variable font data sizes*/ |
1191 | writeint(ofp, pf->bits_size); /* # words of bitmap_t*/ | 1195 | writeint(ofp, pf->bits_size); /* # words of bitmap_t*/ |
1192 | writeint(ofp, pf->offset? pf->size: 0); /* # ints of offset*/ | 1196 | writeint(ofp, pf->offset? pf->size: 0); /* # ints of offset*/ |
1193 | writeint(ofp, pf->width? pf->size: 0); /* # bytes of width*/ | 1197 | writeint(ofp, pf->width? pf->size: 0); /* # bytes of width*/ |
1194 | /* variable font data*/ | 1198 | /* variable font data*/ |
1195 | #ifdef ROTATE | 1199 | #ifdef ROTATE |
1196 | for (i=0; i<pf->size; ++i) | 1200 | for (i=0; i<pf->size; ++i) |
@@ -1201,7 +1205,7 @@ int gen_fnt_file(struct font* pf, char *path) | |||
1201 | unsigned char bytemap[512]; | 1205 | unsigned char bytemap[512]; |
1202 | 1206 | ||
1203 | /* Skip missing glyphs */ | 1207 | /* Skip missing glyphs */ |
1204 | if (pf->offset && (pf->offset[i] == (unsigned int)-1)) | 1208 | if (pf->offset && (pf->offset[i] == -1)) |
1205 | continue; | 1209 | continue; |
1206 | 1210 | ||
1207 | bits = pf->bits + (pf->offset? (int)pf->offset[i]: (pf->height * i)); | 1211 | bits = pf->bits + (pf->offset? (int)pf->offset[i]: (pf->height * i)); |
@@ -1231,7 +1235,7 @@ int gen_fnt_file(struct font* pf, char *path) | |||
1231 | { | 1235 | { |
1232 | for (i=0; i<pf->size; ++i) | 1236 | for (i=0; i<pf->size; ++i) |
1233 | { | 1237 | { |
1234 | if (pf->offset[i] == (unsigned int)-1) { | 1238 | if (pf->offset[i] == -1) { |
1235 | pf->offrot[i] = pf->offrot[pf->defaultchar - pf->firstchar]; | 1239 | pf->offrot[i] = pf->offrot[pf->defaultchar - pf->firstchar]; |
1236 | } | 1240 | } |
1237 | if ( pf->bits_size < 0xFFDB ) | 1241 | if ( pf->bits_size < 0xFFDB ) |
@@ -1248,7 +1252,7 @@ int gen_fnt_file(struct font* pf, char *path) | |||
1248 | for (i=0; i<pf->bits_size; ++i) | 1252 | for (i=0; i<pf->bits_size; ++i) |
1249 | writeshort(ofp, pf->bits[i]); | 1253 | writeshort(ofp, pf->bits[i]); |
1250 | if (ftell(ofp) & 2) | 1254 | if (ftell(ofp) & 2) |
1251 | writeshort(ofp, 0); /* pad to 32-bit boundary*/ | 1255 | writeshort(ofp, 0); /* pad to 32-bit boundary*/ |
1252 | 1256 | ||
1253 | if (pf->offset) | 1257 | if (pf->offset) |
1254 | for (i=0; i<pf->size; ++i) { | 1258 | for (i=0; i<pf->size; ++i) { |