summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJonathan Gordon <rockbox@jdgordon.info>2011-09-24 14:52:16 +0000
committerJonathan Gordon <rockbox@jdgordon.info>2011-09-24 14:52:16 +0000
commit83cfbf4e5102f1a72b4af2ae47a893168dc7cd02 (patch)
treef4a836b576902b2dd9cc2877268bfaf6f99bcb80
parent0c521cffd4b8875a7fa42912f2b86582d37494d5 (diff)
downloadrockbox-83cfbf4e5102f1a72b4af2ae47a893168dc7cd02.zip
rockbox-83cfbf4e5102f1a72b4af2ae47a893168dc7cd02.tar.gz
rockbox-83cfbf4e5102f1a72b4af2ae47a893168dc7cd02.tar.bz2
rockbox-83cfbf4e5102f1a72b4af2ae47a893168dc7cd02.tar.xz
Allow fonts to use smaller buffers than the default size. use font_load_ex() to speficiy the buffer size. If the font is already loaded with a smaller buffer it will be reloaded to use the new size. Also fix an issue where handles would get lost if fonts fail to load in skins
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30592 a1c6a512-1295-4272-9138-f99709370657
-rw-r--r--apps/gui/skin_engine/skin_parser.c29
-rw-r--r--firmware/export/font.h4
-rw-r--r--firmware/font.c49
3 files changed, 59 insertions, 23 deletions
diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c
index 8c87553..c8cca3d 100644
--- a/apps/gui/skin_engine/skin_parser.c
+++ b/apps/gui/skin_engine/skin_parser.c
@@ -419,7 +419,7 @@ static int parse_font_load(struct skin_element *element,
if(element->params_count > 2)
glyphs = element->params[2].data.number;
else
- glyphs = GLYPHS_TO_CACHE;
+ glyphs = 0;
if (id < 2)
{
DEBUGF("font id must be >= 2\n");
@@ -1675,8 +1675,13 @@ static bool skin_load_fonts(struct wps_data *data)
{
char path[MAX_PATH];
snprintf(path, sizeof path, FONT_DIR "/%s", font->name);
- font->id = font_load(path/*,
- skinfonts[font_id-FONT_FIRSTUSERFONT].glyphs*/);
+ if (skinfonts[font_id-2].glyphs > 0)
+ {
+ font->id = font_load_ex(path,
+ font_glyphs_to_bufsize(path, skinfonts[font_id-2].glyphs));
+ }
+ else
+ font->id = font_load(path);
//printf("[%d] %s -> %d\n",font_id, font->name, font->id);
id_array[font_count++] = font->id;
}
@@ -1693,18 +1698,16 @@ static bool skin_load_fonts(struct wps_data *data)
/* finally, assign the font_id to the viewport */
vp->font = font->id;
}
- if (success)
+ data->font_ids = skin_buffer_alloc(font_count * sizeof(int));
+ if (!success || data->font_ids == NULL)
{
- data->font_ids = skin_buffer_alloc(font_count * sizeof(int));
- if (data->font_ids == NULL)
- {
- while (font_count > 0)
- font_unload(id_array[--font_count]);
- return false;
- }
- memcpy(data->font_ids, id_array, sizeof(int)*font_count);
- data->font_count = font_count;
+ while (font_count > 0)
+ font_unload(id_array[--font_count]);
+ data->font_ids = NULL;
+ return false;
}
+ memcpy(data->font_ids, id_array, sizeof(int)*font_count);
+ data->font_count = font_count;
return success;
}
diff --git a/firmware/export/font.h b/firmware/export/font.h
index 6c9e616..582c08f 100644
--- a/firmware/export/font.h
+++ b/firmware/export/font.h
@@ -21,6 +21,7 @@
#ifndef _FONT_H
#define _FONT_H
+#include <stdlib.h>
#include "inttypes.h"
#include "stdbool.h"
@@ -102,7 +103,7 @@ struct font {
unsigned char *buffer_start; /* buffer to store the font in */
unsigned char *buffer_position; /* position in the buffer */
unsigned char *buffer_end; /* end of the buffer */
- int buffer_size; /* size of the buffer in bytes */
+ size_t buffer_size; /* size of the buffer in bytes */
#ifndef __PCTOOL__
struct font_cache cache;
uint32_t file_width_offset; /* offset to file width data */
@@ -116,6 +117,7 @@ struct font {
void font_init(void) INIT_ATTR;
const char* font_filename(int font_id);
int font_load(const char *path);
+int font_load_ex(const char *path, size_t buffer_size);
int font_glyphs_to_bufsize(const char *path, int glyphs);
void font_unload(int font_id);
diff --git a/firmware/font.c b/firmware/font.c
index fea210a..2fda848 100644
--- a/firmware/font.c
+++ b/firmware/font.c
@@ -79,7 +79,7 @@ struct buflib_alloc_data {
struct font font;
bool handle_locked; /* is the buflib handle currently locked? */
int refcount; /* how many times has this font been loaded? */
- unsigned char buffer[MAX_FONT_SIZE];
+ unsigned char buffer[];
};
static int buflib_allocations[MAXFONTS];
static int handle_for_glyphcache;
@@ -349,7 +349,7 @@ static void font_reset(int font_id)
static bool internal_load_font(int font_id, const char *path,
char *buf, size_t buf_size)
{
- int size;
+ size_t size;
struct font* pf = pf_from_handle(buflib_allocations[font_id]);
/* save loaded glyphs */
glyph_cache_save(pf);
@@ -433,15 +433,16 @@ static int find_font_index(const char* path)
return FONT_SYSFIXED;
}
-static int alloc_and_init(int font_idx, const char* name)
+static int alloc_and_init(int font_idx, const char* name, size_t size)
{
int *phandle = &buflib_allocations[font_idx];
int handle = *phandle;
struct buflib_alloc_data *pdata;
struct font *pf;
+ size_t alloc_size = size + sizeof(struct buflib_alloc_data);
if (handle > 0)
return handle;
- *phandle = core_alloc_ex(name, sizeof(struct buflib_alloc_data), &buflibops);
+ *phandle = core_alloc_ex(name, alloc_size, &buflibops);
handle = *phandle;
if (handle < 0)
return handle;
@@ -451,7 +452,7 @@ static int alloc_and_init(int font_idx, const char* name)
pdata->handle_locked = false;
pdata->refcount = 1;
pf->buffer_position = pf->buffer_start = buffer_from_handle(handle);
- pf->buffer_size = MAX_FONT_SIZE;
+ pf->buffer_size = size;
return handle;
}
@@ -465,17 +466,44 @@ const char* font_filename(int font_id)
/* read and load font into incore font structure,
* returns the font number on success, -1 on failure */
-int font_load(const char *path)
+int font_load_ex(const char *path, size_t buffer_size)
{
int font_id = find_font_index(path);
char *buffer;
- size_t buffer_size;
int *handle;
if (font_id > FONT_SYSFIXED)
{
/* already loaded, no need to reload */
struct buflib_alloc_data *pd = core_get_data(buflib_allocations[font_id]);
+ if (pd->font.buffer_size < buffer_size)
+ {
+ int old_refcount, old_id;
+ /* reload the font:
+ * 1) save of refcont and id
+ * 2) force unload (set refcount to 1 to make sure it get unloaded)
+ * 3) reload with the larger buffer
+ * 4) restore the id and refcount
+ */
+ old_id = font_id;
+ old_refcount = pd->refcount;
+ pd->refcount = 1;
+ font_unload(font_id);
+ font_id = font_load_ex(path, buffer_size);
+ if (font_id < 0)
+ {
+ // not much we can do here, maybe try reloading with the small buffer again
+ return -1;
+ }
+ if (old_id != font_id)
+ {
+ buflib_allocations[old_id] = buflib_allocations[font_id];
+ buflib_allocations[font_id] = -1;
+ font_id = old_id;
+ }
+ pd = core_get_data(buflib_allocations[font_id]);
+ pd->refcount = old_refcount;
+ }
pd->refcount++;
//printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount);
return font_id;
@@ -490,7 +518,7 @@ int font_load(const char *path)
}
}
handle = &buflib_allocations[font_id];
- *handle = alloc_and_init(font_id, path);
+ *handle = alloc_and_init(font_id, path, buffer_size);
if (*handle < 0)
return -1;
@@ -498,7 +526,6 @@ int font_load(const char *path)
handle_for_glyphcache = *handle;
buffer = buffer_from_handle(*handle);
- buffer_size = MAX_FONT_SIZE; //FIXME
lock_font_handle(*handle, true);
if (!internal_load_font(font_id, path, buffer, buffer_size))
@@ -513,6 +540,10 @@ int font_load(const char *path)
//printf("%s -> [%d] -> %d\n", path, font_id, *handle);
return font_id; /* success!*/
}
+int font_load(const char *path)
+{
+ return font_load_ex(path, MAX_FONT_SIZE);
+}
void font_unload(int font_id)
{