summaryrefslogtreecommitdiff
path: root/firmware/font.c
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 /firmware/font.c
parent5783bef32c792e192ddf0c160cd793971612d0cc (diff)
downloadrockbox-559c56905e1208264e87ff3bbc2049eb054f95c8.tar.gz
rockbox-559c56905e1208264e87ff3bbc2049eb054f95c8.zip
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
Diffstat (limited to 'firmware/font.c')
-rw-r--r--firmware/font.c77
1 files changed, 48 insertions, 29 deletions
diff --git a/firmware/font.c b/firmware/font.c
index 624e0de9a7..8e89e69a28 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -37,6 +37,27 @@
37#include "rbunicode.h" 37#include "rbunicode.h"
38#include "diacritic.h" 38#include "diacritic.h"
39 39
40#define MAX_FONTSIZE_FOR_16_BIT_OFFSETS 0xFFDB
41
42/* max static loadable font buffer size */
43#ifndef MAX_FONT_SIZE
44#if LCD_HEIGHT > 64
45#if MEM > 2
46#define MAX_FONT_SIZE 60000
47#else
48#define MAX_FONT_SIZE 10000
49#endif
50#else
51#define MAX_FONT_SIZE 4000
52#endif
53#endif
54
55#ifndef FONT_HEADER_SIZE
56#define FONT_HEADER_SIZE 36
57#endif
58
59#define GLYPH_CACHE_FILE ROCKBOX_DIR"/.glyphcache"
60
40#ifndef BOOTLOADER 61#ifndef BOOTLOADER
41/* Font cache includes */ 62/* Font cache includes */
42#include "font_cache.h" 63#include "font_cache.h"
@@ -109,33 +130,23 @@ static int32_t readlong(void)
109 return l; 130 return l;
110} 131}
111 132
112/* read count bytes*/
113static void readstr(char *buf, int count)
114{
115 while (count--)
116 *buf++ = *fileptr++;
117}
118
119void font_reset(void) 133void font_reset(void)
120{ 134{
121 memset(&font_ui, 0, sizeof(struct font)); 135 memset(&font_ui, 0, sizeof(struct font));
122} 136}
123 137
124static struct font* font_load_header(struct font *pf) 138static struct font* font_load_header(struct font *pf)
125{ 139{
126 char version[4+1];
127
128 /* Check we have enough data */ 140 /* Check we have enough data */
129 if (!HAVEBYTES(28)) 141 if (!HAVEBYTES(28))
130 return NULL; 142 return NULL;
131 143
132 /* read magic and version #*/ 144 /* read magic and version #*/
133 memset(version, 0, sizeof(version)); 145 if (memcmp(fileptr, VERSION, 4) != 0)
134 readstr(version, 4);
135
136 if (strcmp(version, VERSION) != 0)
137 return NULL; 146 return NULL;
138 147
148 fileptr += 4;
149
139 /* font info*/ 150 /* font info*/
140 pf->maxwidth = readshort(); 151 pf->maxwidth = readshort();
141 pf->height = readshort(); 152 pf->height = readshort();
@@ -169,7 +180,7 @@ static struct font* font_load_in_memory(struct font* pf)
169 pf->bits = (unsigned char *)fileptr; 180 pf->bits = (unsigned char *)fileptr;
170 fileptr += pf->bits_size*sizeof(unsigned char); 181 fileptr += pf->bits_size*sizeof(unsigned char);
171 182
172 if ( pf->bits_size < 0xFFDB ) 183 if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
173 { 184 {
174 /* pad to 16-bit boundary */ 185 /* pad to 16-bit boundary */
175 fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1); 186 fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1);
@@ -182,24 +193,24 @@ static struct font* font_load_in_memory(struct font* pf)
182 193
183 if (noffset) 194 if (noffset)
184 { 195 {
185 if ( pf->bits_size < 0xFFDB ) 196 if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
186 { 197 {
187 long_offset = 0; 198 long_offset = 0;
188 pf->offset = (unsigned short *)fileptr; 199 pf->offset = (uint16_t*)fileptr;
189 200
190 /* Check we have sufficient buffer */ 201 /* Check we have sufficient buffer */
191 if (!HAVEBYTES(noffset * sizeof(short))) 202 if (!HAVEBYTES(noffset * sizeof(uint16_t)))
192 return NULL; 203 return NULL;
193 204
194 for (i=0; i<noffset; ++i) 205 for (i=0; i<noffset; ++i)
195 { 206 {
196 ((unsigned short*)(pf->offset))[i] = (unsigned short)readshort(); 207 ((uint16_t*)(pf->offset))[i] = (uint16_t)readshort();
197 } 208 }
198 } 209 }
199 else 210 else
200 { 211 {
201 long_offset = 1; 212 long_offset = 1;
202 pf->offset = (unsigned short *)fileptr; 213 pf->offset = (uint16_t*)fileptr;
203 214
204 /* Check we have sufficient buffer */ 215 /* Check we have sufficient buffer */
205 if (!HAVEBYTES(noffset * sizeof(int32_t))) 216 if (!HAVEBYTES(noffset * sizeof(int32_t)))
@@ -248,7 +259,7 @@ static struct font* font_load_cached(struct font* pf)
248 /* Calculate offset to offset data */ 259 /* Calculate offset to offset data */
249 fileptr += pf->bits_size * sizeof(unsigned char); 260 fileptr += pf->bits_size * sizeof(unsigned char);
250 261
251 if ( pf->bits_size < 0xFFDB ) 262 if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
252 { 263 {
253 long_offset = 0; 264 long_offset = 0;
254 /* pad to 16-bit boundary */ 265 /* pad to 16-bit boundary */
@@ -267,8 +278,8 @@ static struct font* font_load_cached(struct font* pf)
267 file_offset_offset = 0; 278 file_offset_offset = 0;
268 279
269 /* Calculate offset to widths data */ 280 /* Calculate offset to widths data */
270 if ( pf->bits_size < 0xFFDB ) 281 if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
271 fileptr += noffset * sizeof(unsigned short); 282 fileptr += noffset * sizeof(uint16_t);
272 else 283 else
273 fileptr += noffset * sizeof(uint32_t); 284 fileptr += noffset * sizeof(uint32_t);
274 285
@@ -408,7 +419,7 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
408 419
409 if (file_offset_offset) 420 if (file_offset_offset)
410 { 421 {
411 int32_t offset = file_offset_offset + char_code * (long_offset ? sizeof(int32_t) : sizeof(short)); 422 int32_t offset = file_offset_offset + char_code * (long_offset ? sizeof(int32_t) : sizeof(int16_t));
412 lseek(fnt_file, offset, SEEK_SET); 423 lseek(fnt_file, offset, SEEK_SET);
413 read (fnt_file, tmp, 2); 424 read (fnt_file, tmp, 2);
414 bitmap_offset = tmp[0] | (tmp[1] << 8); 425 bitmap_offset = tmp[0] | (tmp[1] << 8);
@@ -472,11 +483,18 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
472 } 483 }
473 else 484 else
474 { 485 {
475 bits = pf->bits + (pf->offset? 486 bits = pf->bits;
476 pf->offset[char_code]: 487 if (pf->offset)
477 (((pf->height + 7) / 8) * pf->maxwidth * char_code)); 488 {
489 if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
490 bits += ((uint16_t*)(pf->offset))[char_code];
491 else
492 bits += ((uint32_t*)(pf->offset))[char_code];
493 }
494 else
495 bits += ((pf->height + 7) / 8) * pf->maxwidth * char_code;
478 } 496 }
479 497
480 return bits; 498 return bits;
481} 499}
482 500
@@ -585,8 +603,9 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
585 char_code = pf->defaultchar; 603 char_code = pf->defaultchar;
586 char_code -= pf->firstchar; 604 char_code -= pf->firstchar;
587 605
606 /* assume small font with uint16_t offsets*/
588 bits = pf->bits + (pf->offset? 607 bits = pf->bits + (pf->offset?
589 pf->offset[char_code]: 608 ((uint16_t*)(pf->offset)[char_code]:
590 (((pf->height + 7) / 8) * pf->maxwidth * char_code)); 609 (((pf->height + 7) / 8) * pf->maxwidth * char_code));
591 610
592 return bits; 611 return bits;