diff options
author | Thomas Martitz <kugel@rockbox.org> | 2014-01-26 13:56:53 +0100 |
---|---|---|
committer | Thomas Martitz <kugel@rockbox.org> | 2014-01-26 14:01:48 +0100 |
commit | 37be80a1a5eefd862f7ee132083723cef03ceb3c (patch) | |
tree | 521c648ceff493422893bcc7e432bd43de969e89 | |
parent | 8142c68bd294a43a9d615995850fe185baa53216 (diff) | |
download | rockbox-37be80a1a5eefd862f7ee132083723cef03ceb3c.tar.gz rockbox-37be80a1a5eefd862f7ee132083723cef03ceb3c.zip |
fonts: Fix regression(s) caused by c23ce62.
The builtin sysfont does not have an associated buflib_alloc_data
(because it's builtin right?). font_get_{width,bits} accessed a field of
it for all fonts which crashed on some systems but not on mine.
Solution: Move this field to struct font directly.
The cache size calculated was also busted.
Fixes FS#12944 and most likely FS#12938.
Change-Id: I32303c4335a12a6c421fdca34f7ece851aac12ca
-rw-r--r-- | firmware/export/font.h | 1 | ||||
-rw-r--r-- | firmware/font.c | 29 |
2 files changed, 13 insertions, 17 deletions
diff --git a/firmware/export/font.h b/firmware/export/font.h index d19e0b87ad..ad72cb52c7 100644 --- a/firmware/export/font.h +++ b/firmware/export/font.h | |||
@@ -107,6 +107,7 @@ struct font { | |||
107 | unsigned char *buffer_position; /* position in the buffer */ | 107 | unsigned char *buffer_position; /* position in the buffer */ |
108 | unsigned char *buffer_end; /* end of the buffer */ | 108 | unsigned char *buffer_end; /* end of the buffer */ |
109 | size_t buffer_size; /* size of the buffer in bytes */ | 109 | size_t buffer_size; /* size of the buffer in bytes */ |
110 | bool disabled; /* font disabled (use blank as fallback if not in cache) */ | ||
110 | #ifndef __PCTOOL__ | 111 | #ifndef __PCTOOL__ |
111 | struct font_cache cache; | 112 | struct font_cache cache; |
112 | uint32_t file_width_offset; /* offset to file width data */ | 113 | uint32_t file_width_offset; /* offset to file width data */ |
diff --git a/firmware/font.c b/firmware/font.c index 1b5825ae86..617a8a33e3 100644 --- a/firmware/font.c +++ b/firmware/font.c | |||
@@ -91,7 +91,6 @@ struct buflib_alloc_data { | |||
91 | struct font font; /* must be the first member! */ | 91 | struct font font; /* must be the first member! */ |
92 | int handle_locks; /* is the buflib handle currently locked? */ | 92 | int handle_locks; /* is the buflib handle currently locked? */ |
93 | int refcount; /* how many times has this font been loaded? */ | 93 | int refcount; /* how many times has this font been loaded? */ |
94 | int disabled; /* font disabled (use fallback glyphs, from sysfont) */ | ||
95 | unsigned char buffer[]; | 94 | unsigned char buffer[]; |
96 | }; | 95 | }; |
97 | static int buflib_allocations[MAXFONTS]; | 96 | static int buflib_allocations[MAXFONTS]; |
@@ -471,7 +470,6 @@ int font_load_ex( const char *path, size_t buf_size, int glyphs ) | |||
471 | old_id = font_id; | 470 | old_id = font_id; |
472 | old_refcount = pd->refcount; | 471 | old_refcount = pd->refcount; |
473 | pd->refcount = 1; | 472 | pd->refcount = 1; |
474 | pd->disabled = false; | ||
475 | font_unload(font_id); | 473 | font_unload(font_id); |
476 | font_id = font_load_ex(path, bufsize, glyphs); | 474 | font_id = font_load_ex(path, bufsize, glyphs); |
477 | if (font_id < 0) | 475 | if (font_id < 0) |
@@ -526,7 +524,6 @@ int font_load_ex( const char *path, size_t buf_size, int glyphs ) | |||
526 | pdata = core_get_data(handle); | 524 | pdata = core_get_data(handle); |
527 | pdata->handle_locks = 1; | 525 | pdata->handle_locks = 1; |
528 | pdata->refcount = 1; | 526 | pdata->refcount = 1; |
529 | pdata->disabled = false; | ||
530 | 527 | ||
531 | /* load and init */ | 528 | /* load and init */ |
532 | struct font *pf = &pdata->font; | 529 | struct font *pf = &pdata->font; |
@@ -535,6 +532,7 @@ int font_load_ex( const char *path, size_t buf_size, int glyphs ) | |||
535 | pf->fd = fd; | 532 | pf->fd = fd; |
536 | pf->fd_width = pf->fd_offset = -1; | 533 | pf->fd_width = pf->fd_offset = -1; |
537 | pf->handle = handle; | 534 | pf->handle = handle; |
535 | pf->disabled = false; | ||
538 | 536 | ||
539 | pf->buffer_start = buffer_from_handle( pf->handle ); | 537 | pf->buffer_start = buffer_from_handle( pf->handle ); |
540 | pf->buffer_position = pf->buffer_start + FONT_HEADER_SIZE; | 538 | pf->buffer_position = pf->buffer_start + FONT_HEADER_SIZE; |
@@ -643,7 +641,7 @@ static void font_disable(int font_id) | |||
643 | glyph_cache_save(font_id); | 641 | glyph_cache_save(font_id); |
644 | close(pf->fd); | 642 | close(pf->fd); |
645 | pf->fd = -1; | 643 | pf->fd = -1; |
646 | pdata->disabled = true; | 644 | pf->disabled = true; |
647 | } | 645 | } |
648 | } | 646 | } |
649 | 647 | ||
@@ -663,11 +661,11 @@ static void font_enable(int font_id) | |||
663 | struct buflib_alloc_data *pdata = core_get_data(handle); | 661 | struct buflib_alloc_data *pdata = core_get_data(handle); |
664 | struct font *pf = &pdata->font; | 662 | struct font *pf = &pdata->font; |
665 | 663 | ||
666 | if (pdata->disabled && pf->fd < 0) | 664 | if (pf->disabled && pf->fd < 0) |
667 | { | 665 | { |
668 | const char *filename = font_filename(font_id); | 666 | const char *filename = font_filename(font_id); |
669 | pf->fd = open(filename, O_RDONLY); | 667 | pf->fd = open(filename, O_RDONLY); |
670 | pdata->disabled = false; | 668 | pf->disabled = false; |
671 | } | 669 | } |
672 | } | 670 | } |
673 | 671 | ||
@@ -774,7 +772,7 @@ static void cache_create(struct font* pf) | |||
774 | /* reserve one blank glyph that is guaranteed to be available, even | 772 | /* reserve one blank glyph that is guaranteed to be available, even |
775 | * when the font file is closed during USB */ | 773 | * when the font file is closed during USB */ |
776 | unsigned char *cache_buf = pf->buffer_start + bitmap_size; | 774 | unsigned char *cache_buf = pf->buffer_start + bitmap_size; |
777 | size_t cache_size = pf->buffer_size - (cache_buf - pf->buffer_start); | 775 | size_t cache_size = pf->buffer_size - bitmap_size; |
778 | ALIGN_BUFFER(cache_buf, cache_size, 2); | 776 | ALIGN_BUFFER(cache_buf, cache_size, 2); |
779 | memset(pf->buffer_start, 0, bitmap_size); | 777 | memset(pf->buffer_start, 0, bitmap_size); |
780 | /* Initialise cache */ | 778 | /* Initialise cache */ |
@@ -788,17 +786,17 @@ int font_get_width(struct font* pf, unsigned short char_code) | |||
788 | { | 786 | { |
789 | int width; | 787 | int width; |
790 | struct font_cache_entry *e; | 788 | struct font_cache_entry *e; |
791 | struct buflib_alloc_data *data = (struct buflib_alloc_data *) pf; | ||
792 | bool cache_only = data->disabled; | ||
793 | 789 | ||
794 | /* check input range*/ | 790 | /* check input range*/ |
795 | if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size) | 791 | if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size) |
796 | char_code = pf->defaultchar; | 792 | char_code = pf->defaultchar; |
797 | char_code -= pf->firstchar; | 793 | char_code -= pf->firstchar; |
798 | 794 | ||
799 | if ((pf->fd >= 0 || cache_only) && pf != &sysfont | 795 | if (pf->fd >= 0 && pf != &sysfont) |
800 | && (e = font_cache_get(&pf->cache,char_code,cache_only,load_cache_entry,pf))) | 796 | width = font_cache_get(&pf->cache,char_code,false,load_cache_entry,pf)->width; |
801 | width = e->width; | 797 | else if (pf->disabled && |
798 | (e = font_cache_get(&pf->cache,char_code,true,load_cache_entry,pf))) | ||
799 | width = e->width; /* falls back to pf->maxwidth if !e */ | ||
802 | else if (pf->width) | 800 | else if (pf->width) |
803 | width = pf->width[char_code]; | 801 | width = pf->width[char_code]; |
804 | else | 802 | else |
@@ -810,22 +808,19 @@ int font_get_width(struct font* pf, unsigned short char_code) | |||
810 | const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) | 808 | const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) |
811 | { | 809 | { |
812 | const unsigned char* bits; | 810 | const unsigned char* bits; |
813 | struct buflib_alloc_data *data; | ||
814 | 811 | ||
815 | /* check input range*/ | 812 | /* check input range*/ |
816 | if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size) | 813 | if (char_code < pf->firstchar || char_code >= pf->firstchar+pf->size) |
817 | char_code = pf->defaultchar; | 814 | char_code = pf->defaultchar; |
818 | char_code -= pf->firstchar; | 815 | char_code -= pf->firstchar; |
819 | 816 | ||
820 | data = (struct buflib_alloc_data *) pf; | ||
821 | |||
822 | if (pf->fd >= 0 && pf != &sysfont) | 817 | if (pf->fd >= 0 && pf != &sysfont) |
823 | { | 818 | { |
824 | bits = | 819 | bits = |
825 | (unsigned char*)font_cache_get(&pf->cache, char_code, | 820 | (unsigned char*)font_cache_get(&pf->cache, char_code, |
826 | false, load_cache_entry, data)->bitmap; | 821 | false, load_cache_entry, pf)->bitmap; |
827 | } | 822 | } |
828 | else if (data->disabled) | 823 | else if (pf->disabled) |
829 | { | 824 | { |
830 | /* the font handle is closed, but the cache is intact. Attempt | 825 | /* the font handle is closed, but the cache is intact. Attempt |
831 | * a lookup, which is very likely to succeed. Return a placeholder | 826 | * a lookup, which is very likely to succeed. Return a placeholder |