summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Martitz <kugel@rockbox.org>2014-01-26 13:56:53 +0100
committerThomas Martitz <kugel@rockbox.org>2014-01-26 14:01:48 +0100
commit37be80a1a5eefd862f7ee132083723cef03ceb3c (patch)
tree521c648ceff493422893bcc7e432bd43de969e89
parent8142c68bd294a43a9d615995850fe185baa53216 (diff)
downloadrockbox-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.h1
-rw-r--r--firmware/font.c29
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};
97static int buflib_allocations[MAXFONTS]; 96static 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)
810const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) 808const 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