forked from len0rd/rockbox
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
This commit is contained in:
parent
0c521cffd4
commit
83cfbf4e51
3 changed files with 59 additions and 23 deletions
|
@ -419,7 +419,7 @@ static int parse_font_load(struct skin_element *element,
|
||||||
if(element->params_count > 2)
|
if(element->params_count > 2)
|
||||||
glyphs = element->params[2].data.number;
|
glyphs = element->params[2].data.number;
|
||||||
else
|
else
|
||||||
glyphs = GLYPHS_TO_CACHE;
|
glyphs = 0;
|
||||||
if (id < 2)
|
if (id < 2)
|
||||||
{
|
{
|
||||||
DEBUGF("font id must be >= 2\n");
|
DEBUGF("font id must be >= 2\n");
|
||||||
|
@ -1675,8 +1675,13 @@ static bool skin_load_fonts(struct wps_data *data)
|
||||||
{
|
{
|
||||||
char path[MAX_PATH];
|
char path[MAX_PATH];
|
||||||
snprintf(path, sizeof path, FONT_DIR "/%s", font->name);
|
snprintf(path, sizeof path, FONT_DIR "/%s", font->name);
|
||||||
font->id = font_load(path/*,
|
if (skinfonts[font_id-2].glyphs > 0)
|
||||||
skinfonts[font_id-FONT_FIRSTUSERFONT].glyphs*/);
|
{
|
||||||
|
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);
|
//printf("[%d] %s -> %d\n",font_id, font->name, font->id);
|
||||||
id_array[font_count++] = 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 */
|
/* finally, assign the font_id to the viewport */
|
||||||
vp->font = font->id;
|
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));
|
while (font_count > 0)
|
||||||
if (data->font_ids == NULL)
|
font_unload(id_array[--font_count]);
|
||||||
{
|
data->font_ids = NULL;
|
||||||
while (font_count > 0)
|
return false;
|
||||||
font_unload(id_array[--font_count]);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
memcpy(data->font_ids, id_array, sizeof(int)*font_count);
|
|
||||||
data->font_count = font_count;
|
|
||||||
}
|
}
|
||||||
|
memcpy(data->font_ids, id_array, sizeof(int)*font_count);
|
||||||
|
data->font_count = font_count;
|
||||||
return success;
|
return success;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#ifndef _FONT_H
|
#ifndef _FONT_H
|
||||||
#define _FONT_H
|
#define _FONT_H
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
#include "inttypes.h"
|
#include "inttypes.h"
|
||||||
#include "stdbool.h"
|
#include "stdbool.h"
|
||||||
|
|
||||||
|
@ -102,7 +103,7 @@ struct font {
|
||||||
unsigned char *buffer_start; /* buffer to store the font in */
|
unsigned char *buffer_start; /* buffer to store the font in */
|
||||||
unsigned char *buffer_position; /* position in the buffer */
|
unsigned char *buffer_position; /* position in the buffer */
|
||||||
unsigned char *buffer_end; /* end of 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__
|
#ifndef __PCTOOL__
|
||||||
struct font_cache cache;
|
struct font_cache cache;
|
||||||
uint32_t file_width_offset; /* offset to file width data */
|
uint32_t file_width_offset; /* offset to file width data */
|
||||||
|
@ -116,6 +117,7 @@ struct font {
|
||||||
void font_init(void) INIT_ATTR;
|
void font_init(void) INIT_ATTR;
|
||||||
const char* font_filename(int font_id);
|
const char* font_filename(int font_id);
|
||||||
int font_load(const char *path);
|
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);
|
int font_glyphs_to_bufsize(const char *path, int glyphs);
|
||||||
void font_unload(int font_id);
|
void font_unload(int font_id);
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ struct buflib_alloc_data {
|
||||||
struct font font;
|
struct font font;
|
||||||
bool handle_locked; /* is the buflib handle currently locked? */
|
bool handle_locked; /* is the buflib handle currently locked? */
|
||||||
int refcount; /* how many times has this font been loaded? */
|
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 buflib_allocations[MAXFONTS];
|
||||||
static int handle_for_glyphcache;
|
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,
|
static bool internal_load_font(int font_id, const char *path,
|
||||||
char *buf, size_t buf_size)
|
char *buf, size_t buf_size)
|
||||||
{
|
{
|
||||||
int size;
|
size_t size;
|
||||||
struct font* pf = pf_from_handle(buflib_allocations[font_id]);
|
struct font* pf = pf_from_handle(buflib_allocations[font_id]);
|
||||||
/* save loaded glyphs */
|
/* save loaded glyphs */
|
||||||
glyph_cache_save(pf);
|
glyph_cache_save(pf);
|
||||||
|
@ -433,15 +433,16 @@ static int find_font_index(const char* path)
|
||||||
return FONT_SYSFIXED;
|
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 *phandle = &buflib_allocations[font_idx];
|
||||||
int handle = *phandle;
|
int handle = *phandle;
|
||||||
struct buflib_alloc_data *pdata;
|
struct buflib_alloc_data *pdata;
|
||||||
struct font *pf;
|
struct font *pf;
|
||||||
|
size_t alloc_size = size + sizeof(struct buflib_alloc_data);
|
||||||
if (handle > 0)
|
if (handle > 0)
|
||||||
return handle;
|
return handle;
|
||||||
*phandle = core_alloc_ex(name, sizeof(struct buflib_alloc_data), &buflibops);
|
*phandle = core_alloc_ex(name, alloc_size, &buflibops);
|
||||||
handle = *phandle;
|
handle = *phandle;
|
||||||
if (handle < 0)
|
if (handle < 0)
|
||||||
return handle;
|
return handle;
|
||||||
|
@ -451,7 +452,7 @@ static int alloc_and_init(int font_idx, const char* name)
|
||||||
pdata->handle_locked = false;
|
pdata->handle_locked = false;
|
||||||
pdata->refcount = 1;
|
pdata->refcount = 1;
|
||||||
pf->buffer_position = pf->buffer_start = buffer_from_handle(handle);
|
pf->buffer_position = pf->buffer_start = buffer_from_handle(handle);
|
||||||
pf->buffer_size = MAX_FONT_SIZE;
|
pf->buffer_size = size;
|
||||||
return handle;
|
return handle;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -465,17 +466,44 @@ const char* font_filename(int font_id)
|
||||||
|
|
||||||
/* read and load font into incore font structure,
|
/* read and load font into incore font structure,
|
||||||
* returns the font number on success, -1 on failure */
|
* 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);
|
int font_id = find_font_index(path);
|
||||||
char *buffer;
|
char *buffer;
|
||||||
size_t buffer_size;
|
|
||||||
int *handle;
|
int *handle;
|
||||||
|
|
||||||
if (font_id > FONT_SYSFIXED)
|
if (font_id > FONT_SYSFIXED)
|
||||||
{
|
{
|
||||||
/* already loaded, no need to reload */
|
/* already loaded, no need to reload */
|
||||||
struct buflib_alloc_data *pd = core_get_data(buflib_allocations[font_id]);
|
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++;
|
pd->refcount++;
|
||||||
//printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount);
|
//printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount);
|
||||||
return font_id;
|
return font_id;
|
||||||
|
@ -490,7 +518,7 @@ int font_load(const char *path)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
handle = &buflib_allocations[font_id];
|
handle = &buflib_allocations[font_id];
|
||||||
*handle = alloc_and_init(font_id, path);
|
*handle = alloc_and_init(font_id, path, buffer_size);
|
||||||
if (*handle < 0)
|
if (*handle < 0)
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
@ -498,7 +526,6 @@ int font_load(const char *path)
|
||||||
handle_for_glyphcache = *handle;
|
handle_for_glyphcache = *handle;
|
||||||
|
|
||||||
buffer = buffer_from_handle(*handle);
|
buffer = buffer_from_handle(*handle);
|
||||||
buffer_size = MAX_FONT_SIZE; //FIXME
|
|
||||||
lock_font_handle(*handle, true);
|
lock_font_handle(*handle, true);
|
||||||
|
|
||||||
if (!internal_load_font(font_id, path, buffer, buffer_size))
|
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);
|
//printf("%s -> [%d] -> %d\n", path, font_id, *handle);
|
||||||
return font_id; /* success!*/
|
return font_id; /* success!*/
|
||||||
}
|
}
|
||||||
|
int font_load(const char *path)
|
||||||
|
{
|
||||||
|
return font_load_ex(path, MAX_FONT_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
void font_unload(int font_id)
|
void font_unload(int font_id)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue