summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNils Wallménius <nils@rockbox.org>2009-12-13 11:07:40 +0000
committerNils Wallménius <nils@rockbox.org>2009-12-13 11:07:40 +0000
commit559c56905e1208264e87ff3bbc2049eb054f95c8 (patch)
tree9085ed0f8193d5fd514b6c46d7834341cba37cbf
parent5783bef32c792e192ddf0c160cd793971612d0cc (diff)
downloadrockbox-559c56905e1208264e87ff3bbc2049eb054f95c8.zip
rockbox-559c56905e1208264e87ff3bbc2049eb054f95c8.tar.gz
rockbox-559c56905e1208264e87ff3bbc2049eb054f95c8.tar.bz2
rockbox-559c56905e1208264e87ff3bbc2049eb054f95c8.tar.xz
Font improvements: Fix bug that caused some fonts to be rendered garbled on custom builds with MAX_FONT_SIZE > 64k (closes FS#10844). Simplify version check. Use void pointer and explicit casting for the offsets to make it clearer that they may be of different sizes, add a comment too. Use uint16_t in stead of short in some places for consistency. Replace magic number with meaningful define.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@23969 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--firmware/export/font.h21
-rw-r--r--firmware/font.c77
2 files changed, 50 insertions, 48 deletions
diff --git a/firmware/export/font.h b/firmware/export/font.h
index 75b012d..0fe6c30 100644
--- a/firmware/export/font.h
+++ b/firmware/export/font.h
@@ -33,24 +33,6 @@
#include "sysfont.h"
#endif
-/* max static loadable font buffer size */
-#ifndef MAX_FONT_SIZE
-#if LCD_HEIGHT > 64
-#if MEM > 2
-#define MAX_FONT_SIZE 60000
-#else
-#define MAX_FONT_SIZE 10000
-#endif
-#else
-#define MAX_FONT_SIZE 4000
-#endif
-#endif
-
-#ifndef FONT_HEADER_SIZE
-#define FONT_HEADER_SIZE 36
-#endif
-
-#define GLYPH_CACHE_FILE ROCKBOX_DIR"/.glyphcache"
/*
* Fonts are specified by number, and used for display
@@ -102,7 +84,8 @@ struct font {
int firstchar; /* first character in bitmap*/
int size; /* font size in glyphs*/
const unsigned char *bits; /* 8-bit column bitmap data*/
- const unsigned short *offset; /* offsets into bitmap data*/
+ const void *offset; /* offsets into bitmap data,
+ uint16_t if bits_size < 0xFFDB else uint32_t*/
const unsigned char *width; /* character widths or NULL if fixed*/
int defaultchar; /* default char (not glyph index)*/
int32_t bits_size; /* # bytes of glyph bits*/
diff --git a/firmware/font.c b/firmware/font.c
index 624e0de..8e89e69 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -37,6 +37,27 @@
#include "rbunicode.h"
#include "diacritic.h"
+#define MAX_FONTSIZE_FOR_16_BIT_OFFSETS 0xFFDB
+
+/* max static loadable font buffer size */
+#ifndef MAX_FONT_SIZE
+#if LCD_HEIGHT > 64
+#if MEM > 2
+#define MAX_FONT_SIZE 60000
+#else
+#define MAX_FONT_SIZE 10000
+#endif
+#else
+#define MAX_FONT_SIZE 4000
+#endif
+#endif
+
+#ifndef FONT_HEADER_SIZE
+#define FONT_HEADER_SIZE 36
+#endif
+
+#define GLYPH_CACHE_FILE ROCKBOX_DIR"/.glyphcache"
+
#ifndef BOOTLOADER
/* Font cache includes */
#include "font_cache.h"
@@ -109,33 +130,23 @@ static int32_t readlong(void)
return l;
}
-/* read count bytes*/
-static void readstr(char *buf, int count)
-{
- while (count--)
- *buf++ = *fileptr++;
-}
-
void font_reset(void)
{
memset(&font_ui, 0, sizeof(struct font));
}
-static struct font* font_load_header(struct font *pf)
+static struct font* font_load_header(struct font *pf)
{
- char version[4+1];
-
/* Check we have enough data */
if (!HAVEBYTES(28))
return NULL;
/* read magic and version #*/
- memset(version, 0, sizeof(version));
- readstr(version, 4);
-
- if (strcmp(version, VERSION) != 0)
+ if (memcmp(fileptr, VERSION, 4) != 0)
return NULL;
+ fileptr += 4;
+
/* font info*/
pf->maxwidth = readshort();
pf->height = readshort();
@@ -169,7 +180,7 @@ static struct font* font_load_in_memory(struct font* pf)
pf->bits = (unsigned char *)fileptr;
fileptr += pf->bits_size*sizeof(unsigned char);
- if ( pf->bits_size < 0xFFDB )
+ if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
{
/* pad to 16-bit boundary */
fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1);
@@ -182,24 +193,24 @@ static struct font* font_load_in_memory(struct font* pf)
if (noffset)
{
- if ( pf->bits_size < 0xFFDB )
+ if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
{
long_offset = 0;
- pf->offset = (unsigned short *)fileptr;
+ pf->offset = (uint16_t*)fileptr;
/* Check we have sufficient buffer */
- if (!HAVEBYTES(noffset * sizeof(short)))
+ if (!HAVEBYTES(noffset * sizeof(uint16_t)))
return NULL;
for (i=0; i<noffset; ++i)
{
- ((unsigned short*)(pf->offset))[i] = (unsigned short)readshort();
+ ((uint16_t*)(pf->offset))[i] = (uint16_t)readshort();
}
}
else
{
long_offset = 1;
- pf->offset = (unsigned short *)fileptr;
+ pf->offset = (uint16_t*)fileptr;
/* Check we have sufficient buffer */
if (!HAVEBYTES(noffset * sizeof(int32_t)))
@@ -248,7 +259,7 @@ static struct font* font_load_cached(struct font* pf)
/* Calculate offset to offset data */
fileptr += pf->bits_size * sizeof(unsigned char);
- if ( pf->bits_size < 0xFFDB )
+ if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
{
long_offset = 0;
/* pad to 16-bit boundary */
@@ -267,8 +278,8 @@ static struct font* font_load_cached(struct font* pf)
file_offset_offset = 0;
/* Calculate offset to widths data */
- if ( pf->bits_size < 0xFFDB )
- fileptr += noffset * sizeof(unsigned short);
+ if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
+ fileptr += noffset * sizeof(uint16_t);
else
fileptr += noffset * sizeof(uint32_t);
@@ -408,7 +419,7 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
if (file_offset_offset)
{
- int32_t offset = file_offset_offset + char_code * (long_offset ? sizeof(int32_t) : sizeof(short));
+ int32_t offset = file_offset_offset + char_code * (long_offset ? sizeof(int32_t) : sizeof(int16_t));
lseek(fnt_file, offset, SEEK_SET);
read (fnt_file, tmp, 2);
bitmap_offset = tmp[0] | (tmp[1] << 8);
@@ -472,11 +483,18 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
}
else
{
- bits = pf->bits + (pf->offset?
- pf->offset[char_code]:
- (((pf->height + 7) / 8) * pf->maxwidth * char_code));
+ bits = pf->bits;
+ if (pf->offset)
+ {
+ if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
+ bits += ((uint16_t*)(pf->offset))[char_code];
+ else
+ bits += ((uint32_t*)(pf->offset))[char_code];
+ }
+ else
+ bits += ((pf->height + 7) / 8) * pf->maxwidth * char_code;
}
-
+
return bits;
}
@@ -585,8 +603,9 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
char_code = pf->defaultchar;
char_code -= pf->firstchar;
+ /* assume small font with uint16_t offsets*/
bits = pf->bits + (pf->offset?
- pf->offset[char_code]:
+ ((uint16_t*)(pf->offset)[char_code]:
(((pf->height + 7) / 8) * pf->maxwidth * char_code));
return bits;