forked from len0rd/rockbox
Revamp of the bitmap allocation for the fonts. Implements the idea from FS#9907 (reallocate when maxwidth grows), but does it correctly. Also gets rid of the warning "DWIDTH spec > ..." which is irritating since the bounding box header of the font is not required to specify the MAX width.
Also replaced TABs with spaces. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@20219 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
c8a60784d0
commit
cbcef6700c
1 changed files with 132 additions and 128 deletions
|
@ -22,16 +22,20 @@
|
||||||
#define VERSION "RB11"
|
#define VERSION "RB11"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* bitmap_t helper macros*/
|
/*
|
||||||
#define BITMAP_WORDS(x) (((x)+15)/16) /* image size in words*/
|
* bitmap_t helper macros
|
||||||
#define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t))
|
*/
|
||||||
|
typedef unsigned short bitmap_t; /* bitmap image unit size*/
|
||||||
|
|
||||||
|
/* Number of words to hold a pixel line of width x pixels */
|
||||||
#define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8)
|
#define BITMAP_BITSPERIMAGE (sizeof(bitmap_t) * 8)
|
||||||
|
#define BITMAP_WORDS(x) (((x)+BITMAP_BITSPERIMAGE-1)/BITMAP_BITSPERIMAGE)
|
||||||
|
#define BITMAP_BYTES(x) (BITMAP_WORDS(x)*sizeof(bitmap_t))
|
||||||
#define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n)))
|
#define BITMAP_BITVALUE(n) ((bitmap_t) (((bitmap_t) 1) << (n)))
|
||||||
#define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1))
|
#define BITMAP_FIRSTBIT (BITMAP_BITVALUE(BITMAP_BITSPERIMAGE - 1))
|
||||||
#define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT)
|
#define BITMAP_TESTBIT(m) ((m) & BITMAP_FIRSTBIT)
|
||||||
#define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1))
|
#define BITMAP_SHIFTBIT(m) ((bitmap_t) ((m) << 1))
|
||||||
|
|
||||||
typedef unsigned short bitmap_t; /* bitmap image unit size*/
|
|
||||||
|
|
||||||
/* builtin C-based proportional/fixed font structure */
|
/* builtin C-based proportional/fixed font structure */
|
||||||
/* based on The Microwindows Project http://microwindows.org */
|
/* based on The Microwindows Project http://microwindows.org */
|
||||||
|
@ -42,7 +46,7 @@ struct font {
|
||||||
int firstchar; /* first character in bitmap */
|
int firstchar; /* first character in bitmap */
|
||||||
int size; /* font size in glyphs ('holes' included) */
|
int size; /* font size in glyphs ('holes' included) */
|
||||||
bitmap_t* bits; /* 16-bit right-padded bitmap data */
|
bitmap_t* bits; /* 16-bit right-padded bitmap data */
|
||||||
unsigned int* offset; /* offsets into bitmap data*/
|
int* offset; /* offsets into bitmap data */
|
||||||
unsigned char* width; /* character widths or NULL if fixed */
|
unsigned char* width; /* character widths or NULL if fixed */
|
||||||
int defaultchar; /* default char (not glyph index) */
|
int defaultchar; /* default char (not glyph index) */
|
||||||
int bits_size; /* # words of bitmap_t bits */
|
int bits_size; /* # words of bitmap_t bits */
|
||||||
|
@ -71,8 +75,6 @@ struct font {
|
||||||
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
#define MAX(a,b) ((a) > (b) ? (a) : (b))
|
||||||
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
#define MIN(a,b) ((a) < (b) ? (a) : (b))
|
||||||
|
|
||||||
#define EXTRA 300 /* # bytes extra allocation for buggy .bdf files*/
|
|
||||||
|
|
||||||
int gen_c = 0;
|
int gen_c = 0;
|
||||||
int gen_h = 0;
|
int gen_h = 0;
|
||||||
int gen_fnt = 0;
|
int gen_fnt = 0;
|
||||||
|
@ -92,6 +94,7 @@ int bdf_read_header(FILE *fp, struct font* pf);
|
||||||
int bdf_read_bitmaps(FILE *fp, struct font* pf);
|
int bdf_read_bitmaps(FILE *fp, struct font* pf);
|
||||||
char * bdf_getline(FILE *fp, char *buf, int len);
|
char * bdf_getline(FILE *fp, char *buf, int len);
|
||||||
bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2);
|
bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2);
|
||||||
|
void bitmap_buf_alloc(struct font* pf);
|
||||||
|
|
||||||
int gen_c_source(struct font* pf, char *path);
|
int gen_c_source(struct font* pf, char *path);
|
||||||
int gen_h_header(struct font* pf, char *path);
|
int gen_h_header(struct font* pf, char *path);
|
||||||
|
@ -312,6 +315,7 @@ struct font* bdf_read_font(char *path)
|
||||||
pf = (struct font*)calloc(1, sizeof(struct font));
|
pf = (struct font*)calloc(1, sizeof(struct font));
|
||||||
if (!pf)
|
if (!pf)
|
||||||
goto errout;
|
goto errout;
|
||||||
|
memset(pf, 0, sizeof(struct font));
|
||||||
|
|
||||||
pf->name = strdup(basename(path));
|
pf->name = strdup(basename(path));
|
||||||
|
|
||||||
|
@ -350,7 +354,6 @@ struct font* bdf_read_font(char *path)
|
||||||
int bdf_read_header(FILE *fp, struct font* pf)
|
int bdf_read_header(FILE *fp, struct font* pf)
|
||||||
{
|
{
|
||||||
int encoding;
|
int encoding;
|
||||||
int maxwidth;
|
|
||||||
int firstchar = 65535;
|
int firstchar = 65535;
|
||||||
int lastchar = -1;
|
int lastchar = -1;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
@ -461,17 +464,17 @@ int bdf_read_header(FILE *fp, struct font* pf)
|
||||||
/* calc font size (offset/width entries) */
|
/* calc font size (offset/width entries) */
|
||||||
pf->firstchar = firstchar;
|
pf->firstchar = firstchar;
|
||||||
pf->size = lastchar - firstchar + 1;
|
pf->size = lastchar - firstchar + 1;
|
||||||
|
if (pf->size < pf->nchars) {
|
||||||
|
fprintf(stderr, "Error: NCHARS and max code mismatch\n");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
/* use the font boundingbox to get initial maxwidth */
|
/* use the font boundingbox to get initial maxwidth */
|
||||||
/*maxwidth = pf->fbbw - pf->fbbx;*/
|
/*maxwidth = pf->fbbw - pf->fbbx;*/
|
||||||
maxwidth = pf->fbbw;
|
pf->maxwidth = pf->fbbw;
|
||||||
|
bitmap_buf_alloc(pf); /* Allocate bitmaps */
|
||||||
|
|
||||||
/* initially use font maxwidth * height for bits allocation*/
|
pf->offset = (int *)malloc(pf->size * sizeof(int));
|
||||||
pf->bits_size = pf->nchars * BITMAP_WORDS(maxwidth) * pf->height;
|
|
||||||
|
|
||||||
/* allocate bits, offset, and width arrays*/
|
|
||||||
pf->bits = (bitmap_t *)malloc(pf->bits_size * sizeof(bitmap_t) + EXTRA);
|
|
||||||
pf->offset = (unsigned int *)malloc(pf->size * sizeof(unsigned int));
|
|
||||||
pf->offrot = (unsigned int *)malloc(pf->size * sizeof(unsigned int));
|
pf->offrot = (unsigned int *)malloc(pf->size * sizeof(unsigned int));
|
||||||
pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char));
|
pf->width = (unsigned char *)malloc(pf->size * sizeof(unsigned char));
|
||||||
|
|
||||||
|
@ -488,13 +491,14 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf)
|
||||||
{
|
{
|
||||||
int ofs = 0;
|
int ofs = 0;
|
||||||
int ofr = 0;
|
int ofr = 0;
|
||||||
int maxwidth = 0;
|
|
||||||
int i, k, encoding, width;
|
int i, k, encoding, width;
|
||||||
int bbw, bbh, bbx, bby;
|
int bbw, bbh, bbx, bby;
|
||||||
int proportional = 0;
|
int proportional = 0;
|
||||||
int encodetable = 0;
|
int encodetable = 0;
|
||||||
int l;
|
int l;
|
||||||
char buf[256];
|
char buf[256];
|
||||||
|
bitmap_t *ch_bitmap;
|
||||||
|
int ch_words;
|
||||||
|
|
||||||
/* reset file pointer */
|
/* reset file pointer */
|
||||||
fseek(fp, 0L, SEEK_SET);
|
fseek(fp, 0L, SEEK_SET);
|
||||||
|
@ -543,8 +547,6 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (strequal(buf, "BITMAP") || strequal(buf, "BITMAP ")) {
|
if (strequal(buf, "BITMAP") || strequal(buf, "BITMAP ")) {
|
||||||
bitmap_t *ch_bitmap = pf->bits + ofs;
|
|
||||||
int ch_words;
|
|
||||||
int overflow_asc, overflow_desc;
|
int overflow_asc, overflow_desc;
|
||||||
int bbh_orig, bby_orig, y;
|
int bbh_orig, bby_orig, y;
|
||||||
|
|
||||||
|
@ -552,7 +554,7 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
/* set bits offset in encode map*/
|
/* set bits offset in encode map*/
|
||||||
if (pf->offset[encoding-pf->firstchar] != (unsigned int)-1) {
|
if (pf->offset[encoding-pf->firstchar] != -1) {
|
||||||
fprintf(stderr, "Error: duplicate encoding for character %d (0x%02x), ignoring duplicate\n",
|
fprintf(stderr, "Error: duplicate encoding for character %d (0x%02x), ignoring duplicate\n",
|
||||||
encoding, encoding);
|
encoding, encoding);
|
||||||
continue;
|
continue;
|
||||||
|
@ -562,19 +564,20 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf)
|
||||||
|
|
||||||
/* calc char width */
|
/* calc char width */
|
||||||
if (bbx < 0) {
|
if (bbx < 0) {
|
||||||
|
/* Rockbox can't render overlapping glyphs */
|
||||||
width -= bbx;
|
width -= bbx;
|
||||||
/*if (width > maxwidth)
|
|
||||||
width = maxwidth;*/
|
|
||||||
bbx = 0;
|
bbx = 0;
|
||||||
}
|
}
|
||||||
if (width > maxwidth)
|
if (width > pf->maxwidth) {
|
||||||
maxwidth = width;
|
pf->maxwidth = width;
|
||||||
|
bitmap_buf_alloc(pf); /* Re-allocate bitmaps since the maxwidth has grown */
|
||||||
|
}
|
||||||
pf->width[encoding-pf->firstchar] = width;
|
pf->width[encoding-pf->firstchar] = width;
|
||||||
|
|
||||||
/* clear bitmap*/
|
ch_bitmap = pf->bits + ofs;
|
||||||
memset(ch_bitmap, 0, BITMAP_BYTES(width) * pf->height);
|
|
||||||
|
|
||||||
ch_words = BITMAP_WORDS(width);
|
ch_words = BITMAP_WORDS(width);
|
||||||
|
memset(ch_bitmap, 0, BITMAP_BYTES(width) * pf->height); /* clear bitmap */
|
||||||
|
|
||||||
#define BM(row,col) (*(ch_bitmap + ((row)*ch_words) + (col)))
|
#define BM(row,col) (*(ch_bitmap + ((row)*ch_words) + (col)))
|
||||||
#define BITMAP_NIBBLES (BITMAP_BITSPERIMAGE/4)
|
#define BITMAP_NIBBLES (BITMAP_BITSPERIMAGE/4)
|
||||||
|
|
||||||
|
@ -615,7 +618,8 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf)
|
||||||
int hexnibbles;
|
int hexnibbles;
|
||||||
|
|
||||||
if (!bdf_getline(fp, buf, sizeof(buf))) {
|
if (!bdf_getline(fp, buf, sizeof(buf))) {
|
||||||
fprintf(stderr, "Error: EOF reading BITMAP data\n");
|
fprintf(stderr, "Error: EOF reading BITMAP data for character %d\n",
|
||||||
|
encoding);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (isprefix(buf, "ENDCHAR"))
|
if (isprefix(buf, "ENDCHAR"))
|
||||||
|
@ -662,14 +666,11 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* set max width*/
|
|
||||||
pf->maxwidth = maxwidth;
|
|
||||||
|
|
||||||
/* change unused width values to default char values */
|
/* change unused width values to default char values */
|
||||||
for (i=0; i<pf->size; ++i) {
|
for (i=0; i<pf->size; ++i) {
|
||||||
int defchar = pf->defaultchar - pf->firstchar;
|
int defchar = pf->defaultchar - pf->firstchar;
|
||||||
|
|
||||||
if (pf->offset[i] == (unsigned int)-1)
|
if (pf->offset[i] == -1)
|
||||||
pf->width[i] = pf->width[defchar];
|
pf->width[i] = pf->width[defchar];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -700,7 +701,7 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf)
|
||||||
|
|
||||||
/* determine whether font is fixed-width */
|
/* determine whether font is fixed-width */
|
||||||
for (i=0; i<pf->size; ++i) {
|
for (i=0; i<pf->size; ++i) {
|
||||||
if (pf->width[i] != maxwidth) {
|
if (pf->width[i] != pf->maxwidth) {
|
||||||
proportional = 1;
|
proportional = 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -715,16 +716,6 @@ int bdf_read_bitmaps(FILE *fp, struct font* pf)
|
||||||
pf->bits = realloc(pf->bits, ofs * sizeof(bitmap_t));
|
pf->bits = realloc(pf->bits, ofs * sizeof(bitmap_t));
|
||||||
pf->bits_size = ofs;
|
pf->bits_size = ofs;
|
||||||
}
|
}
|
||||||
else {
|
|
||||||
if (ofs > pf->bits_size) {
|
|
||||||
fprintf(stderr, "Warning: DWIDTH spec > max FONTBOUNDINGBOX\n");
|
|
||||||
if (ofs > pf->bits_size+EXTRA) {
|
|
||||||
fprintf(stderr, "Error: Not enough bits initially allocated\n");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
pf->bits_size = ofs;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef ROTATE
|
#ifdef ROTATE
|
||||||
pf->bits_size = ofr; /* always update, rotated is smaller */
|
pf->bits_size = ofr; /* always update, rotated is smaller */
|
||||||
|
@ -759,6 +750,19 @@ char *bdf_getline(FILE *fp, char *buf, int len)
|
||||||
return buf;
|
return buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Calculates the necessary size of the bit buffer to hold all the
|
||||||
|
bitmaps for the glyphs in the font. Shoud be called every time
|
||||||
|
the max width of the font grows. Font height, the max width and
|
||||||
|
the number of chars in the font must have been already set.
|
||||||
|
*/
|
||||||
|
void bitmap_buf_alloc(struct font* pf)
|
||||||
|
{
|
||||||
|
pf->bits_size = pf->size * BITMAP_WORDS(pf->maxwidth) * pf->height;
|
||||||
|
pf->bits = (bitmap_t *)realloc(pf->bits, pf->bits_size * sizeof(bitmap_t));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* return hex value of portion of buffer*/
|
/* return hex value of portion of buffer*/
|
||||||
bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2)
|
bitmap_t bdf_hexval(unsigned char *buf, int ndx1, int ndx2)
|
||||||
{
|
{
|
||||||
|
@ -913,7 +917,7 @@ int gen_c_source(struct font* pf, char *path)
|
||||||
bitmap_t bitvalue=0;
|
bitmap_t bitvalue=0;
|
||||||
|
|
||||||
/* Skip missing glyphs */
|
/* Skip missing glyphs */
|
||||||
if (pf->offset && (pf->offset[i] == (unsigned int)-1))
|
if (pf->offset && (pf->offset[i] == -1))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bits = pf->bits + (pf->offset? (int)pf->offset[i]: (pf->height * i));
|
bits = pf->bits + (pf->offset? (int)pf->offset[i]: (pf->height * i));
|
||||||
|
@ -994,7 +998,7 @@ int gen_c_source(struct font* pf, char *path)
|
||||||
"static const unsigned short _sysfont_offset[] = {\n");
|
"static const unsigned short _sysfont_offset[] = {\n");
|
||||||
|
|
||||||
for (i=0; i<pf->size; ++i) {
|
for (i=0; i<pf->size; ++i) {
|
||||||
if (pf->offset[i] == (unsigned int)-1) {
|
if (pf->offset[i] == -1) {
|
||||||
pf->offset[i] = pf->offset[pf->defaultchar - pf->firstchar];
|
pf->offset[i] = pf->offset[pf->defaultchar - pf->firstchar];
|
||||||
pf->offrot[i] = pf->offrot[pf->defaultchar - pf->firstchar];
|
pf->offrot[i] = pf->offrot[pf->defaultchar - pf->firstchar];
|
||||||
}
|
}
|
||||||
|
@ -1201,7 +1205,7 @@ int gen_fnt_file(struct font* pf, char *path)
|
||||||
unsigned char bytemap[512];
|
unsigned char bytemap[512];
|
||||||
|
|
||||||
/* Skip missing glyphs */
|
/* Skip missing glyphs */
|
||||||
if (pf->offset && (pf->offset[i] == (unsigned int)-1))
|
if (pf->offset && (pf->offset[i] == -1))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bits = pf->bits + (pf->offset? (int)pf->offset[i]: (pf->height * i));
|
bits = pf->bits + (pf->offset? (int)pf->offset[i]: (pf->height * i));
|
||||||
|
@ -1231,7 +1235,7 @@ int gen_fnt_file(struct font* pf, char *path)
|
||||||
{
|
{
|
||||||
for (i=0; i<pf->size; ++i)
|
for (i=0; i<pf->size; ++i)
|
||||||
{
|
{
|
||||||
if (pf->offset[i] == (unsigned int)-1) {
|
if (pf->offset[i] == -1) {
|
||||||
pf->offrot[i] = pf->offrot[pf->defaultchar - pf->firstchar];
|
pf->offrot[i] = pf->offrot[pf->defaultchar - pf->firstchar];
|
||||||
}
|
}
|
||||||
if ( pf->bits_size < 0xFFDB )
|
if ( pf->bits_size < 0xFFDB )
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue