diff options
author | Nils Wallménius <nils@rockbox.org> | 2009-12-13 11:07:40 +0000 |
---|---|---|
committer | Nils Wallménius <nils@rockbox.org> | 2009-12-13 11:07:40 +0000 |
commit | 559c56905e1208264e87ff3bbc2049eb054f95c8 (patch) | |
tree | 9085ed0f8193d5fd514b6c46d7834341cba37cbf /firmware/font.c | |
parent | 5783bef32c792e192ddf0c160cd793971612d0cc (diff) | |
download | rockbox-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.c | 77 |
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*/ | ||
113 | static void readstr(char *buf, int count) | ||
114 | { | ||
115 | while (count--) | ||
116 | *buf++ = *fileptr++; | ||
117 | } | ||
118 | |||
119 | void font_reset(void) | 133 | void 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 | ||
124 | static struct font* font_load_header(struct font *pf) | 138 | static 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; |