summaryrefslogtreecommitdiffstats
path: root/firmware/font.c
diff options
context:
space:
mode:
authorBjörn Stenberg <bjorn@haxx.se>2002-09-20 08:07:51 +0000
committerBjörn Stenberg <bjorn@haxx.se>2002-09-20 08:07:51 +0000
commitbed3d3f7e06c6582f9677ab6222cd89c84a9c8c7 (patch)
tree59ef1faa129f0813071d5e81b2e55b5d04886202 /firmware/font.c
parenteb5cc653dba373f2d2ce48f8efbc0b19a424971e (diff)
downloadrockbox-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.c339
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 @@
#include <string.h>
#include "lcd.h"
#include "font.h"
+#include "file.h"
#include "debug.h"
#include "panic.h"
-/* available compiled-in fonts*/
-extern MWCFONT font_X5x8;
-/*extern MWCFONT font_X6x9; */
-/*extern MWCFONT font_courB08; */
-/*extern MWCFONT font_timR08; */
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+/* compiled-in font */
+extern struct font sysfont;
-/* structure filled in by rbf_load_font*/
-static MWCFONT font_UI;
+/* structure filled in by font_load */
+static struct font font_ui;
-/* system font table, in order of FONT_xxx definition*/
-struct corefont sysfonts[MAXFONTS] = {
- { &font_X5x8, NULL }, /* compiled-in FONT_SYSFIXED*/
- { &font_UI, "/system.fnt" }, /* loaded FONT_UI*/
- { NULL, NULL }, /* no FONT_MP3*/
-};
+/* system font table, in order of FONT_xxx definition */
+static struct font* sysfonts[MAXFONTS] = { &sysfont, &font_ui };
-static void rotate_font_bits(PMWCFONT pf);
-static void rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width,
- unsigned int height);
+/* static buffer allocation structures */
+static unsigned char mbuf[MAX_FONT_SIZE];
+static unsigned char *freeptr = mbuf;
+static unsigned char *fileptr;
+static unsigned char *eofptr;
-void
-font_init(void)
+static void rotate_font_bits(struct font* pf);
+static void rotleft(unsigned char *dst,
+ bitmap_t *src,
+ unsigned int width,
+ unsigned int height);
+
+void font_init(void)
{
- struct corefont *cfp;
-
- for (cfp=sysfonts; cfp < &sysfonts[MAXFONTS]; ++cfp) {
- if (cfp->pf && cfp->diskname) {
- cfp->pf = rbf_load_font(cfp->diskname, cfp->pf);
-#if defined(DEBUG) || defined(SIMULATOR)
- if (!cfp->pf)
- DEBUGF("Font load failed: %s\n", cfp->diskname);
-#endif
- }
+ rotate_font_bits(&sysfont);
+ memset(&font_ui, 0, sizeof(struct font));
+}
- /* one-time rotate font bits to rockbox format*/
- if (cfp->pf && cfp->pf->height)
- rotate_font_bits(cfp->pf);
- }
+static int readshort(unsigned short *sp)
+{
+ unsigned short s;
+
+ s = *fileptr++ & 0xff;
+ *sp = (*fileptr++ << 8) | s;
+ return (fileptr <= eofptr);
}
-/*
- * Return a pointer to an incore font structure.
- * If the requested font isn't loaded/compiled-in,
- * decrement the font number and try again.
- */
-PMWCFONT
-getfont(int font)
+static int readlong(unsigned long *lp)
{
- PMWCFONT pf;
+ unsigned long l;
- if (font >= MAXFONTS)
- font = 0;
- while (1) {
- pf = sysfonts[font].pf;
- if (pf && pf->height)
- return pf;
- if (--font < 0)
- panicf("No font!");
- }
+ l = *fileptr++ & 0xff;
+ l |= *fileptr++ << 8;
+ l |= *fileptr++ << 16;
+ *lp = (*fileptr++ << 24) | l;
+ return (fileptr <= eofptr);
}
-/*
- * Return width and height of a given font.
- */
-void lcd_getfontsize(int font, int *width, int *height)
+/* read count bytes*/
+static int readstr(char *buf, int count)
{
- PMWCFONT pf = getfont(font);
+ int n = count;
- *width = pf->maxwidth;
- *height = pf->height;
+ while (--n >= 0)
+ *buf++ = *fileptr++;
+ return (fileptr <= eofptr)? count: 0;
}
-/*
- * Return width and height of a given font.
- */
-//FIXME rename to font_gettextsize, add baseline
-int
-lcd_getstringsize(unsigned char *str, int font, int *w, int *h)
+/* read totlen bytes, return NUL terminated string*/
+/* may write 1 past buf[totlen]; removes blank pad*/
+static int readstrpad(char *buf, int totlen)
{
- PMWCFONT pf = getfont(font);
- int ch;
- int width = 0;
-
- while((ch = *str++)) {
- /* check input range*/
- if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
- ch = pf->defaultchar;
- ch -= pf->firstchar;
-
- /* get proportional width and glyph bits*/
- width += pf->width? pf->width[ch]: pf->maxwidth;
+ char *p = buf;
+ int n = totlen;
+
+ while (--n >= 0)
+ *p++ = *fileptr++;
+ if (fileptr > eofptr)
+ return 0;
+
+ p = &buf[totlen];
+ *p-- = 0;
+ while (*p == ' ' && p >= buf)
+ *p-- = '\0';
+ return totlen;
+}
+
+/* read and load font into incore font structure*/
+struct font* font_load(char *path)
+{
+ int fd, filesize;
+ unsigned short maxwidth, height, ascent, pad;
+ unsigned long firstchar, defaultchar, size;
+ unsigned long i, nbits, noffset, nwidth;
+ char version[4+1];
+ char copyright[256+1];
+ struct font* pf = &font_ui;
+
+ memset(pf, 0, sizeof(struct font));
+
+ /* open and read entire font file*/
+ fd = open(path, O_RDONLY|O_BINARY);
+ if (fd < 0) {
+ DEBUGF("Can't open font: %s\n", path);
+ return NULL;
+ }
+
+ /* currently, font loading replaces earlier font allocation*/
+ freeptr = (unsigned char *)(((int)mbuf + 3) & ~3);
+
+ fileptr = freeptr;
+ filesize = read(fd, fileptr, MAX_FONT_SIZE);
+ eofptr = fileptr + filesize;
+
+ /* no need for multiple font loads currently*/
+ /*freeptr += filesize;*/
+ /*freeptr = (unsigned char *)(freeptr + 3) & ~3;*/ /* pad freeptr*/
+
+ close(fd);
+ if (filesize == MAX_FONT_SIZE) {
+ DEBUGF("Font %s too large: %d\n", path, filesize);
+ return NULL;
}
- *w = width;
- *h = pf->height;
- return width;
+ /* read magic and version #*/
+ memset(version, 0, sizeof(version));
+ if (readstr(version, 4) != 4)
+ return NULL;
+ if (strcmp(version, VERSION) != 0)
+ return NULL;
+
+ /* internal font name*/
+ pf->name = fileptr;
+ if (readstrpad(pf->name, 64) != 64)
+ return NULL;
+
+ /* copyright, not currently stored*/
+ if (readstrpad(copyright, 256) != 256)
+ return NULL;
+
+ /* font info*/
+ if (!readshort(&maxwidth))
+ return NULL;
+ pf->maxwidth = maxwidth;
+ if (!readshort(&height))
+ return NULL;
+ pf->height = height;
+ if (!readshort(&ascent))
+ return NULL;
+ pf->ascent = ascent;
+ if (!readshort(&pad))
+ return NULL;
+ if (!readlong(&firstchar))
+ return NULL;
+ pf->firstchar = firstchar;
+ if (!readlong(&defaultchar))
+ return NULL;
+ pf->defaultchar = defaultchar;
+ if (!readlong(&size))
+ return NULL;
+ pf->size = size;
+
+ /* get variable font data sizes*/
+ /* # words of bitmap_t*/
+ if (!readlong(&nbits))
+ return NULL;
+ pf->bits_size = nbits;
+
+ /* # longs of offset*/
+ if (!readlong(&noffset))
+ return NULL;
+
+ /* # bytes of width*/
+ if (!readlong(&nwidth))
+ return NULL;
+
+ /* variable font data*/
+ pf->bits = (bitmap_t *)fileptr;
+ for (i=0; i<nbits; ++i)
+ if (!readshort(&pf->bits[i]))
+ return NULL;
+ /* pad to longword boundary*/
+ fileptr = (unsigned char *)(((int)fileptr + 3) & ~3);
+
+ if (noffset) {
+ pf->offset = (unsigned long *)fileptr;
+ for (i=0; i<noffset; ++i)
+ if (!readlong(&pf->offset[i]))
+ return NULL;
+ }
+ else
+ pf->offset = NULL;
+
+ if (nwidth) {
+ pf->width = (unsigned char *)fileptr;
+ fileptr += nwidth*sizeof(unsigned char);
+ }
+ else
+ pf->width = NULL;
+
+ if (fileptr > eofptr)
+ return NULL;
+
+ /* one-time rotate font bits to rockbox format*/
+ rotate_font_bits(pf);
+
+ return pf; /* success!*/
}
/*
- * Put a string at specified bit position
+ * Return a pointer to an incore font structure.
+ * If the requested font isn't loaded/compiled-in,
+ * decrement the font number and try again.
*/
-//FIXME rename font_putsxy?
-void
-lcd_putsxy(int x, int y, unsigned char *str, int font)
+struct font* font_get(int font)
{
- int ch;
- PMWCFONT pf = getfont(font);
-
- while (((ch = *str++) != '\0')) {
- MWIMAGEBITS *bits;
- int width;
-
- /* check input range*/
- if (ch < pf->firstchar || ch >= pf->firstchar+pf->size)
- ch = pf->defaultchar;
- ch -= pf->firstchar;
-
- /* get proportional width and glyph bits*/
- width = pf->width? pf->width[ch]: pf->maxwidth;
- if (x + width > LCD_WIDTH)
- break;
-
- /* no partial-height drawing for now...*/
- if (y + pf->height > LCD_HEIGHT)
- break;
- bits = pf->bits + (pf->offset? pf->offset[ch]: (pf->height * ch));
-
- lcd_bitmap((unsigned char *)bits, x, y, width, pf->height, true);
- x += width;
+ struct font* pf;
+
+ if (font >= MAXFONTS)
+ font = 0;
+
+ while (1) {
+ pf = sysfonts[font];
+ if (pf && pf->height)
+ return pf;
+ if (--font < 0)
+ panicf("No font!");
}
}
/* convert font bitmap data inplace to rockbox format*/
-static void
-rotate_font_bits(PMWCFONT pf)
+static void rotate_font_bits(struct font* pf)
{
int i;
- int defaultchar = pf->defaultchar - pf->firstchar;
- int did_defaultchar = 0;
+ unsigned long defaultchar = pf->defaultchar - pf->firstchar;
+ bool did_defaultchar = false;
unsigned char buf[256];
for (i=0; i<pf->size; ++i) {
- MWIMAGEBITS *bits = pf->bits +
- (pf->offset? pf->offset[i]: (pf->height * i));
+ bitmap_t *bits = pf->bits +
+ (pf->offset ? pf->offset[i] : (pf->height * i));
int width = pf->width? pf->width[i]: pf->maxwidth;
- int src_bytes = MWIMAGE_BYTES(width) * pf->height;
+ int src_bytes = BITMAP_BYTES(width) * pf->height;
/*
* Due to the way the offset map works,
* non-mapped characters are mapped to the default
* character, and shouldn't be rotated twice.
*/
- if (i == defaultchar) {
+
+ if (pf->offset && pf->offset[i] == defaultchar) {
if (did_defaultchar)
continue;
- did_defaultchar = 1;
+ did_defaultchar = true;
}
/* rotate left for lcd_bitmap function input*/
@@ -200,16 +292,15 @@ rotate_font_bits(PMWCFONT pf)
}
/*
- * Take an MWIMAGEBITS bitmap and convert to Rockbox format.
+ * Take an bitmap_t bitmap and convert to Rockbox format.
* Used for converting font glyphs for the time being.
* Can use for standard X11 and Win32 images as well.
*
* Doing it this way keeps fonts in standard formats,
* as well as keeping Rockbox hw bitmap format.
*/
-static void
-rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width,
- unsigned int height)
+static void rotleft(unsigned char *dst, bitmap_t *src, unsigned int width,
+ unsigned int height)
{
unsigned int i,j;
unsigned int dst_col = 0; /* destination column*/
@@ -221,17 +312,17 @@ rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width,
dst_linelen = (height-1)/8+1;
/* calc words of input image*/
- src_words = MWIMAGE_WORDS(width) * height;
+ src_words = BITMAP_WORDS(width) * height;
/* clear background*/
memset(dst, 0, dst_linelen*width);
for (i=0; i < src_words; i++) {
- MWIMAGEBITS srcmap; /* current src input bit*/
- MWIMAGEBITS dstmap; /* current dst output bit*/
+ bitmap_t srcmap; /* current src input bit*/
+ bitmap_t dstmap; /* current dst output bit*/
/* calc src input bit*/
- srcmap = 1 << (sizeof(MWIMAGEBITS)*8-1);
+ srcmap = 1 << (sizeof(bitmap_t)*8-1);
/* calc dst output bit*/
if (i>0 && (i%8==0)) {
@@ -244,9 +335,9 @@ rotleft(unsigned char *dst, MWIMAGEBITS *src, unsigned int width,
for(j=0; j < width; j++) {
/* calc input bitmask*/
- MWIMAGEBITS bit = srcmap >> j;
+ bitmap_t bit = srcmap >> j;
if (bit==0) {
- srcmap = 1 << (sizeof(MWIMAGEBITS)*8-1);
+ srcmap = 1 << (sizeof(bitmap_t)*8-1);
bit = srcmap >> (j % 16);
}