1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
10 * Copyright (c) 2002 by Greg Haerr <greg@censoft.com>
12 * All files in this archive are subject to the GNU General Public License.
13 * See the file COPYING in the source tree root for full license agreement.
15 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
16 * KIND, either express or implied.
18 ****************************************************************************/
20 * Rockbox startup font initialization
21 * This file specifies which fonts get compiled-in and
22 * loaded at startup, as well as their mapping into
23 * the FONT_SYSFIXED, FONT_UI and FONT_MP3 ids.
27 #if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
41 /* compiled-in font */
42 extern struct font sysfont
;
44 /* structure filled in by font_load */
45 static struct font font_ui
;
47 /* system font table, in order of FONT_xxx definition */
48 static struct font
* sysfonts
[MAXFONTS
] = { &sysfont
, &font_ui
};
50 /* static buffer allocation structures */
51 static unsigned char mbuf
[MAX_FONT_SIZE
];
52 static unsigned char *freeptr
= mbuf
;
53 static unsigned char *fileptr
;
54 static unsigned char *eofptr
;
56 static void rotate_font_bits(struct font
* pf
);
57 static void rotleft(unsigned char *dst
,
64 rotate_font_bits(&sysfont
);
65 memset(&font_ui
, 0, sizeof(struct font
));
68 static int readshort(unsigned short *sp
)
72 s
= *fileptr
++ & 0xff;
73 *sp
= (*fileptr
++ << 8) | s
;
74 return (fileptr
<= eofptr
);
77 static int readlong(unsigned long *lp
)
81 l
= *fileptr
++ & 0xff;
83 l
|= *fileptr
++ << 16;
84 *lp
= (*fileptr
++ << 24) | l
;
85 return (fileptr
<= eofptr
);
89 static int readstr(char *buf
, int count
)
95 return (fileptr
<= eofptr
)? count
: 0;
98 /* read totlen bytes, return NUL terminated string*/
99 /* may write 1 past buf[totlen]; removes blank pad*/
100 static int readstrpad(char *buf
, int totlen
)
107 if (fileptr
> eofptr
)
112 while (*p
== ' ' && p
>= buf
)
117 void font_reset(void)
119 memset(&font_ui
, 0, sizeof(struct font
));
122 /* read and load font into incore font structure*/
123 struct font
* font_load(char *path
)
126 unsigned short maxwidth
, height
, ascent
, pad
;
127 unsigned long firstchar
, defaultchar
, size
;
128 unsigned long i
, nbits
, noffset
, nwidth
;
130 char copyright
[256+1];
131 struct font
* pf
= &font_ui
;
133 /* open and read entire font file*/
134 fd
= open(path
, O_RDONLY
|O_BINARY
);
136 DEBUGF("Can't open font: %s\n", path
);
142 /* currently, font loading replaces earlier font allocation*/
143 freeptr
= (unsigned char *)(((int)mbuf
+ 3) & ~3);
146 filesize
= read(fd
, fileptr
, MAX_FONT_SIZE
);
147 eofptr
= fileptr
+ filesize
;
149 /* no need for multiple font loads currently*/
150 /*freeptr += filesize;*/
151 /*freeptr = (unsigned char *)(freeptr + 3) & ~3;*/ /* pad freeptr*/
154 if (filesize
== MAX_FONT_SIZE
) {
155 DEBUGF("Font %s too large: %d\n", path
, filesize
);
159 /* read magic and version #*/
160 memset(version
, 0, sizeof(version
));
161 if (readstr(version
, 4) != 4)
163 if (strcmp(version
, VERSION
) != 0)
166 /* internal font name*/
168 if (readstrpad(pf
->name
, 64) != 64)
171 /* copyright, not currently stored*/
172 if (readstrpad(copyright
, 256) != 256)
176 if (!readshort(&maxwidth
))
178 pf
->maxwidth
= maxwidth
;
179 if (!readshort(&height
))
182 if (!readshort(&ascent
))
185 if (!readshort(&pad
))
187 if (!readlong(&firstchar
))
189 pf
->firstchar
= firstchar
;
190 if (!readlong(&defaultchar
))
192 pf
->defaultchar
= defaultchar
;
193 if (!readlong(&size
))
197 /* get variable font data sizes*/
198 /* # words of bitmap_t*/
199 if (!readlong(&nbits
))
201 pf
->bits_size
= nbits
;
203 /* # longs of offset*/
204 if (!readlong(&noffset
))
207 /* # bytes of width*/
208 if (!readlong(&nwidth
))
211 /* variable font data*/
212 pf
->bits
= (bitmap_t
*)fileptr
;
213 for (i
=0; i
<nbits
; ++i
)
214 if (!readshort(&pf
->bits
[i
]))
216 /* pad to longword boundary*/
217 fileptr
= (unsigned char *)(((int)fileptr
+ 3) & ~3);
220 pf
->offset
= (unsigned long *)fileptr
;
221 for (i
=0; i
<noffset
; ++i
)
222 if (!readlong(&pf
->offset
[i
]))
229 pf
->width
= (unsigned char *)fileptr
;
230 fileptr
+= nwidth
*sizeof(unsigned char);
235 if (fileptr
> eofptr
)
238 /* one-time rotate font bits to rockbox format*/
239 rotate_font_bits(pf
);
241 return pf
; /* success!*/
245 * Return a pointer to an incore font structure.
246 * If the requested font isn't loaded/compiled-in,
247 * decrement the font number and try again.
249 struct font
* font_get(int font
)
253 if (font
>= MAXFONTS
)
258 if (pf
&& pf
->height
)
265 /* convert font bitmap data inplace to rockbox format*/
266 static void rotate_font_bits(struct font
* pf
)
269 unsigned long defaultchar
= pf
->defaultchar
- pf
->firstchar
;
270 bool did_defaultchar
= false;
271 unsigned char buf
[256];
273 for (i
=0; i
<pf
->size
; ++i
) {
274 bitmap_t
*bits
= pf
->bits
+
275 (pf
->offset
? pf
->offset
[i
] : (pf
->height
* i
));
276 int width
= pf
->width
? pf
->width
[i
]: pf
->maxwidth
;
277 int src_bytes
= BITMAP_BYTES(width
) * pf
->height
;
280 * Due to the way the offset map works,
281 * non-mapped characters are mapped to the default
282 * character, and shouldn't be rotated twice.
285 if (pf
->offset
&& pf
->offset
[i
] == defaultchar
) {
288 did_defaultchar
= true;
291 /* rotate left for lcd_bitmap function input*/
292 rotleft(buf
, bits
, width
, pf
->height
);
294 /* copy back into original location*/
295 memcpy(bits
, buf
, src_bytes
);
300 * Take an bitmap_t bitmap and convert to Rockbox format.
301 * Used for converting font glyphs for the time being.
302 * Can use for standard X11 and Win32 images as well.
304 * Doing it this way keeps fonts in standard formats,
305 * as well as keeping Rockbox hw bitmap format.
307 static void rotleft(unsigned char *dst
, bitmap_t
*src
, unsigned int width
,
311 unsigned int dst_col
= 0; /* destination column*/
312 unsigned int dst_shift
= 0; /* destination shift amount*/
313 unsigned int dst_linelen
; /* # bytes per output row*/
314 unsigned int src_words
; /* # words of input image*/
316 /* calc bytes per output row*/
317 dst_linelen
= (height
-1)/8+1;
319 /* calc words of input image*/
320 src_words
= BITMAP_WORDS(width
) * height
;
322 /* clear background*/
323 memset(dst
, 0, dst_linelen
*width
);
325 for (i
=0; i
< src_words
; i
++) {
326 bitmap_t srcmap
; /* current src input bit*/
327 bitmap_t dstmap
; /* current dst output bit*/
329 /* calc src input bit*/
330 srcmap
= 1 << (sizeof(bitmap_t
)*8-1);
332 /* calc dst output bit*/
333 if (i
>0 && (i
%8==0)) {
337 dstmap
= 1 << dst_shift
++;
339 /* for each input column...*/
340 for(j
=0; j
< width
; j
++) {
342 /* calc input bitmask*/
343 bitmap_t bit
= srcmap
>> j
;
345 srcmap
= 1 << (sizeof(bitmap_t
)*8-1);
346 bit
= srcmap
>> (j
% 16);
349 /* if set in input, set in rotated output*/
351 /* input column j becomes output row*/
352 dst
[j
*dst_linelen
+ dst_col
] |= dstmap
;
354 /*debugf((bit & src[i])? "*": ".");*/
359 #endif /* HAVE_LCD_BITMAP */
361 /* -----------------------------------------------------------------
363 * eval: (load-file "rockbox-mode.el")
364 * vim: et sw=4 ts=8 sts=4 tw=78