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
This commit is contained in:
Björn Stenberg 2002-09-20 08:07:51 +00:00
parent eb5cc653db
commit bed3d3f7e0
21 changed files with 3427 additions and 5857 deletions

View file

@ -19,6 +19,7 @@ SYSTEM_FONT = fonts/alt6x10.bdf
# store output files in this directory:
OBJDIR = .
TOOLSDIR = ../tools
CFLAGS = -W -Wall -O -m1 -nostdlib -ffreestanding -Wstrict-prototypes $(INCLUDES) $(TARGET) $(EXTRA_DEFINES)
@ -38,9 +39,8 @@ DIRS = $(subst $(DEPS),".",$(DEPDIRS))
OUTPUT = $(OBJDIR)/librockbox.a
ifeq (LOADABLE_FONTS,$(findstring LOADABLE_FONTS, $(CFLAGS)))
EXTRA_TARGETS = $(OBJDIR)/system.ajf
ifeq (RECORDER,$(findstring RECORDER, $(CFLAGS)))
OBJS += $(OBJDIR)/sysfont.o
endif
all: $(OUTPUT) $(EXTRA_TARGETS)
@ -70,6 +70,10 @@ clean:
$(OBJDIR)/thread.o: thread.c thread.h
$(CC) -c -O -fomit-frame-pointer $(CFLAGS) $< -o $@
$(OBJDIR)/sysfont.o: fonts/clR6x8.bdf
$(TOOLSDIR)/convbdf -c -o $(OBJDIR)/sysfont.c $<
$(CC) $(CFLAGS) -c $(OBJDIR)/sysfont.c -o $@
$(OBJDIR)/$(DEPS)/%.d: %.c
@$(SHELL) -c 'for d in $(DEPDIRS); do { if [ ! -d $(OBJDIR)/$$d ]; then mkdir $(OBJDIR)/$$d; fi; }; done'
@echo "Updating dependencies for $<"

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -547,7 +547,6 @@ void lcd_set_contrast(int val)
*/
unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8];
static int font=0;
static int xmargin=0;
static int ymargin=0;
@ -661,11 +660,6 @@ void lcd_clear_display (void)
#endif
}
void lcd_setfont(int newfont)
{
font = newfont;
}
void lcd_setmargins(int x, int y)
{
xmargin = x;
@ -682,10 +676,11 @@ int lcd_getymargin(void)
return ymargin;
}
static int curfont = FONT_SYSFIXED;
/*
* Put a string at specified character position
*/
//FIXME require font parameter
void lcd_puts(int x, int y, unsigned char *str)
{
int xpos,ypos,w,h;
@ -707,10 +702,10 @@ void lcd_puts(int x, int y, unsigned char *str)
if(!str || !str[0])
return;
lcd_getstringsize(str, font, &w, &h);
xpos = xmargin + x*w / strlen(str); //FIXME why strlen?
lcd_getstringsize(str, curfont, &w, &h);
xpos = xmargin + x*w / strlen(str);
ypos = ymargin + y*h;
lcd_putsxy( xpos, ypos, str, font);
lcd_putsxy( xpos, ypos, str, curfont);
lcd_clearrect(xpos + w, ypos, LCD_WIDTH - (xpos + w), h);
#if defined(SIMULATOR) && defined(HAVE_LCD_CHARCELLS)
/* this function is being used when simulating a charcell LCD and
@ -719,6 +714,80 @@ void lcd_puts(int x, int y, unsigned char *str)
#endif
}
/* set current font*/
void lcd_setfont(int newfont)
{
curfont = newfont;
}
/*
* Return width and height of a given font.
*/
void lcd_getfontsize(int font, int *width, int *height)
{
struct font* pf = font_get(font);
*width = pf->maxwidth;
*height = pf->height;
}
/*
* Return width and height of a given font.
*/
int lcd_getstringsize(unsigned char *str, int font, int *w, int *h)
{
struct font* pf = font_get(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;
}
*w = width;
*h = pf->height;
return width;
}
/*
* Put a string at specified bit position
*/
void lcd_putsxy(int x, int y, unsigned char *str, int font)
{
int ch;
struct font* pf = font_get(font);
while (((ch = *str++) != '\0')) {
bitmap_t *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;
}
}
/*
* Display a bitmap at (x, y), size (nx, ny)
* clear is true to clear destination area first
@ -1038,14 +1107,14 @@ void lcd_puts_scroll(int x, int y, unsigned char* string )
unsigned char ch[2];
int w, h;
int width, height;
lcd_getfontsize(font, &width, &height);
lcd_getfontsize(curfont, &width, &height);
ch[1] = 0; /* zero terminate */
ch[0] = string[0];
width = 0;
s->space = 0;
while ( ch[0] &&
(width + lcd_getstringsize(ch, 0, &w, &h) <
(width + lcd_getstringsize(ch, curfont, &w, &h) <
(LCD_WIDTH - x*8))) {
width += w;
s->space++;
@ -1058,7 +1127,7 @@ void lcd_puts_scroll(int x, int y, unsigned char* string )
#ifdef HAVE_LCD_BITMAP
s->space += 2;
lcd_getstringsize(string,0,&w,&h);
lcd_getstringsize(string,curfont,&w,&h);
if ( w > LCD_WIDTH - xmargin ) {
#else
if ( s->textlen > s->space ) {

View file

@ -99,9 +99,6 @@ extern void lcd_double_height (bool on);
*/
extern unsigned char lcd_framebuffer[LCD_WIDTH][LCD_HEIGHT/8];
extern void lcd_putsxy(int x, int y, unsigned char *string, int font);
extern void lcd_setfont(int font);
extern void lcd_getfontsize(int font, int *width, int *height);
extern void lcd_setmargins(int xmargin, int ymargin);
extern int lcd_getxmargin(void);
extern int lcd_getymargin(void);
@ -118,6 +115,10 @@ extern void lcd_clearpixel(int x, int y);
extern void lcd_invertpixel(int x, int y);
extern void lcd_roll(int pixels);
extern void lcd_setfont(int font);
extern void lcd_getfontsize(int font, int *width, int *height);
extern void lcd_putsxy(int x, int y, unsigned char *string, int font);
#endif /* CHARCELLS / BITMAP */
extern int lcd_getstringsize(unsigned char *str, int font, int *w, int *h);

View file

@ -30,47 +30,210 @@
#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; */
/* structure filled in by rbf_load_font*/
static MWCFONT 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*/
};
static void rotate_font_bits(PMWCFONT pf);
static void rotleft(unsigned char *dst, MWIMAGEBITS *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);
#ifndef O_BINARY
#define O_BINARY 0
#endif
}
/* one-time rotate font bits to rockbox format*/
if (cfp->pf && cfp->pf->height)
rotate_font_bits(cfp->pf);
/* compiled-in font */
extern struct font sysfont;
/* structure filled in by font_load */
static struct font font_ui;
/* system font table, in order of FONT_xxx definition */
static struct font* sysfonts[MAXFONTS] = { &sysfont, &font_ui };
/* 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 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)
{
rotate_font_bits(&sysfont);
memset(&font_ui, 0, sizeof(struct font));
}
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*/
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;
}
/* 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!*/
}
/*
@ -78,15 +241,15 @@ font_init(void)
* If the requested font isn't loaded/compiled-in,
* decrement the font number and try again.
*/
PMWCFONT
getfont(int font)
struct font* font_get(int font)
{
PMWCFONT pf;
struct font* pf;
if (font >= MAXFONTS)
font = 0;
while (1) {
pf = sysfonts[font].pf;
pf = sysfonts[font];
if (pf && pf->height)
return pf;
if (--font < 0)
@ -94,101 +257,30 @@ getfont(int font)
}
}
/*
* Return width and height of a given font.
*/
void lcd_getfontsize(int font, int *width, int *height)
{
PMWCFONT pf = getfont(font);
*width = pf->maxwidth;
*height = pf->height;
}
/*
* 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)
{
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;
}
*w = width;
*h = pf->height;
return width;
}
/*
* Put a string at specified bit position
*/
//FIXME rename font_putsxy?
void
lcd_putsxy(int x, int y, unsigned char *str, 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;
}
}
/* 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);
}

View file

@ -38,13 +38,14 @@
* must be available at system startup.
* Fonts are specified in firmware/font.c.
*/
#define FONT_SYSFIXED 0 /* system fixed pitch font*/
#define FONT_UI 1 /* system porportional font*/
#define FONT_MP3 2 /* font used for mp3 info*/
#define MAXFONTS 3 /* max # fonts*/
enum {
FONT_SYSFIXED, /* system fixed pitch font*/
FONT_UI, /* system porportional font*/
MAXFONTS
};
/*
* .fnt (.rbf) loadable font file format definition
* .fnt loadable font file format definition
*
* format len description
* ------------------------- ---- ------------------------------
@ -70,54 +71,42 @@
/* loadable font magic and version #*/
#define VERSION "RB11"
/* MWIMAGEBITS helper macros*/
#define MWIMAGE_WORDS(x) (((x)+15)/16) /* image size in words*/
#define MWIMAGE_BYTES(x) (MWIMAGE_WORDS(x)*sizeof(MWIMAGEBITS))
#define MWIMAGE_BITSPERIMAGE (sizeof(MWIMAGEBITS) * 8)
#define MWIMAGE_BITVALUE(n) ((MWIMAGEBITS) (((MWIMAGEBITS) 1) << (n)))
#define MWIMAGE_FIRSTBIT (MWIMAGE_BITVALUE(MWIMAGE_BITSPERIMAGE - 1))
#define MWIMAGE_TESTBIT(m) ((m) & MWIMAGE_FIRSTBIT)
#define MWIMAGE_SHIFTBIT(m) ((MWIMAGEBITS) ((m) << 1))
typedef unsigned short bitmap_t; /* bitmap image unit size*/
typedef unsigned short MWIMAGEBITS; /* bitmap image unit size*/
/* bitmap_t helper macros*/
#define BITMAP_WORDS(x) (((x)+15)/16) /* image size in words*/
#define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t))
#define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8)
#define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n)))
#define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1))
#define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT)
#define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1))
/* builtin C-based proportional/fixed font structure */
/* based on The Microwindows Project http://microwindows.org */
typedef struct {
struct font {
char * name; /* font name*/
int maxwidth; /* max width in pixels*/
unsigned int height; /* height in pixels*/
int ascent; /* ascent (baseline) height*/
int firstchar; /* first character in bitmap*/
int size; /* font size in glyphs*/
MWIMAGEBITS *bits; /* 16-bit right-padded bitmap data*/
bitmap_t *bits; /* 16-bit right-padded bitmap data*/
unsigned long *offset; /* offsets into bitmap data*/
unsigned char *width; /* character widths or NULL if fixed*/
int defaultchar; /* default char (not glyph index)*/
long bits_size; /* # words of MWIMAGEBITS bits*/
#if 0
char * facename; /* facename of font*/
char * copyright; /* copyright info for loadable fonts*/
#endif
} MWCFONT, *PMWCFONT;
/* structure for rockbox startup font selection*/
struct corefont {
PMWCFONT pf; /* compiled-in or loaded font*/
char *diskname; /* diskname if not compiled-in*/
long bits_size; /* # words of bitmap_t bits*/
};
extern struct corefont sysfonts[MAXFONTS];
/* font routines*/
PMWCFONT getfont(int font);
PMWCFONT rbf_load_font(char *path, PMWCFONT pf);
void font_init(void);
struct font* font_load(char *path);
struct font* font_get(int font);
#else /* HAVE_LCD_BITMAP */
#define font_init()
#define font_load(x)
#endif

2895
firmware/fonts/clR6x8.bdf Normal file

File diff suppressed because it is too large Load diff

View file

@ -1,212 +0,0 @@
/***************************************************************************
* __________ __ ___.
* 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:
*/