FS#12293 Global default glyph setting in System > Limits > Glyphs To Cache. Defaults to 250. This saves a lot of RAM while still allowing non-English users to have adequate glyph coverage.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31031 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
d78e05c572
commit
ea7a89606c
11 changed files with 247 additions and 264 deletions
|
@ -78,7 +78,6 @@
|
|||
|
||||
#define WPS_ERROR_INVALID_PARAM -1
|
||||
|
||||
#define GLYPHS_TO_CACHE 256
|
||||
static char* skin_buffer = NULL;
|
||||
void skinparser_set_buffer(char* pointer)
|
||||
{
|
||||
|
@ -468,7 +467,7 @@ static int parse_font_load(struct skin_element *element,
|
|||
if(element->params_count > 2)
|
||||
glyphs = get_param(element, 2)->data.number;
|
||||
else
|
||||
glyphs = GLYPHS_TO_CACHE;
|
||||
glyphs = global_settings.glyphs;
|
||||
if (id < 2)
|
||||
{
|
||||
DEBUGF("font id must be >= 2\n");
|
||||
|
@ -1742,8 +1741,7 @@ static bool skin_load_fonts(struct wps_data *data)
|
|||
char path[MAX_PATH];
|
||||
snprintf(path, sizeof path, FONT_DIR "/%s", font->name);
|
||||
#ifndef __PCTOOL__
|
||||
font->id = font_load_ex(path,
|
||||
font_glyphs_to_bufsize(path, skinfonts[font_id-2].glyphs));
|
||||
font->id = font_load_ex(path, 0, skinfonts[font_id-2].glyphs);
|
||||
|
||||
#else
|
||||
font->id = font_load(path);
|
||||
|
|
|
@ -12951,3 +12951,17 @@
|
|||
hardware_click: "Speaker Keyclick"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
id: LANG_GLYPHS
|
||||
desc: in settings_menu
|
||||
user: core
|
||||
<source>
|
||||
*: "Glyphs To Cache"
|
||||
</source>
|
||||
<dest>
|
||||
*: "Glyphs To Cache"
|
||||
</dest>
|
||||
<voice>
|
||||
*: "Glyphs To Cache"
|
||||
</voice>
|
||||
</phrase>
|
||||
|
|
|
@ -221,8 +221,15 @@ MENUITEM_SETTING(poweroff, &global_settings.poweroff, NULL);
|
|||
/* Limits menu */
|
||||
MENUITEM_SETTING(max_files_in_dir, &global_settings.max_files_in_dir, NULL);
|
||||
MENUITEM_SETTING(max_files_in_playlist, &global_settings.max_files_in_playlist, NULL);
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
MENUITEM_SETTING(default_glyphs, &global_settings.glyphs, NULL);
|
||||
#endif
|
||||
MAKE_MENU(limits_menu, ID2P(LANG_LIMITS_MENU), 0, Icon_NOICON,
|
||||
&max_files_in_dir, &max_files_in_playlist);
|
||||
&max_files_in_dir, &max_files_in_playlist
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
,&default_glyphs
|
||||
#endif
|
||||
);
|
||||
|
||||
|
||||
/* Keyclick menu */
|
||||
|
|
|
@ -886,7 +886,7 @@ void settings_apply(bool read_disk)
|
|||
CHART2(">font_load ", global_settings.font_file);
|
||||
if (font_ui >= 0)
|
||||
font_unload(font_ui);
|
||||
rc = font_load(buf);
|
||||
rc = font_load_ex(buf, 0, global_settings.glyphs);
|
||||
CHART2("<font_load ", global_settings.font_file);
|
||||
screens[SCREEN_MAIN].setuifont(rc);
|
||||
screens[SCREEN_MAIN].setfont(rc);
|
||||
|
|
|
@ -672,6 +672,7 @@ struct user_settings
|
|||
unsigned char icon_file[MAX_FILENAME+1];
|
||||
unsigned char viewers_icon_file[MAX_FILENAME+1];
|
||||
unsigned char font_file[MAX_FILENAME+1]; /* last font */
|
||||
int glyphs;
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
unsigned char remote_font_file[MAX_FILENAME+1]; /* last font */
|
||||
#endif
|
||||
|
|
|
@ -222,6 +222,9 @@ static const char graphic_numeric[] = "graphic,numeric";
|
|||
#else
|
||||
#define DEFAULT_FONTNAME "35-Adobe-Helvetica"
|
||||
#endif
|
||||
#define DEFAULT_GLYPHS 250
|
||||
#define MIN_GLYPHS 50
|
||||
#define MAX_GLYPHS 65540
|
||||
|
||||
#else
|
||||
#define DEFAULT_FONTNAME ""
|
||||
|
@ -1622,6 +1625,9 @@ const struct settings_list settings[] = {
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
TEXT_SETTING(F_THEMESETTING, font_file, "font",
|
||||
DEFAULT_FONTNAME, FONT_DIR "/", ".fnt"),
|
||||
INT_SETTING(0, glyphs, LANG_GLYPHS, DEFAULT_GLYPHS,
|
||||
"glyphs", UNIT_INT, MIN_GLYPHS, MAX_GLYPHS, 10,
|
||||
NULL, NULL, NULL),
|
||||
#endif
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
TEXT_SETTING(F_THEMESETTING, remote_font_file, "remote font",
|
||||
|
|
|
@ -102,6 +102,7 @@ struct font {
|
|||
int fd; /* fd for the font file. >= 0 if cached */
|
||||
int fd_width; /* fd for the font file. >= 0 if cached */
|
||||
int fd_offset; /* fd for the font file. >= 0 if cached */
|
||||
int handle; /* core_allocator handle */
|
||||
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 */
|
||||
|
@ -119,8 +120,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);
|
||||
int font_load_ex(const char *path, size_t buffer_size, int glyphs);
|
||||
void font_unload(int font_id);
|
||||
void font_unload_all(void);
|
||||
void font_lock(int font_id, bool lock);
|
||||
|
|
445
firmware/font.c
445
firmware/font.c
|
@ -55,6 +55,11 @@
|
|||
#define MAX_FONT_SIZE 4000
|
||||
#endif
|
||||
#endif
|
||||
#define GLYPHS_TO_CACHE 256
|
||||
|
||||
#if MEMORYSIZE < 4
|
||||
#define FONT_HARD_LIMIT
|
||||
#endif
|
||||
|
||||
#ifndef FONT_HEADER_SIZE
|
||||
#define FONT_HEADER_SIZE 36
|
||||
|
@ -117,6 +122,8 @@ static int buflibmove_callback(int handle, void* current, void* new)
|
|||
}
|
||||
static void lock_font_handle(int handle, bool lock)
|
||||
{
|
||||
if ( handle < 0 )
|
||||
return;
|
||||
struct buflib_alloc_data *alloc = core_get_data(handle);
|
||||
if ( lock )
|
||||
alloc->handle_locks++;
|
||||
|
@ -150,7 +157,7 @@ static inline unsigned char *buffer_from_handle(int handle)
|
|||
|
||||
/* Font cache structures */
|
||||
static void cache_create(struct font* pf);
|
||||
static void glyph_cache_load(int fond_id);
|
||||
static void glyph_cache_load(const char *font_path, struct font *pf);
|
||||
/* End Font cache structures */
|
||||
|
||||
void font_init(void)
|
||||
|
@ -199,48 +206,14 @@ static int glyph_bytes( struct font *pf, int width )
|
|||
return (ret + 1) & ~1;
|
||||
}
|
||||
|
||||
static struct font* font_load_header(struct font *pf)
|
||||
{
|
||||
/* Check we have enough data */
|
||||
if (!HAVEBYTES(28))
|
||||
return NULL;
|
||||
|
||||
/* read magic and version #*/
|
||||
if (memcmp(pf->buffer_position, VERSION, 4) != 0)
|
||||
return NULL;
|
||||
|
||||
pf->buffer_position += 4;
|
||||
|
||||
/* font info*/
|
||||
pf->maxwidth = readshort(pf);
|
||||
pf->height = readshort(pf);
|
||||
pf->ascent = readshort(pf);
|
||||
pf->depth = readshort(pf);
|
||||
pf->firstchar = readlong(pf);
|
||||
pf->defaultchar = readlong(pf);
|
||||
pf->size = readlong(pf);
|
||||
|
||||
/* get variable font data sizes*/
|
||||
/* # words of bitmap_t*/
|
||||
pf->bits_size = readlong(pf);
|
||||
|
||||
return pf;
|
||||
}
|
||||
/* Load memory font */
|
||||
static struct font* font_load_in_memory(struct font* pf)
|
||||
static struct font* font_load_in_memory(struct font* pf,
|
||||
int32_t noffset,
|
||||
int32_t nwidth )
|
||||
{
|
||||
int32_t i, noffset, nwidth;
|
||||
|
||||
if (!HAVEBYTES(4))
|
||||
return NULL;
|
||||
|
||||
/* # longs of offset*/
|
||||
noffset = readlong(pf);
|
||||
|
||||
/* # bytes of width*/
|
||||
nwidth = readlong(pf);
|
||||
|
||||
int i;
|
||||
/* variable font data*/
|
||||
pf->buffer_position = pf->buffer_start + 36;
|
||||
pf->bits = (unsigned char *)pf->buffer_position;
|
||||
pf->buffer_position += pf->bits_size*sizeof(unsigned char);
|
||||
|
||||
|
@ -303,20 +276,10 @@ static struct font* font_load_in_memory(struct font* pf)
|
|||
}
|
||||
|
||||
/* Load cached font */
|
||||
static struct font* font_load_cached(struct font* pf)
|
||||
static struct font* font_load_cached(struct font* pf,
|
||||
int32_t nwidth,
|
||||
int32_t noffset)
|
||||
{
|
||||
uint32_t noffset, nwidth;
|
||||
unsigned char* oldfileptr = pf->buffer_position;
|
||||
|
||||
if (!HAVEBYTES(2 * sizeof(int32_t)))
|
||||
return NULL;
|
||||
|
||||
/* # longs of offset*/
|
||||
noffset = readlong(pf);
|
||||
|
||||
/* # bytes of width*/
|
||||
nwidth = readlong(pf);
|
||||
|
||||
/* We are now at the bitmap data, this is fixed at 36.. */
|
||||
pf->bits = NULL;
|
||||
|
||||
|
@ -352,96 +315,12 @@ static struct font* font_load_cached(struct font* pf)
|
|||
else
|
||||
pf->file_width_offset = 0;
|
||||
|
||||
pf->buffer_position = oldfileptr;
|
||||
|
||||
/* Create the cache */
|
||||
cache_create(pf);
|
||||
|
||||
return pf;
|
||||
}
|
||||
|
||||
static bool internal_load_font(int font_id, const char *path, char *buf,
|
||||
size_t buf_size, int handle)
|
||||
{
|
||||
size_t size;
|
||||
struct font* pf = pf_from_handle(handle);
|
||||
|
||||
/* open and read entire font file*/
|
||||
pf->fd = open(path, O_RDONLY|O_BINARY);
|
||||
|
||||
if (pf->fd < 0) {
|
||||
DEBUGF("Can't open font: %s\n", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check file size */
|
||||
size = filesize(pf->fd);
|
||||
pf->buffer_start = buf;
|
||||
pf->buffer_size = buf_size;
|
||||
|
||||
pf->buffer_position = buf;
|
||||
|
||||
if (size > pf->buffer_size)
|
||||
{
|
||||
read(pf->fd, pf->buffer_position, FONT_HEADER_SIZE);
|
||||
pf->buffer_end = pf->buffer_position + FONT_HEADER_SIZE;
|
||||
|
||||
if (!font_load_header(pf))
|
||||
{
|
||||
DEBUGF("Failed font header load");
|
||||
close(pf->fd);
|
||||
pf->fd = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!font_load_cached(pf))
|
||||
{
|
||||
DEBUGF("Failed font cache load");
|
||||
close(pf->fd);
|
||||
pf->fd = -1;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Cheat to get sector cache for different parts of font *
|
||||
* file while preloading glyphs. Without this the disk head *
|
||||
* thrashes between the width, offset, and bitmap data *
|
||||
* in glyph_cache_load(). */
|
||||
pf->fd_width = open(path, O_RDONLY|O_BINARY);
|
||||
pf->fd_offset = open(path, O_RDONLY|O_BINARY);
|
||||
|
||||
glyph_cache_load(font_id);
|
||||
|
||||
if(pf->fd_width >= 0)
|
||||
close(pf->fd_width);
|
||||
pf->fd_width = -1;
|
||||
|
||||
if(pf->fd_offset >= 0)
|
||||
close(pf->fd_offset);
|
||||
pf->fd_offset = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
read(pf->fd, pf->buffer_position, pf->buffer_size);
|
||||
pf->buffer_end = pf->buffer_position + size;
|
||||
close(pf->fd);
|
||||
pf->fd = -1;
|
||||
pf->fd_width = -1;
|
||||
pf->fd_offset = -1;
|
||||
|
||||
if (!font_load_header(pf))
|
||||
{
|
||||
DEBUGF("Failed font header load");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!font_load_in_memory(pf))
|
||||
{
|
||||
DEBUGF("Failed mem load");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
static int find_font_index(const char* path)
|
||||
{
|
||||
|
@ -457,30 +336,6 @@ static int find_font_index(const char* path)
|
|||
return FONT_SYSFIXED;
|
||||
}
|
||||
|
||||
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, alloc_size, &buflibops);
|
||||
handle = *phandle;
|
||||
if (handle < 0)
|
||||
return handle;
|
||||
pdata = core_get_data(handle);
|
||||
pf = &pdata->font;
|
||||
pdata->handle_locks = 0;
|
||||
pdata->refcount = 1;
|
||||
pf->buffer_position = pf->buffer_start = buffer_from_handle(handle);
|
||||
pf->buffer_size = size;
|
||||
pf->fd_width = -1;
|
||||
pf->fd_offset = -1;
|
||||
return handle;
|
||||
}
|
||||
|
||||
const char* font_filename(int font_id)
|
||||
{
|
||||
int handle = buflib_allocations[font_id];
|
||||
|
@ -489,21 +344,117 @@ const char* font_filename(int font_id)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* read and load font into incore font structure,
|
||||
* returns the font number on success, -1 on failure */
|
||||
int font_load_ex(const char *path, size_t buffer_size)
|
||||
size_t font_glyphs_to_bufsize(struct font *pf, int glyphs)
|
||||
{
|
||||
size_t bufsize;
|
||||
|
||||
/* LRU bytes per glyph */
|
||||
bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) +
|
||||
sizeof( unsigned short);
|
||||
/* Image bytes per glyph */
|
||||
bufsize += glyph_bytes(pf, pf->maxwidth);
|
||||
bufsize *= glyphs;
|
||||
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
static struct font* font_load_header(int fd, struct font *pheader,
|
||||
struct font *pf,
|
||||
uint32_t *nwidth, uint32_t *noffset)
|
||||
{
|
||||
/* Load the header. Readshort() and readlong() *
|
||||
* update buffer_position address as they read */
|
||||
pheader->buffer_start = pheader->buffer_position = (char *)pheader;
|
||||
pheader->buffer_size = FONT_HEADER_SIZE;
|
||||
pheader->buffer_end = pheader->buffer_start + pheader->buffer_size;
|
||||
|
||||
if (read(fd, pheader, FONT_HEADER_SIZE) != FONT_HEADER_SIZE)
|
||||
return NULL;
|
||||
|
||||
/* read magic and version #*/
|
||||
if (memcmp(pheader->buffer_position, VERSION, 4) != 0)
|
||||
return NULL;
|
||||
|
||||
pheader->buffer_position += 4;
|
||||
|
||||
/* font info*/
|
||||
pf->maxwidth = readshort(pheader);
|
||||
pf->height = readshort(pheader);
|
||||
pf->ascent = readshort(pheader);
|
||||
pf->depth = readshort(pheader);
|
||||
pf->firstchar = readlong(pheader);
|
||||
pf->defaultchar = readlong(pheader);
|
||||
pf->size = readlong(pheader);
|
||||
|
||||
/* get variable font data sizes*/
|
||||
/* # words of bitmap_t*/
|
||||
pf->bits_size = readlong(pheader);
|
||||
*noffset = readlong(pheader);
|
||||
*nwidth = readlong(pheader);
|
||||
|
||||
return pf;
|
||||
}
|
||||
|
||||
/* load a font with room for glyphs, limited to bufsize if not zero */
|
||||
int font_load_ex( const char *path, size_t buf_size, int glyphs )
|
||||
{
|
||||
//printf("\nfont_load_ex(%s, %d, %d)\n", path, buf_size, glyphs);
|
||||
int fd = open(path, O_RDONLY|O_BINARY);
|
||||
if ( fd < 0 )
|
||||
return -1;
|
||||
|
||||
/* load font struct f with file header */
|
||||
int file_size = filesize( fd );
|
||||
struct font header;
|
||||
struct font *pheader = &header;
|
||||
struct font f;
|
||||
|
||||
uint32_t nwidth, noffset;
|
||||
if ( !font_load_header( fd, pheader, &f, &nwidth, &noffset )
|
||||
#if LCD_DEPTH < 16
|
||||
|| f.depth
|
||||
#endif
|
||||
)
|
||||
{
|
||||
close(fd);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* examine f and calc buffer size */
|
||||
bool cached = false;
|
||||
size_t bufsize = buf_size;
|
||||
size_t glyph_buf_size = font_glyphs_to_bufsize( &f, glyphs );
|
||||
|
||||
if ( bufsize && glyphs && bufsize > glyph_buf_size)
|
||||
bufsize = glyph_buf_size;
|
||||
else
|
||||
{
|
||||
if ( glyphs )
|
||||
bufsize = glyph_buf_size;
|
||||
else
|
||||
bufsize = MAX_FONT_SIZE;
|
||||
}
|
||||
#ifdef FONT_HARD_LIMIT
|
||||
if ( bufsize > MAX_FONT_SIZE )
|
||||
bufsize = MAX_FONT_SIZE;
|
||||
#endif
|
||||
if ( bufsize < (size_t) file_size )
|
||||
cached = true;
|
||||
else
|
||||
bufsize = file_size;
|
||||
|
||||
/* check already loaded */
|
||||
int font_id = find_font_index(path);
|
||||
char *buffer;
|
||||
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)
|
||||
if (pd->font.buffer_size < bufsize)
|
||||
{
|
||||
int old_refcount, old_id;
|
||||
size_t old_bufsize = pd->font.buffer_size;
|
||||
bool failed = false;
|
||||
/* reload the font:
|
||||
* 1) save of refcont and id
|
||||
* 2) force unload (set refcount to 1 to make sure it get unloaded)
|
||||
|
@ -514,10 +465,13 @@ int font_load_ex(const char *path, size_t buffer_size)
|
|||
old_refcount = pd->refcount;
|
||||
pd->refcount = 1;
|
||||
font_unload(font_id);
|
||||
font_id = font_load_ex(path, buffer_size);
|
||||
font_id = font_load_ex(path, bufsize, glyphs);
|
||||
if (font_id < 0)
|
||||
{
|
||||
// not much we can do here, maybe try reloading with the small buffer again
|
||||
failed = true;
|
||||
font_id = font_load_ex(path, old_bufsize, 0);
|
||||
/* we couldn't even get the old size, this shouldn't happen */
|
||||
if ( font_id < 0 )
|
||||
return -1;
|
||||
}
|
||||
if (old_id != font_id)
|
||||
|
@ -528,51 +482,100 @@ int font_load_ex(const char *path, size_t buffer_size)
|
|||
}
|
||||
pd = core_get_data(buflib_allocations[font_id]);
|
||||
pd->refcount = old_refcount;
|
||||
if(failed)
|
||||
/* return error because we didn't satisfy the new buffer size */
|
||||
return -1;
|
||||
}
|
||||
pd->refcount++;
|
||||
//printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount);
|
||||
close(fd);
|
||||
return font_id;
|
||||
}
|
||||
|
||||
int open_slot = -1;
|
||||
|
||||
for (font_id = FONT_FIRSTUSERFONT; font_id < MAXFONTS; font_id++)
|
||||
{
|
||||
handle = buflib_allocations[font_id];
|
||||
if (handle < 0)
|
||||
if (buflib_allocations[ font_id ] < 0)
|
||||
{
|
||||
open_slot = font_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
handle = alloc_and_init(font_id, path, buffer_size);
|
||||
if (handle < 0)
|
||||
if ( open_slot == -1 )
|
||||
return -1;
|
||||
font_id = open_slot;
|
||||
|
||||
buffer = buffer_from_handle(handle);
|
||||
lock_font_handle(handle, true);
|
||||
|
||||
if (!internal_load_font(font_id, path, buffer, buffer_size, handle))
|
||||
/* allocate mem */
|
||||
int handle = core_alloc_ex( path,
|
||||
bufsize + sizeof( struct buflib_alloc_data ),
|
||||
&buflibops );
|
||||
if ( handle < 0 )
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
struct buflib_alloc_data *pdata;
|
||||
pdata = core_get_data(handle);
|
||||
pdata->handle_locks = 1;
|
||||
pdata->refcount = 1;
|
||||
|
||||
/* load and init */
|
||||
struct font *pf = pf_from_handle( handle );
|
||||
memcpy(pf, &f, sizeof( struct font) );
|
||||
|
||||
pf->fd = fd;
|
||||
pf->fd_width = pf->fd_offset = -1;
|
||||
pf->handle = handle;
|
||||
|
||||
pf->buffer_start = buffer_from_handle( pf->handle );
|
||||
pf->buffer_position = pf->buffer_start + FONT_HEADER_SIZE;
|
||||
pf->buffer_size = bufsize;
|
||||
pf->buffer_end = pf->buffer_start + bufsize;
|
||||
|
||||
if ( cached )
|
||||
{
|
||||
if ( ! font_load_cached( pf, nwidth, noffset ) )
|
||||
{
|
||||
lock_font_handle(handle, false);
|
||||
core_free( handle );
|
||||
buflib_allocations[font_id] = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lock_font_handle(handle, false);
|
||||
/* trick to get a small cache for each file section *
|
||||
* during glyph_cache_load() */
|
||||
pf->fd_width = open( path, O_RDONLY|O_BINARY );
|
||||
pf->fd_offset = open( path, O_RDONLY|O_BINARY );
|
||||
|
||||
glyph_cache_load( path, pf );
|
||||
|
||||
/* cached font: pf->fd stays open until the font is unloaded */
|
||||
close( pf->fd_width );
|
||||
pf->fd_width = -1;
|
||||
close( pf->fd_offset );
|
||||
pf->fd_offset = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
lseek( fd, 0, SEEK_SET);
|
||||
read(fd, pf->buffer_start, pf->buffer_size);
|
||||
|
||||
close( fd );
|
||||
pf->fd = -1;
|
||||
|
||||
if ( ! font_load_in_memory( pf, nwidth, noffset ) )
|
||||
{
|
||||
core_free( handle );
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buflib_allocations[font_id] = handle;
|
||||
//printf("%s -> [%d] -> %d\n", path, font_id, *handle);
|
||||
lock_font_handle( handle, false );
|
||||
return font_id; /* success!*/
|
||||
}
|
||||
|
||||
int font_load(const char *path)
|
||||
{
|
||||
int size;
|
||||
int fd = open( path, O_RDONLY );
|
||||
if ( fd < 0 )
|
||||
return -1;
|
||||
size = filesize(fd);
|
||||
if (size > MAX_FONT_SIZE)
|
||||
size = MAX_FONT_SIZE;
|
||||
close(fd);
|
||||
return font_load_ex(path, size);
|
||||
return font_load_ex(path, MAX_FONT_SIZE, GLYPHS_TO_CACHE);
|
||||
}
|
||||
|
||||
void font_unload(int font_id)
|
||||
|
@ -640,22 +643,6 @@ struct font* font_get(int font)
|
|||
}
|
||||
}
|
||||
|
||||
static int pf_to_handle(struct font* pf)
|
||||
{
|
||||
int i;
|
||||
for (i=0; i<MAXFONTS; i++)
|
||||
{
|
||||
int handle = buflib_allocations[i];
|
||||
if (handle > 0)
|
||||
{
|
||||
struct buflib_alloc_data *pdata = core_get_data(handle);
|
||||
if (pf == &pdata->font)
|
||||
return handle;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Reads an entry into cache entry
|
||||
*/
|
||||
|
@ -663,13 +650,12 @@ static void
|
|||
load_cache_entry(struct font_cache_entry* p, void* callback_data)
|
||||
{
|
||||
struct font* pf = callback_data;
|
||||
int handle = pf_to_handle(pf);
|
||||
|
||||
unsigned short char_code = p->_char_code;
|
||||
unsigned char tmp[2];
|
||||
int fd;
|
||||
|
||||
if (handle > 0)
|
||||
lock_font_handle(handle, true);
|
||||
lock_font_handle(pf->handle, true);
|
||||
if (pf->file_width_offset)
|
||||
{
|
||||
int width_offset = pf->file_width_offset + char_code;
|
||||
|
@ -714,8 +700,7 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
|
|||
int src_bytes = glyph_bytes(pf, p->width);
|
||||
read(pf->fd, p->bitmap, src_bytes);
|
||||
|
||||
if (handle > 0)
|
||||
lock_font_handle(handle, false);
|
||||
lock_font_handle(pf->handle, false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -850,49 +835,13 @@ void glyph_cache_save(int font_id)
|
|||
return;
|
||||
}
|
||||
|
||||
int font_glyphs_to_bufsize(const char *path, int glyphs)
|
||||
{
|
||||
struct font f;
|
||||
int bufsize;
|
||||
char buf[FONT_HEADER_SIZE];
|
||||
|
||||
f.buffer_start = buf;
|
||||
f.buffer_size = sizeof(buf);
|
||||
f.buffer_position = buf;
|
||||
|
||||
f.fd = open(path, O_RDONLY|O_BINARY);
|
||||
if(f.fd < 0)
|
||||
return 0;
|
||||
|
||||
read(f.fd, f.buffer_position, FONT_HEADER_SIZE);
|
||||
f.buffer_end = f.buffer_position + FONT_HEADER_SIZE;
|
||||
|
||||
if( !font_load_header(&f) )
|
||||
{
|
||||
close(f.fd);
|
||||
return 0;
|
||||
}
|
||||
close(f.fd);
|
||||
|
||||
bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) +
|
||||
sizeof( unsigned short);
|
||||
bufsize += glyph_bytes(&f, f.maxwidth);
|
||||
bufsize *= glyphs;
|
||||
if ( bufsize < FONT_HEADER_SIZE )
|
||||
bufsize = FONT_HEADER_SIZE;
|
||||
return bufsize;
|
||||
}
|
||||
|
||||
static int ushortcmp(const void *a, const void *b)
|
||||
{
|
||||
return ((int)(*(unsigned short*)a - *(unsigned short*)b));
|
||||
}
|
||||
static void glyph_cache_load(int font_id)
|
||||
static void glyph_cache_load(const char *font_path, struct font *pf)
|
||||
{
|
||||
int handle = buflib_allocations[font_id];
|
||||
if (handle < 0)
|
||||
return;
|
||||
struct font *pf = pf_from_handle(handle);
|
||||
#define MAX_SORT 256
|
||||
if (pf->fd >= 0) {
|
||||
int i, size, fd;
|
||||
|
@ -907,7 +856,7 @@ static void glyph_cache_load(int font_id)
|
|||
sort_size = MAX_SORT;
|
||||
|
||||
char filename[MAX_PATH];
|
||||
font_path_to_glyph_path(font_filename(font_id), filename);
|
||||
font_path_to_glyph_path(font_path, filename);
|
||||
|
||||
fd = open(filename, O_RDONLY|O_BINARY);
|
||||
#ifdef TRY_DEFAULT_GLYPHCACHE
|
||||
|
|
|
@ -342,7 +342,8 @@ and the WPS, but you can use multiple fonts in each of the individual screens.\\
|
|||
\item `filename' is the font filename to load. Fonts should be stored in
|
||||
\fname{/.rockbox/fonts/}
|
||||
\item `glyphs' is an optional specification of how many unique glyphs to
|
||||
store in memory. Default is 256.
|
||||
store in memory. Default is from the system setting
|
||||
\setting{Glyphs To Load}.
|
||||
\end{itemize}
|
||||
|
||||
An example would be: \config{\%Fl(2,12-Nimbus.fnt,100)}
|
||||
|
|
|
@ -136,9 +136,15 @@ This sub menu relates to limits in the Rockbox operating system.
|
|||
in steps of 1,000 (default is 10,000). Higher values will shorten the
|
||||
music buffer, so you should increase this setting \emph{only} if you
|
||||
have very large playlists.
|
||||
|
||||
\item [Glyphs To Cache.] This sets the default memory allocation size
|
||||
for fonts in unique glyphs. This should be set to the number of unique
|
||||
language glyphs and punctuation marks that are frequently displayed.
|
||||
The default is 250.
|
||||
\end{description}
|
||||
\note{You will need to restart your player for changes to these options
|
||||
to take effect.}
|
||||
\note{You will need to restart your player for changes to \setting{Max
|
||||
Entries in File Browser} or \setting{Max Playlist Size} to take effect
|
||||
while \setting{Glyphs To Cache} will affect the next font load.}
|
||||
% TODO: this needs to be rewritten in another style, it lets you mix sound from another source into the music
|
||||
\opt{player}{
|
||||
\subsection{Line In} This option activates the line-in port on \dap, which is
|
||||
|
|
|
@ -1413,6 +1413,7 @@ int gen_c_source(struct font* pf, char *path)
|
|||
fprintf(ofp, " -1, /* font fd */\n"
|
||||
" -1, /* font fd width */\n"
|
||||
" -1, /* font fd offset */\n"
|
||||
" -1, /* font handle */\n"
|
||||
" 0, /* buffer start */\n"
|
||||
" 0, /* ^ position */\n"
|
||||
" 0, /* ^ end */\n"
|
||||
|
|
Loading…
Reference in a new issue