mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-10-14 10:37:38 -04:00
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
This commit is contained in:
parent
5783bef32c
commit
559c56905e
2 changed files with 50 additions and 48 deletions
|
@ -33,24 +33,6 @@
|
||||||
#include "sysfont.h"
|
#include "sysfont.h"
|
||||||
#endif
|
#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
|
* Fonts are specified by number, and used for display
|
||||||
|
@ -102,7 +84,8 @@ struct font {
|
||||||
int firstchar; /* first character in bitmap*/
|
int firstchar; /* first character in bitmap*/
|
||||||
int size; /* font size in glyphs*/
|
int size; /* font size in glyphs*/
|
||||||
const unsigned char *bits; /* 8-bit column bitmap data*/
|
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*/
|
const unsigned char *width; /* character widths or NULL if fixed*/
|
||||||
int defaultchar; /* default char (not glyph index)*/
|
int defaultchar; /* default char (not glyph index)*/
|
||||||
int32_t bits_size; /* # bytes of glyph bits*/
|
int32_t bits_size; /* # bytes of glyph bits*/
|
||||||
|
|
|
@ -37,6 +37,27 @@
|
||||||
#include "rbunicode.h"
|
#include "rbunicode.h"
|
||||||
#include "diacritic.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
|
#ifndef BOOTLOADER
|
||||||
/* Font cache includes */
|
/* Font cache includes */
|
||||||
#include "font_cache.h"
|
#include "font_cache.h"
|
||||||
|
@ -109,13 +130,6 @@ static int32_t readlong(void)
|
||||||
return l;
|
return l;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* read count bytes*/
|
|
||||||
static void readstr(char *buf, int count)
|
|
||||||
{
|
|
||||||
while (count--)
|
|
||||||
*buf++ = *fileptr++;
|
|
||||||
}
|
|
||||||
|
|
||||||
void font_reset(void)
|
void font_reset(void)
|
||||||
{
|
{
|
||||||
memset(&font_ui, 0, sizeof(struct font));
|
memset(&font_ui, 0, sizeof(struct font));
|
||||||
|
@ -123,19 +137,16 @@ void font_reset(void)
|
||||||
|
|
||||||
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 */
|
/* Check we have enough data */
|
||||||
if (!HAVEBYTES(28))
|
if (!HAVEBYTES(28))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* read magic and version #*/
|
/* read magic and version #*/
|
||||||
memset(version, 0, sizeof(version));
|
if (memcmp(fileptr, VERSION, 4) != 0)
|
||||||
readstr(version, 4);
|
|
||||||
|
|
||||||
if (strcmp(version, VERSION) != 0)
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
fileptr += 4;
|
||||||
|
|
||||||
/* font info*/
|
/* font info*/
|
||||||
pf->maxwidth = readshort();
|
pf->maxwidth = readshort();
|
||||||
pf->height = readshort();
|
pf->height = readshort();
|
||||||
|
@ -169,7 +180,7 @@ static struct font* font_load_in_memory(struct font* pf)
|
||||||
pf->bits = (unsigned char *)fileptr;
|
pf->bits = (unsigned char *)fileptr;
|
||||||
fileptr += pf->bits_size*sizeof(unsigned char);
|
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 */
|
/* pad to 16-bit boundary */
|
||||||
fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1);
|
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 (noffset)
|
||||||
{
|
{
|
||||||
if ( pf->bits_size < 0xFFDB )
|
if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
|
||||||
{
|
{
|
||||||
long_offset = 0;
|
long_offset = 0;
|
||||||
pf->offset = (unsigned short *)fileptr;
|
pf->offset = (uint16_t*)fileptr;
|
||||||
|
|
||||||
/* Check we have sufficient buffer */
|
/* Check we have sufficient buffer */
|
||||||
if (!HAVEBYTES(noffset * sizeof(short)))
|
if (!HAVEBYTES(noffset * sizeof(uint16_t)))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
for (i=0; i<noffset; ++i)
|
for (i=0; i<noffset; ++i)
|
||||||
{
|
{
|
||||||
((unsigned short*)(pf->offset))[i] = (unsigned short)readshort();
|
((uint16_t*)(pf->offset))[i] = (uint16_t)readshort();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
long_offset = 1;
|
long_offset = 1;
|
||||||
pf->offset = (unsigned short *)fileptr;
|
pf->offset = (uint16_t*)fileptr;
|
||||||
|
|
||||||
/* Check we have sufficient buffer */
|
/* Check we have sufficient buffer */
|
||||||
if (!HAVEBYTES(noffset * sizeof(int32_t)))
|
if (!HAVEBYTES(noffset * sizeof(int32_t)))
|
||||||
|
@ -248,7 +259,7 @@ static struct font* font_load_cached(struct font* pf)
|
||||||
/* Calculate offset to offset data */
|
/* Calculate offset to offset data */
|
||||||
fileptr += pf->bits_size * sizeof(unsigned char);
|
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;
|
long_offset = 0;
|
||||||
/* pad to 16-bit boundary */
|
/* pad to 16-bit boundary */
|
||||||
|
@ -267,8 +278,8 @@ static struct font* font_load_cached(struct font* pf)
|
||||||
file_offset_offset = 0;
|
file_offset_offset = 0;
|
||||||
|
|
||||||
/* Calculate offset to widths data */
|
/* Calculate offset to widths data */
|
||||||
if ( pf->bits_size < 0xFFDB )
|
if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
|
||||||
fileptr += noffset * sizeof(unsigned short);
|
fileptr += noffset * sizeof(uint16_t);
|
||||||
else
|
else
|
||||||
fileptr += noffset * sizeof(uint32_t);
|
fileptr += noffset * sizeof(uint32_t);
|
||||||
|
|
||||||
|
@ -408,7 +419,7 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
|
||||||
|
|
||||||
if (file_offset_offset)
|
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);
|
lseek(fnt_file, offset, SEEK_SET);
|
||||||
read (fnt_file, tmp, 2);
|
read (fnt_file, tmp, 2);
|
||||||
bitmap_offset = tmp[0] | (tmp[1] << 8);
|
bitmap_offset = tmp[0] | (tmp[1] << 8);
|
||||||
|
@ -472,9 +483,16 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bits = pf->bits + (pf->offset?
|
bits = pf->bits;
|
||||||
pf->offset[char_code]:
|
if (pf->offset)
|
||||||
(((pf->height + 7) / 8) * pf->maxwidth * char_code));
|
{
|
||||||
|
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;
|
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->defaultchar;
|
||||||
char_code -= pf->firstchar;
|
char_code -= pf->firstchar;
|
||||||
|
|
||||||
|
/* assume small font with uint16_t offsets*/
|
||||||
bits = pf->bits + (pf->offset?
|
bits = pf->bits + (pf->offset?
|
||||||
pf->offset[char_code]:
|
((uint16_t*)(pf->offset)[char_code]:
|
||||||
(((pf->height + 7) / 8) * pf->maxwidth * char_code));
|
(((pf->height + 7) / 8) * pf->maxwidth * char_code));
|
||||||
|
|
||||||
return bits;
|
return bits;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue