diff options
author | Björn Stenberg <bjorn@haxx.se> | 2002-09-20 08:07:51 +0000 |
---|---|---|
committer | Björn Stenberg <bjorn@haxx.se> | 2002-09-20 08:07:51 +0000 |
commit | bed3d3f7e06c6582f9677ab6222cd89c84a9c8c7 (patch) | |
tree | 59ef1faa129f0813071d5e81b2e55b5d04886202 /firmware/font.c | |
parent | eb5cc653dba373f2d2ce48f8efbc0b19a424971e (diff) | |
download | rockbox-bed3d3f7e06c6582f9677ab6222cd89c84a9c8c7.tar.gz rockbox-bed3d3f7e06c6582f9677ab6222cd89c84a9c8c7.zip |
New full ISO-8859-1 system font.
Added font loading from dir browser.
Changed default font location to /.rockbox/default.fnt.
Code-policed font code.
Removed old font tools.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@2347 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/font.c')
-rw-r--r-- | firmware/font.c | 339 |
1 files changed, 215 insertions, 124 deletions
diff --git a/firmware/font.c b/firmware/font.c index e9c70cd64e..72c7085b7a 100644 --- a/firmware/font.c +++ b/firmware/font.c | |||
@@ -30,165 +30,257 @@ | |||
30 | #include <string.h> | 30 | #include <string.h> |
31 | #include "lcd.h" | 31 | #include "lcd.h" |
32 | #include "font.h" | 32 | #include "font.h" |
33 | #include "file.h" | ||
33 | #include "debug.h" | 34 | #include "debug.h" |
34 | #include "panic.h" | 35 | #include "panic.h" |
35 | 36 | ||
36 | /* available compiled-in fonts*/ | 37 | #ifndef O_BINARY |
37 | extern MWCFONT font_X5x8; | 38 | #define O_BINARY 0 |
38 | /*extern MWCFONT font_X6x9; */ | 39 | #endif |
39 | /*extern MWCFONT font_courB08; */ | 40 | |
40 | /*extern MWCFONT font_timR08; */ | 41 | /* compiled-in font */ |
42 | extern struct font sysfont; | ||
41 | 43 | ||
42 | /* structure filled in by rbf_load_font*/ | 44 | /* structure filled in by font_load */ |
43 | static MWCFONT font_UI; | 45 | static struct font font_ui; |
44 | 46 | ||
45 | /* system font table, in order of FONT_xxx definition*/ | 47 | /* system font table, in order of FONT_xxx definition */ |
46 | struct corefont sysfonts[MAXFONTS] = { | 48 | static struct font* sysfonts[MAXFONTS] = { &sysfont, &font_ui }; |
47 | { &font_X5x8, NULL }, /* compiled-in FONT_SYSFIXED*/ | ||
48 | { &font_UI, "/system.fnt" }, /* loaded FONT_UI*/ | ||
49 | { NULL, NULL }, /* no FONT_MP3*/ | ||
50 | }; | ||
51 | 49 | ||
52 | static void rotate_font_bits(PMWCFONT pf); | 50 | /* static buffer allocation structures */ |
53 | static void rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width, | 51 | static unsigned char mbuf[MAX_FONT_SIZE]; |
54 | unsigned int height); | 52 | static unsigned char *freeptr = mbuf; |
53 | static unsigned char *fileptr; | ||
54 | static unsigned char *eofptr; | ||
55 | 55 | ||
56 | void | 56 | static void rotate_font_bits(struct font* pf); |
57 | font_init(void) | 57 | static void rotleft(unsigned char *dst, |
58 | bitmap_t *src, | ||
59 | unsigned int width, | ||
60 | unsigned int height); | ||
61 | |||
62 | void font_init(void) | ||
58 | { | 63 | { |
59 | struct corefont *cfp; | 64 | rotate_font_bits(&sysfont); |
60 | 65 | memset(&font_ui, 0, sizeof(struct font)); | |
61 | for (cfp=sysfonts; cfp < &sysfonts[MAXFONTS]; ++cfp) { | 66 | } |
62 | if (cfp->pf && cfp->diskname) { | ||
63 | cfp->pf = rbf_load_font(cfp->diskname, cfp->pf); | ||
64 | #if defined(DEBUG) || defined(SIMULATOR) | ||
65 | if (!cfp->pf) | ||
66 | DEBUGF("Font load failed: %s\n", cfp->diskname); | ||
67 | #endif | ||
68 | } | ||
69 | 67 | ||
70 | /* one-time rotate font bits to rockbox format*/ | 68 | static int readshort(unsigned short *sp) |
71 | if (cfp->pf && cfp->pf->height) | 69 | { |
72 | rotate_font_bits(cfp->pf); | 70 | unsigned short s; |
73 | } | 71 | |
72 | s = *fileptr++ & 0xff; | ||
73 | *sp = (*fileptr++ << 8) | s; | ||
74 | return (fileptr <= eofptr); | ||
74 | } | 75 | } |
75 | 76 | ||
76 | /* | 77 | static int readlong(unsigned long *lp) |
77 | * Return a pointer to an incore font structure. | ||
78 | * If the requested font isn't loaded/compiled-in, | ||
79 | * decrement the font number and try again. | ||
80 | */ | ||
81 | PMWCFONT | ||
82 | getfont(int font) | ||
83 | { | 78 | { |
84 | PMWCFONT pf; | 79 | unsigned long l; |
85 | 80 | ||
86 | if (font >= MAXFONTS) | 81 | l = *fileptr++ & 0xff; |
87 | font = 0; | 82 | l |= *fileptr++ << 8; |
88 | while (1) { | 83 | l |= *fileptr++ << 16; |
89 | pf = sysfonts[font].pf; | 84 | *lp = (*fileptr++ << 24) | l; |
90 | if (pf && pf->height) | 85 | return (fileptr <= eofptr); |
91 | return pf; | ||
92 | if (--font < 0) | ||
93 | panicf("No font!"); | ||
94 | } | ||
95 | } | 86 | } |
96 | 87 | ||
97 | /* | 88 | /* read count bytes*/ |
98 | * Return width and height of a given font. | 89 | static int readstr(char *buf, int count) |
99 | */ | ||
100 | void lcd_getfontsize(int font, int *width, int *height) | ||
101 | { | 90 | { |
102 | PMWCFONT pf = getfont(font); | 91 | int n = count; |
103 | 92 | ||
104 | *width = pf->maxwidth; | 93 | while (--n >= 0) |
105 | *height = pf->height; | 94 | *buf++ = *fileptr++; |
95 | return (fileptr <= eofptr)? count: 0; | ||
106 | } | 96 | } |
107 | 97 | ||
108 | /* | 98 | /* read totlen bytes, return NUL terminated string*/ |
109 | * Return width and height of a given font. | 99 | /* may write 1 past buf[totlen]; removes blank pad*/ |
110 | */ | 100 | static int readstrpad(char *buf, int totlen) |
111 | //FIXME rename to font_gettextsize, add baseline | ||
112 | int | ||
113 | lcd_getstringsize(unsigned char *str, int font, int *w, int *h) | ||
114 | { | 101 | { |
115 | PMWCFONT pf = getfont(font); | 102 | char *p = buf; |
116 | int ch; | 103 | int n = totlen; |
117 | int width = 0; | 104 | |
118 | 105 | while (--n >= 0) | |
119 | while((ch = *str++)) { | 106 | *p++ = *fileptr++; |
120 | /* check input range*/ | 107 | if (fileptr > eofptr) |
121 | if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) | 108 | return 0; |
122 | ch = pf->defaultchar; | 109 | |
123 | ch -= pf->firstchar; | 110 | p = &buf[totlen]; |
124 | 111 | *p-- = 0; | |
125 | /* get proportional width and glyph bits*/ | 112 | while (*p == ' ' && p >= buf) |
126 | width += pf->width? pf->width[ch]: pf->maxwidth; | 113 | *p-- = '\0'; |
114 | return totlen; | ||
115 | } | ||
116 | |||
117 | /* read and load font into incore font structure*/ | ||
118 | struct font* font_load(char *path) | ||
119 | { | ||
120 | int fd, filesize; | ||
121 | unsigned short maxwidth, height, ascent, pad; | ||
122 | unsigned long firstchar, defaultchar, size; | ||
123 | unsigned long i, nbits, noffset, nwidth; | ||
124 | char version[4+1]; | ||
125 | char copyright[256+1]; | ||
126 | struct font* pf = &font_ui; | ||
127 | |||
128 | memset(pf, 0, sizeof(struct font)); | ||
129 | |||
130 | /* open and read entire font file*/ | ||
131 | fd = open(path, O_RDONLY|O_BINARY); | ||
132 | if (fd < 0) { | ||
133 | DEBUGF("Can't open font: %s\n", path); | ||
134 | return NULL; | ||
135 | } | ||
136 | |||
137 | /* currently, font loading replaces earlier font allocation*/ | ||
138 | freeptr = (unsigned char *)(((int)mbuf + 3) & ~3); | ||
139 | |||
140 | fileptr = freeptr; | ||
141 | filesize = read(fd, fileptr, MAX_FONT_SIZE); | ||
142 | eofptr = fileptr + filesize; | ||
143 | |||
144 | /* no need for multiple font loads currently*/ | ||
145 | /*freeptr += filesize;*/ | ||
146 | /*freeptr = (unsigned char *)(freeptr + 3) & ~3;*/ /* pad freeptr*/ | ||
147 | |||
148 | close(fd); | ||
149 | if (filesize == MAX_FONT_SIZE) { | ||
150 | DEBUGF("Font %s too large: %d\n", path, filesize); | ||
151 | return NULL; | ||
127 | } | 152 | } |
128 | *w = width; | ||
129 | *h = pf->height; | ||
130 | 153 | ||
131 | return width; | 154 | /* read magic and version #*/ |
155 | memset(version, 0, sizeof(version)); | ||
156 | if (readstr(version, 4) != 4) | ||
157 | return NULL; | ||
158 | if (strcmp(version, VERSION) != 0) | ||
159 | return NULL; | ||
160 | |||
161 | /* internal font name*/ | ||
162 | pf->name = fileptr; | ||
163 | if (readstrpad(pf->name, 64) != 64) | ||
164 | return NULL; | ||
165 | |||
166 | /* copyright, not currently stored*/ | ||
167 | if (readstrpad(copyright, 256) != 256) | ||
168 | return NULL; | ||
169 | |||
170 | /* font info*/ | ||
171 | if (!readshort(&maxwidth)) | ||
172 | return NULL; | ||
173 | pf->maxwidth = maxwidth; | ||
174 | if (!readshort(&height)) | ||
175 | return NULL; | ||
176 | pf->height = height; | ||
177 | if (!readshort(&ascent)) | ||
178 | return NULL; | ||
179 | pf->ascent = ascent; | ||
180 | if (!readshort(&pad)) | ||
181 | return NULL; | ||
182 | if (!readlong(&firstchar)) | ||
183 | return NULL; | ||
184 | pf->firstchar = firstchar; | ||
185 | if (!readlong(&defaultchar)) | ||
186 | return NULL; | ||
187 | pf->defaultchar = defaultchar; | ||
188 | if (!readlong(&size)) | ||
189 | return NULL; | ||
190 | pf->size = size; | ||
191 | |||
192 | /* get variable font data sizes*/ | ||
193 | /* # words of bitmap_t*/ | ||
194 | if (!readlong(&nbits)) | ||
195 | return NULL; | ||
196 | pf->bits_size = nbits; | ||
197 | |||
198 | /* # longs of offset*/ | ||
199 | if (!readlong(&noffset)) | ||
200 | return NULL; | ||
201 | |||
202 | /* # bytes of width*/ | ||
203 | if (!readlong(&nwidth)) | ||
204 | return NULL; | ||
205 | |||
206 | /* variable font data*/ | ||
207 | pf->bits = (bitmap_t *)fileptr; | ||
208 | for (i=0; i<nbits; ++i) | ||
209 | if (!readshort(&pf->bits[i])) | ||
210 | return NULL; | ||
211 | /* pad to longword boundary*/ | ||
212 | fileptr = (unsigned char *)(((int)fileptr + 3) & ~3); | ||
213 | |||
214 | if (noffset) { | ||
215 | pf->offset = (unsigned long *)fileptr; | ||
216 | for (i=0; i<noffset; ++i) | ||
217 | if (!readlong(&pf->offset[i])) | ||
218 | return NULL; | ||
219 | } | ||
220 | else | ||
221 | pf->offset = NULL; | ||
222 | |||
223 | if (nwidth) { | ||
224 | pf->width = (unsigned char *)fileptr; | ||
225 | fileptr += nwidth*sizeof(unsigned char); | ||
226 | } | ||
227 | else | ||
228 | pf->width = NULL; | ||
229 | |||
230 | if (fileptr > eofptr) | ||
231 | return NULL; | ||
232 | |||
233 | /* one-time rotate font bits to rockbox format*/ | ||
234 | rotate_font_bits(pf); | ||
235 | |||
236 | return pf; /* success!*/ | ||
132 | } | 237 | } |
133 | 238 | ||
134 | /* | 239 | /* |
135 | * Put a string at specified bit position | 240 | * Return a pointer to an incore font structure. |
241 | * If the requested font isn't loaded/compiled-in, | ||
242 | * decrement the font number and try again. | ||
136 | */ | 243 | */ |
137 | //FIXME rename font_putsxy? | 244 | struct font* font_get(int font) |
138 | void | ||
139 | lcd_putsxy(int x, int y, unsigned char *str, int font) | ||
140 | { | 245 | { |
141 | int ch; | 246 | struct font* pf; |
142 | PMWCFONT pf = getfont(font); | 247 | |
143 | 248 | if (font >= MAXFONTS) | |
144 | while (((ch = *str++) != '\0')) { | 249 | font = 0; |
145 | MWIMAGEBITS *bits; | 250 | |
146 | int width; | 251 | while (1) { |
147 | 252 | pf = sysfonts[font]; | |
148 | /* check input range*/ | 253 | if (pf && pf->height) |
149 | if (ch < pf->firstchar || ch >= pf->firstchar+pf->size) | 254 | return pf; |
150 | ch = pf->defaultchar; | 255 | if (--font < 0) |
151 | ch -= pf->firstchar; | 256 | panicf("No font!"); |
152 | |||
153 | /* get proportional width and glyph bits*/ | ||
154 | width = pf->width? pf->width[ch]: pf->maxwidth; | ||
155 | if (x + width > LCD_WIDTH) | ||
156 | break; | ||
157 | |||
158 | /* no partial-height drawing for now...*/ | ||
159 | if (y + pf->height > LCD_HEIGHT) | ||
160 | break; | ||
161 | bits = pf->bits + (pf->offset? pf->offset[ch]: (pf->height * ch)); | ||
162 | |||
163 | lcd_bitmap((unsigned char *)bits, x, y, width, pf->height, true); | ||
164 | x += width; | ||
165 | } | 257 | } |
166 | } | 258 | } |
167 | 259 | ||
168 | /* convert font bitmap data inplace to rockbox format*/ | 260 | /* convert font bitmap data inplace to rockbox format*/ |
169 | static void | 261 | static void rotate_font_bits(struct font* pf) |
170 | rotate_font_bits(PMWCFONT pf) | ||
171 | { | 262 | { |
172 | int i; | 263 | int i; |
173 | int defaultchar = pf->defaultchar - pf->firstchar; | 264 | unsigned long defaultchar = pf->defaultchar - pf->firstchar; |
174 | int did_defaultchar = 0; | 265 | bool did_defaultchar = false; |
175 | unsigned char buf[256]; | 266 | unsigned char buf[256]; |
176 | 267 | ||
177 | for (i=0; i<pf->size; ++i) { | 268 | for (i=0; i<pf->size; ++i) { |
178 | MWIMAGEBITS *bits = pf->bits + | 269 | bitmap_t *bits = pf->bits + |
179 | (pf->offset? pf->offset[i]: (pf->height * i)); | 270 | (pf->offset ? pf->offset[i] : (pf->height * i)); |
180 | int width = pf->width? pf->width[i]: pf->maxwidth; | 271 | int width = pf->width? pf->width[i]: pf->maxwidth; |
181 | int src_bytes = MWIMAGE_BYTES(width) * pf->height; | 272 | int src_bytes = BITMAP_BYTES(width) * pf->height; |
182 | 273 | ||
183 | /* | 274 | /* |
184 | * Due to the way the offset map works, | 275 | * Due to the way the offset map works, |
185 | * non-mapped characters are mapped to the default | 276 | * non-mapped characters are mapped to the default |
186 | * character, and shouldn't be rotated twice. | 277 | * character, and shouldn't be rotated twice. |
187 | */ | 278 | */ |
188 | if (i == defaultchar) { | 279 | |
280 | if (pf->offset && pf->offset[i] == defaultchar) { | ||
189 | if (did_defaultchar) | 281 | if (did_defaultchar) |
190 | continue; | 282 | continue; |
191 | did_defaultchar = 1; | 283 | did_defaultchar = true; |
192 | } | 284 | } |
193 | 285 | ||
194 | /* rotate left for lcd_bitmap function input*/ | 286 | /* rotate left for lcd_bitmap function input*/ |
@@ -200,16 +292,15 @@ rotate_font_bits(PMWCFONT pf) | |||
200 | } | 292 | } |
201 | 293 | ||
202 | /* | 294 | /* |
203 | * Take an MWIMAGEBITS bitmap and convert to Rockbox format. | 295 | * Take an bitmap_t bitmap and convert to Rockbox format. |
204 | * Used for converting font glyphs for the time being. | 296 | * Used for converting font glyphs for the time being. |
205 | * Can use for standard X11 and Win32 images as well. | 297 | * Can use for standard X11 and Win32 images as well. |
206 | * | 298 | * |
207 | * Doing it this way keeps fonts in standard formats, | 299 | * Doing it this way keeps fonts in standard formats, |
208 | * as well as keeping Rockbox hw bitmap format. | 300 | * as well as keeping Rockbox hw bitmap format. |
209 | */ | 301 | */ |
210 | static void | 302 | static void rotleft(unsigned char *dst, bitmap_t *src, unsigned int width, |
211 | rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width, | 303 | unsigned int height) |
212 | unsigned int height) | ||
213 | { | 304 | { |
214 | unsigned int i,j; | 305 | unsigned int i,j; |
215 | unsigned int dst_col = 0; /* destination column*/ | 306 | unsigned int dst_col = 0; /* destination column*/ |
@@ -221,17 +312,17 @@ rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width, | |||
221 | dst_linelen = (height-1)/8+1; | 312 | dst_linelen = (height-1)/8+1; |
222 | 313 | ||
223 | /* calc words of input image*/ | 314 | /* calc words of input image*/ |
224 | src_words = MWIMAGE_WORDS(width) * height; | 315 | src_words = BITMAP_WORDS(width) * height; |
225 | 316 | ||
226 | /* clear background*/ | 317 | /* clear background*/ |
227 | memset(dst, 0, dst_linelen*width); | 318 | memset(dst, 0, dst_linelen*width); |
228 | 319 | ||
229 | for (i=0; i < src_words; i++) { | 320 | for (i=0; i < src_words; i++) { |
230 | MWIMAGEBITS srcmap; /* current src input bit*/ | 321 | bitmap_t srcmap; /* current src input bit*/ |
231 | MWIMAGEBITS dstmap; /* current dst output bit*/ | 322 | bitmap_t dstmap; /* current dst output bit*/ |
232 | 323 | ||
233 | /* calc src input bit*/ | 324 | /* calc src input bit*/ |
234 | srcmap = 1 << (sizeof(MWIMAGEBITS)*8-1); | 325 | srcmap = 1 << (sizeof(bitmap_t)*8-1); |
235 | 326 | ||
236 | /* calc dst output bit*/ | 327 | /* calc dst output bit*/ |
237 | if (i>0 && (i%8==0)) { | 328 | if (i>0 && (i%8==0)) { |
@@ -244,9 +335,9 @@ rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width, | |||
244 | for(j=0; j < width; j++) { | 335 | for(j=0; j < width; j++) { |
245 | 336 | ||
246 | /* calc input bitmask*/ | 337 | /* calc input bitmask*/ |
247 | MWIMAGEBITS bit = srcmap >> j; | 338 | bitmap_t bit = srcmap >> j; |
248 | if (bit==0) { | 339 | if (bit==0) { |
249 | srcmap = 1 << (sizeof(MWIMAGEBITS)*8-1); | 340 | srcmap = 1 << (sizeof(bitmap_t)*8-1); |
250 | bit = srcmap >> (j % 16); | 341 | bit = srcmap >> (j % 16); |
251 | } | 342 | } |
252 | 343 | ||