blob: e78f208b13dbc5823614c33435669b5dad7b830a [file] [log] [blame]
/***************************************************************************
* __________ __ ___.
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
* $Id$
*
* Copyright (c) 2002 by Greg Haerr <greg@censoft.com>
*
* All files in this archive are subject to the GNU General Public License.
* See the file COPYING in the source tree root for full license agreement.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
****************************************************************************/
/*
* Load an rbf font, store in incore format.
*/
#include "config.h"
#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
#include <stdio.h>
#include <string.h>
#include "font.h"
#include "file.h"
#ifndef DEBUGF
#include "debug.h"
#endif
#ifndef O_BINARY
#define O_BINARY 0
#endif
/* static buffer allocation structures*/
static unsigned char mbuf[MAX_FONT_SIZE];
static unsigned char *freeptr = mbuf;
static unsigned char *fileptr;
static unsigned char *eofptr;
static int
READSHORT(unsigned short *sp)
{
unsigned short s;
s = *fileptr++ & 0xff;
*sp = (*fileptr++ << 8) | s;
return (fileptr <= eofptr);
}
static int
READLONG(unsigned long *lp)
{
unsigned long l;
l = *fileptr++ & 0xff;
l |= *fileptr++ << 8;
l |= *fileptr++ << 16;
*lp = (*fileptr++ << 24) | l;
return (fileptr <= eofptr);
}
/* read count bytes*/
static int
READSTR(char *buf, int count)
{
int n = count;
while (--n >= 0)
*buf++ = *fileptr++;
return (fileptr <= eofptr)? count: 0;
}
/* read totlen bytes, return NUL terminated string*/
/* may write 1 past buf[totlen]; removes blank pad*/
static int
READSTRPAD(char *buf, int totlen)
{
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*/
PMWCFONT
rbf_load_font(char *path, PMWCFONT pf)
{
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];
memset(pf, 0, sizeof(MWCFONT));
/* 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;
}
freeptr = (unsigned char *)(((int)mbuf + 3) & ~3);
fileptr = freeptr;
filesize = read(fd, fileptr, MAX_FONT_SIZE);
eofptr = fileptr + filesize;
//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;
}
/* 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 MWIMAGEBITS*/
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 = (MWIMAGEBITS *)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;
return pf; /* success!*/
}
#endif /* HAVE_LCD_BITMAP */
/* -----------------------------------------------------------------
* local variables:
* eval: (load-file "rockbox-mode.el")
* vim: et sw=4 ts=8 sts=4 tw=78
* end:
*/