FS#12273 - use buflib for font storage. thanks to the testers :)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@30589 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
f323300b82
commit
aa0f4a4bbe
37 changed files with 410 additions and 404 deletions
|
@ -105,9 +105,6 @@ gui/viewport.c
|
|||
gui/skin_engine/skin_backdrops.c
|
||||
gui/skin_engine/skin_display.c
|
||||
gui/skin_engine/skin_engine.c
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
gui/skin_engine/skin_fonts.c
|
||||
#endif
|
||||
gui/skin_engine/skin_parser.c
|
||||
gui/skin_engine/skin_render.c
|
||||
gui/skin_engine/skin_tokens.c
|
||||
|
|
|
@ -404,27 +404,31 @@ int ft_load(struct tree_context* c, const char* tempdir)
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
static void ft_load_font(char *file)
|
||||
{
|
||||
int current_font_id;
|
||||
enum screen_type screen = SCREEN_MAIN;
|
||||
#if NB_SCREENS > 1
|
||||
MENUITEM_STRINGLIST(menu, ID2P(LANG_CUSTOM_FONT), NULL,
|
||||
ID2P(LANG_MAIN_SCREEN), ID2P(LANG_REMOTE_SCREEN))
|
||||
switch (do_menu(&menu, NULL, NULL, false))
|
||||
{
|
||||
case 0: /* main lcd */
|
||||
splash(0, ID2P(LANG_WAIT));
|
||||
font_load(NULL, file);
|
||||
screen = SCREEN_MAIN;
|
||||
set_file(file, (char *)global_settings.font_file, MAX_FILENAME);
|
||||
break;
|
||||
case 1: /* remote */
|
||||
splash(0, ID2P(LANG_WAIT));
|
||||
font_load_remoteui(file);
|
||||
screen = SCREEN_REMOTE;
|
||||
set_file(file, (char *)global_settings.remote_font_file, MAX_FILENAME);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
splash(0, ID2P(LANG_WAIT));
|
||||
font_load(NULL, file);
|
||||
set_file(file, (char *)global_settings.font_file, MAX_FILENAME);
|
||||
#endif
|
||||
splash(0, ID2P(LANG_WAIT));
|
||||
current_font_id = global_status.font_id[screen];
|
||||
if (current_font_id >= 0)
|
||||
font_unload(current_font_id);
|
||||
global_status.font_id[screen] = font_load(file);
|
||||
viewportmanager_theme_changed(THEME_UI_VIEWPORT);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
|
|
@ -107,9 +107,9 @@ void settings_apply_skins(void)
|
|||
{
|
||||
int i, j;
|
||||
|
||||
for (i=0; i<SKINNABLE_SCREENS_COUNT; i++)
|
||||
for(j=0; j<SKINNABLE_SCREENS_COUNT; j++)
|
||||
{
|
||||
FOR_NB_SCREENS(j)
|
||||
FOR_NB_SCREENS(i)
|
||||
skin_data_free_buflib_allocs(&skins[j][i].data);
|
||||
}
|
||||
|
||||
|
@ -117,7 +117,6 @@ void settings_apply_skins(void)
|
|||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
skin_backdrop_init();
|
||||
skin_font_init();
|
||||
#endif
|
||||
gui_sync_skin_init();
|
||||
|
||||
|
|
|
@ -25,7 +25,6 @@
|
|||
|
||||
#ifndef PLUGIN
|
||||
|
||||
#include "skin_fonts.h"
|
||||
#include "tag_table.h"
|
||||
|
||||
#include "wps_internals.h" /* TODO: remove this line.. shoudlnt be needed */
|
||||
|
@ -44,8 +43,7 @@ enum skinnable_screens {
|
|||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
|
||||
#define SKIN_BUFFER_SIZE (2048 + SKIN_FONT_SIZE) + \
|
||||
(WPS_MAX_TOKENS * \
|
||||
#define SKIN_BUFFER_SIZE (WPS_MAX_TOKENS * \
|
||||
(sizeof(struct wps_token) + (sizeof(struct skin_element))))
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1,142 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2010 Jonathan Gordon
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "file.h"
|
||||
#include "settings.h"
|
||||
#include "font.h"
|
||||
#include "skin_buffer.h"
|
||||
#include "skin_fonts.h"
|
||||
|
||||
static struct skin_font_info {
|
||||
struct font font;
|
||||
int font_id;
|
||||
char name[MAX_PATH];
|
||||
char *buffer;
|
||||
int ref_count; /* how many times has this font been loaded? */
|
||||
} font_table[MAXUSERFONTS];
|
||||
|
||||
/* need this to know if we should be closing font fd's on the next init */
|
||||
static bool first_load = true;
|
||||
|
||||
void skin_font_init(void)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAXUSERFONTS;i++)
|
||||
{
|
||||
if (!first_load)
|
||||
font_unload(font_table[i].font_id);
|
||||
font_table[i].font_id = -1;
|
||||
font_table[i].name[0] = '\0';
|
||||
font_table[i].buffer = NULL;
|
||||
font_table[i].ref_count = 0;
|
||||
}
|
||||
first_load = false;
|
||||
}
|
||||
|
||||
/* load a font into the skin buffer. return the font id. */
|
||||
int skin_font_load(char* font_name, int glyphs)
|
||||
{
|
||||
int i;
|
||||
int skin_font_size = 0;
|
||||
struct font *pf;
|
||||
struct skin_font_info *font = NULL;
|
||||
char filename[MAX_PATH];
|
||||
|
||||
if (!strcmp(font_name, global_settings.font_file))
|
||||
return FONT_UI;
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
if (!strcmp(font_name, global_settings.remote_font_file))
|
||||
return FONT_UI_REMOTE;
|
||||
#endif
|
||||
snprintf(filename, MAX_PATH, FONT_DIR "/%s.fnt", font_name);
|
||||
|
||||
for(i=0;i<MAXUSERFONTS;i++)
|
||||
{
|
||||
if (font_table[i].font_id >= 0 && !strcmp(font_table[i].name, filename))
|
||||
{
|
||||
font_table[i].ref_count++;
|
||||
return font_table[i].font_id;
|
||||
}
|
||||
else if (!font && font_table[i].font_id == -1)
|
||||
{
|
||||
font = &font_table[i];
|
||||
strcpy(font_table[i].name, filename);
|
||||
}
|
||||
}
|
||||
if (!font)
|
||||
return -1; /* too many fonts loaded */
|
||||
|
||||
pf = &font->font;
|
||||
if (!font->buffer)
|
||||
{
|
||||
if (!glyphs)
|
||||
glyphs = GLYPHS_TO_CACHE;
|
||||
#ifndef __PCTOOL__
|
||||
skin_font_size = font_glyphs_to_bufsize(filename, glyphs);
|
||||
#else
|
||||
skin_font_size = 1;
|
||||
#endif
|
||||
if ( !skin_font_size )
|
||||
return -1;
|
||||
pf->buffer_start = (char*)skin_buffer_alloc(skin_font_size);
|
||||
if (!pf->buffer_start)
|
||||
return -1;
|
||||
font->buffer = pf->buffer_start;
|
||||
pf->buffer_size = skin_font_size;
|
||||
}
|
||||
else
|
||||
{
|
||||
pf->buffer_start = font->buffer;
|
||||
}
|
||||
|
||||
pf->fd = -1;
|
||||
font->font_id = font_load(pf, filename);
|
||||
|
||||
if (font->font_id < 0)
|
||||
return -1;
|
||||
font->ref_count = 1;
|
||||
|
||||
return font->font_id;
|
||||
}
|
||||
/* unload a skin font. If a font has been loaded more than once it wont actually
|
||||
* be unloaded untill all references have been unloaded */
|
||||
void skin_font_unload(int font_id)
|
||||
{
|
||||
int i;
|
||||
for(i=0;i<MAXUSERFONTS;i++)
|
||||
{
|
||||
if (font_table[i].font_id == font_id)
|
||||
{
|
||||
if (--font_table[i].ref_count == 0)
|
||||
{
|
||||
font_unload(font_id);
|
||||
font_table[i].font_id = -1;
|
||||
font_table[i].name[0] = '\0';
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,50 +0,0 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id$
|
||||
*
|
||||
* Copyright (C) 2010 Jonathan Gordon
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
||||
* KIND, either express or implied.
|
||||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include "config.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "file.h"
|
||||
#include "settings.h"
|
||||
#include "font.h"
|
||||
|
||||
#ifndef _SKINFONTS_H_
|
||||
#define _SKINFONTS_H_
|
||||
|
||||
#if LCD_HEIGHT > 160
|
||||
#define SKIN_FONT_SIZE (1024*10)
|
||||
#else
|
||||
#define SKIN_FONT_SIZE (1024*3)
|
||||
#endif
|
||||
#define GLYPHS_TO_CACHE 256
|
||||
|
||||
void skin_font_init(void);
|
||||
|
||||
/* load a font into the skin buffer. return the font id.
|
||||
* reserve room for glyphs glyphs */
|
||||
int skin_font_load(char* font_name, int glyphs);
|
||||
|
||||
/* unload a skin font. If a font has been loaded more than once it wont actually
|
||||
* be unloaded untill all references have been unloaded */
|
||||
void skin_font_unload(int font_id);
|
||||
#endif
|
|
@ -62,7 +62,6 @@
|
|||
#include "radio.h"
|
||||
#include "tuner.h"
|
||||
#endif
|
||||
#include "skin_fonts.h"
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "bmp.h"
|
||||
|
@ -77,6 +76,12 @@
|
|||
|
||||
#define WPS_ERROR_INVALID_PARAM -1
|
||||
|
||||
#if LCD_HEIGHT > 160
|
||||
#define SKIN_FONT_SIZE (1024*10)
|
||||
#else
|
||||
#define SKIN_FONT_SIZE (1024*3)
|
||||
#endif
|
||||
#define GLYPHS_TO_CACHE 256
|
||||
|
||||
static bool isdefault(struct skin_tag_parameter *param)
|
||||
{
|
||||
|
@ -415,8 +420,13 @@ static int parse_font_load(struct skin_element *element,
|
|||
glyphs = element->params[2].data.number;
|
||||
else
|
||||
glyphs = GLYPHS_TO_CACHE;
|
||||
if (id < 2)
|
||||
{
|
||||
DEBUGF("font id must be >= 2\n");
|
||||
return 1;
|
||||
}
|
||||
#if defined(DEBUG) || defined(SIMULATOR)
|
||||
if (skinfonts[id-FONT_FIRSTUSERFONT].name != NULL)
|
||||
if (skinfonts[id-2].name != NULL)
|
||||
{
|
||||
DEBUGF("font id %d already being used\n", id);
|
||||
}
|
||||
|
@ -426,9 +436,9 @@ static int parse_font_load(struct skin_element *element,
|
|||
ptr = strchr(filename, '.');
|
||||
if (!ptr || strncmp(ptr, ".fnt", 4))
|
||||
return WPS_ERROR_INVALID_PARAM;
|
||||
skinfonts[id-FONT_FIRSTUSERFONT].id = -1;
|
||||
skinfonts[id-FONT_FIRSTUSERFONT].name = filename;
|
||||
skinfonts[id-FONT_FIRSTUSERFONT].glyphs = glyphs;
|
||||
skinfonts[id-2].id = -1;
|
||||
skinfonts[id-2].name = filename;
|
||||
skinfonts[id-2].glyphs = glyphs;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -1442,6 +1452,11 @@ void skin_data_free_buflib_allocs(struct wps_data *wps_data)
|
|||
core_free(img->buflib_handle);
|
||||
list = list->next;
|
||||
}
|
||||
if (wps_data->font_ids != NULL)
|
||||
{
|
||||
while (wps_data->font_count > 0)
|
||||
font_unload(wps_data->font_ids[--wps_data->font_count]);
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
@ -1617,6 +1632,8 @@ static bool load_skin_bitmaps(struct wps_data *wps_data, char *bmpdir)
|
|||
static bool skin_load_fonts(struct wps_data *data)
|
||||
{
|
||||
/* don't spit out after the first failue to aid debugging */
|
||||
int id_array[MAXUSERFONTS];
|
||||
int font_count = 0;
|
||||
bool success = true;
|
||||
struct skin_element *vp_list;
|
||||
int font_id;
|
||||
|
@ -1628,19 +1645,20 @@ static bool skin_load_fonts(struct wps_data *data)
|
|||
(struct skin_viewport*)vp_list->data;
|
||||
struct viewport *vp = &skin_vp->vp;
|
||||
|
||||
|
||||
if (vp->font <= FONT_UI)
|
||||
font_id = skin_vp->parsed_fontid;
|
||||
if (font_id == 1)
|
||||
{ /* the usual case -> built-in fonts */
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
if (vp->font == FONT_UI)
|
||||
vp->font += curr_screen;
|
||||
#endif
|
||||
vp->font = global_status.font_id[curr_screen];
|
||||
continue;
|
||||
}
|
||||
else if (font_id <= 0)
|
||||
{
|
||||
vp->font = FONT_SYSFIXED;
|
||||
continue;
|
||||
}
|
||||
font_id = vp->font;
|
||||
|
||||
/* now find the corresponding skin_font */
|
||||
struct skin_font *font = &skinfonts[font_id-FONT_FIRSTUSERFONT];
|
||||
struct skin_font *font = &skinfonts[font_id-2];
|
||||
if (!font->name)
|
||||
{
|
||||
if (success)
|
||||
|
@ -1655,10 +1673,12 @@ static bool skin_load_fonts(struct wps_data *data)
|
|||
* multiple viewports use the same */
|
||||
if (font->id < 0)
|
||||
{
|
||||
char *dot = strchr(font->name, '.');
|
||||
*dot = '\0';
|
||||
font->id = skin_font_load(font->name,
|
||||
skinfonts[font_id-FONT_FIRSTUSERFONT].glyphs);
|
||||
char path[MAX_PATH];
|
||||
snprintf(path, sizeof path, FONT_DIR "/%s", font->name);
|
||||
font->id = font_load(path/*,
|
||||
skinfonts[font_id-FONT_FIRSTUSERFONT].glyphs*/);
|
||||
//printf("[%d] %s -> %d\n",font_id, font->name, font->id);
|
||||
id_array[font_count++] = font->id;
|
||||
}
|
||||
|
||||
if (font->id < 0)
|
||||
|
@ -1667,13 +1687,24 @@ static bool skin_load_fonts(struct wps_data *data)
|
|||
font_id, font->name);
|
||||
font->name = NULL; /* to stop trying to load it again if we fail */
|
||||
success = false;
|
||||
font->name = NULL;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* 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 (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;
|
||||
}
|
||||
return success;
|
||||
}
|
||||
|
||||
|
@ -1690,17 +1721,12 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
|
|||
skin_vp->hidden_flags = 0;
|
||||
skin_vp->label = NULL;
|
||||
skin_vp->is_infovp = false;
|
||||
skin_vp->parsed_fontid = 1;
|
||||
element->data = skin_vp;
|
||||
curr_vp = skin_vp;
|
||||
curr_viewport_element = element;
|
||||
|
||||
viewport_set_defaults(&skin_vp->vp, curr_screen);
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
/* viewport_set_defaults() sets the font to FONT_UI+curr_screen.
|
||||
* This parser requires font 1 to always be the UI font,
|
||||
* so force it back to FONT_UI and handle the screen number at the end */
|
||||
skin_vp->vp.font = FONT_UI;
|
||||
#endif
|
||||
|
||||
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
|
||||
skin_vp->start_fgcolour = skin_vp->vp.fg_pattern;
|
||||
|
@ -1788,9 +1814,7 @@ static int convert_viewport(struct wps_data *data, struct skin_element* element)
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
/* font */
|
||||
if (!isdefault(param))
|
||||
{
|
||||
skin_vp->vp.font = param->data.number;
|
||||
}
|
||||
skin_vp->parsed_fontid = param->data.number;
|
||||
#endif
|
||||
if ((unsigned) skin_vp->vp.x >= (unsigned) display->lcdwidth ||
|
||||
skin_vp->vp.width + skin_vp->vp.x > display->lcdwidth ||
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#ifdef HAVE_ALBUMART
|
||||
#include "albumart.h"
|
||||
#endif
|
||||
#include "settings.h"
|
||||
#include "skin_display.h"
|
||||
#include "skin_engine.h"
|
||||
#include "skin_parser.h"
|
||||
|
@ -650,6 +651,10 @@ void skin_render_viewport(struct skin_element* viewport, struct gui_wps *gwps,
|
|||
img->display = -1;
|
||||
imglist = imglist->next;
|
||||
}
|
||||
|
||||
/* fix font ID's */
|
||||
if (skin_viewport->parsed_fontid == 1)
|
||||
skin_viewport->vp.font = global_status.font_id[display->screen_type];
|
||||
#endif
|
||||
|
||||
while (line)
|
||||
|
|
|
@ -182,6 +182,7 @@ struct skin_viewport {
|
|||
char hidden_flags;
|
||||
bool is_infovp;
|
||||
char* label;
|
||||
int parsed_fontid;
|
||||
#if LCD_DEPTH > 1
|
||||
unsigned start_fgcolour;
|
||||
unsigned start_bgcolour;
|
||||
|
@ -325,6 +326,8 @@ struct wps_data
|
|||
struct skin_element *tree;
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
struct skin_token_list *images;
|
||||
int *font_ids;
|
||||
int font_count;
|
||||
#endif
|
||||
#if LCD_DEPTH > 1 || defined(HAVE_REMOTE_LCD) && LCD_REMOTE_DEPTH > 1
|
||||
struct {
|
||||
|
|
|
@ -125,6 +125,10 @@ struct viewport *sb_skin_get_info_vp(enum screen_type screen)
|
|||
viewportmanager_theme_undo(screen, true);
|
||||
}
|
||||
vp = skin_find_item(infovp_label[screen], SKIN_FIND_UIVP, data);
|
||||
if (!vp)
|
||||
return NULL;
|
||||
if (vp->parsed_fontid == 1)
|
||||
vp->vp.font = global_status.font_id[screen];
|
||||
return &vp->vp;
|
||||
}
|
||||
|
||||
|
|
|
@ -41,7 +41,6 @@
|
|||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "bitmaps/usblogo.h"
|
||||
#include "skin_engine/skin_fonts.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
|
@ -265,11 +264,9 @@ void gui_usb_screen_run(bool early_usb)
|
|||
{
|
||||
/* The font system leaves the .fnt fd's open, so we need for force close them all */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
font_reset(NULL);
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
font_load_remoteui(NULL);
|
||||
#endif
|
||||
skin_font_init(); /* unload all the skin fonts */
|
||||
FOR_NB_SCREENS(i)
|
||||
font_unload(global_status.font_id[i]);
|
||||
// FIXME skin_font_init(); /* unload all the skin fonts */
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -272,13 +272,10 @@ void viewportmanager_theme_changed(const int which)
|
|||
screens[SCREEN_MAIN].has_buttonbar = global_settings.buttonbar;
|
||||
}
|
||||
#endif
|
||||
if (which & THEME_UI_VIEWPORT)
|
||||
{
|
||||
}
|
||||
if (which & THEME_LANGUAGE)
|
||||
{
|
||||
}
|
||||
if (which & THEME_STATUSBAR)
|
||||
if (which & (THEME_STATUSBAR|THEME_UI_VIEWPORT))
|
||||
{
|
||||
FOR_NB_SCREENS(i)
|
||||
{
|
||||
|
@ -324,7 +321,7 @@ void viewport_set_fullscreen(struct viewport *vp,
|
|||
#ifndef __PCTOOL__
|
||||
set_default_align_flags(vp);
|
||||
#endif
|
||||
vp->font = FONT_UI + screen; /* default to UI to discourage SYSFONT use */
|
||||
vp->font = global_status.font_id[screen];
|
||||
vp->drawmode = DRMODE_SOLID;
|
||||
#if LCD_DEPTH > 1
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
|
|
|
@ -336,6 +336,7 @@ static void init_tagcache(void)
|
|||
|
||||
static void init(void)
|
||||
{
|
||||
int i;
|
||||
system_init();
|
||||
core_allocator_init();
|
||||
kernel_init();
|
||||
|
@ -347,7 +348,11 @@ static void init(void)
|
|||
#ifdef HAVE_REMOTE_LCD
|
||||
lcd_remote_init();
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
FOR_NB_SCREENS(i)
|
||||
global_status.font_id[i] = FONT_SYSFIXED;
|
||||
font_init();
|
||||
#endif
|
||||
show_logo();
|
||||
button_init();
|
||||
powermgmt_init();
|
||||
|
@ -451,7 +456,11 @@ static void init(void)
|
|||
#ifdef HAVE_REMOTE_LCD
|
||||
lcd_remote_init();
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
FOR_NB_SCREENS(rc)
|
||||
global_status.font_id[rc] = FONT_SYSFIXED;
|
||||
font_init();
|
||||
#endif
|
||||
|
||||
CHART(">show_logo");
|
||||
show_logo();
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdbool.h>
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
|
|
|
@ -174,7 +174,7 @@ static const struct plugin_api rockbox_api = {
|
|||
lcd_update_rect,
|
||||
lcd_set_drawmode,
|
||||
lcd_get_drawmode,
|
||||
lcd_setfont,
|
||||
screen_helper_setfont,
|
||||
lcd_drawpixel,
|
||||
lcd_drawline,
|
||||
lcd_hline,
|
||||
|
@ -230,6 +230,7 @@ static const struct plugin_api rockbox_api = {
|
|||
#endif
|
||||
font_get_bits,
|
||||
font_load,
|
||||
font_unload,
|
||||
font_get,
|
||||
font_getstringsize,
|
||||
font_get_width,
|
||||
|
@ -905,7 +906,7 @@ int plugin_load(const char* plugin, const void* parameter)
|
|||
#endif
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
lcd_setfont(FONT_UI);
|
||||
screen_helper_setfont(FONT_UI);
|
||||
#if LCD_DEPTH > 1
|
||||
#ifdef HAVE_LCD_COLOR
|
||||
lcd_set_drawinfo(DRMODE_SOLID, global_settings.fg_color,
|
||||
|
|
|
@ -272,7 +272,8 @@ struct plugin_api {
|
|||
bool (*is_diacritic)(const unsigned short char_code, bool *is_rtl);
|
||||
#endif
|
||||
const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code );
|
||||
int (*font_load)(struct font*, const char *path);
|
||||
int (*font_load)(const char *path);
|
||||
void (*font_unload)(int font_id);
|
||||
struct font* (*font_get)(int font);
|
||||
int (*font_getstringsize)(const unsigned char *str, int *w, int *h,
|
||||
int fontnumber);
|
||||
|
|
|
@ -265,7 +265,7 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
{
|
||||
int retval = 0;
|
||||
|
||||
rb->lcd_setfont(0);
|
||||
rb->lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
||||
rb->cpu_boost(true);
|
||||
|
|
|
@ -667,7 +667,7 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
rb->cpu_boost(true);
|
||||
#endif
|
||||
|
||||
rb->lcd_setfont(0);
|
||||
rb->lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
// We're using doom's memory management since it implements a proper free (and re-uses the memory)
|
||||
// and now with prboom's code: realloc and calloc
|
||||
|
@ -712,7 +712,7 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
|
||||
Dhandle_ver( namemap[ result ] );
|
||||
|
||||
rb->lcd_setfont(0);
|
||||
rb->lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
rb->lcd_clear_display();
|
||||
|
||||
|
|
|
@ -433,6 +433,11 @@ RB_WRAP(font_getstringsize)
|
|||
int fontnumber = luaL_checkint(L, 2);
|
||||
int w, h;
|
||||
|
||||
if (fontnumber == FONT_UI)
|
||||
fontnumber = rb->global_status->font_id[SCREEN_MAIN];
|
||||
else
|
||||
fontnumber = FONT_SYSFIXED;
|
||||
|
||||
int result = rb->font_getstringsize(str, &w, &h, fontnumber);
|
||||
lua_pushinteger(L, result);
|
||||
lua_pushinteger(L, w);
|
||||
|
|
|
@ -470,7 +470,7 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
rb->splash(HZ*2, " Play .MID file ");
|
||||
return PLUGIN_OK;
|
||||
}
|
||||
rb->lcd_setfont(0);
|
||||
rb->lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
#if defined(HAVE_ADJUSTABLE_CPU_FREQ)
|
||||
rb->cpu_boost(true);
|
||||
|
|
|
@ -823,7 +823,7 @@ int playfile(char* filename)
|
|||
retval = menureturn;
|
||||
}
|
||||
}
|
||||
rb->lcd_setfont(0);
|
||||
rb->lcd_setfont(FONT_SYSFIXED);
|
||||
screenupdated = false;
|
||||
break;
|
||||
|
||||
|
@ -877,7 +877,7 @@ enum plugin_status plugin_start(const void* parameter)
|
|||
return PLUGIN_OK;
|
||||
}
|
||||
|
||||
rb->lcd_setfont(0);
|
||||
rb->lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
rb->pcm_play_stop();
|
||||
#if INPUT_SRC_CAPS != 0
|
||||
|
|
|
@ -125,7 +125,7 @@ int do_user_menu(void) {
|
|||
}
|
||||
}
|
||||
|
||||
rb->lcd_setfont(0); /* Reset the font */
|
||||
rb->lcd_setfont(FONT_SYSFIXED); /* Reset the font */
|
||||
rb->lcd_clear_display(); /* Clear display for screen size changes */
|
||||
|
||||
/* Keep the RTC in sync */
|
||||
|
|
|
@ -409,7 +409,7 @@ static int gnuboy_main(const char *rom)
|
|||
/* this is the plugin entry point */
|
||||
enum plugin_status plugin_start(const void* parameter)
|
||||
{
|
||||
rb->lcd_setfont(0);
|
||||
rb->lcd_setfont(FONT_SYSFIXED);
|
||||
|
||||
rb->lcd_clear_display();
|
||||
|
||||
|
|
|
@ -1016,7 +1016,6 @@ static bool browse_fonts( char *dst, int dst_size )
|
|||
size_t siz;
|
||||
reset_font = true;
|
||||
rb->snprintf( bbuf, MAX_PATH, FONT_DIR "/%s", e->name );
|
||||
rb->font_load(NULL, bbuf );
|
||||
rb->font_getstringsize( e->name, &fw, &fh, FONT_UI );
|
||||
if( fw > LCD_WIDTH ) fw = LCD_WIDTH;
|
||||
siz = (sizeof(struct font_preview) + fw*fh*FB_DATA_SZ+3) & ~3;
|
||||
|
@ -1083,7 +1082,7 @@ static bool browse_fonts( char *dst, int dst_size )
|
|||
li = tree->filesindir-1;
|
||||
if( reset_font )
|
||||
{
|
||||
rb->font_load(NULL, bbuf_s );
|
||||
// fixme rb->font_load(NULL, bbuf_s );
|
||||
reset_font = false;
|
||||
}
|
||||
if( lvi-fvi+1 < tree->filesindir )
|
||||
|
@ -1636,6 +1635,7 @@ static void show_grid( bool update )
|
|||
static void draw_text( int x, int y )
|
||||
{
|
||||
int selected = 0;
|
||||
int current_font_id = rb->global_status->font_id[SCREEN_MAIN];
|
||||
buffer->text.text[0] = '\0';
|
||||
buffer->text.font[0] = '\0';
|
||||
while( 1 )
|
||||
|
@ -1648,9 +1648,12 @@ static void draw_text( int x, int y )
|
|||
break;
|
||||
|
||||
case TEXT_MENU_FONT:
|
||||
if (current_font_id != rb->global_status->font_id[SCREEN_MAIN])
|
||||
rb->font_unload(current_font_id);
|
||||
if(browse_fonts( buffer->text.font, MAX_PATH ) )
|
||||
{
|
||||
rb->font_load(NULL, buffer->text.font );
|
||||
current_font_id = rb->font_load(buffer->text.font );
|
||||
rb->lcd_setfont(current_font_id);
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1704,7 +1707,9 @@ static void draw_text( int x, int y )
|
|||
rb->snprintf( buffer->text.font, MAX_PATH,
|
||||
FONT_DIR "/%s.fnt",
|
||||
rb->global_settings->font_file );
|
||||
rb->font_load(NULL, buffer->text.font );
|
||||
if (current_font_id != rb->global_status->font_id[SCREEN_MAIN])
|
||||
rb->font_unload(current_font_id);
|
||||
rb->lcd_setfont(FONT_UI);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -255,7 +255,7 @@ void tv_set_layout(bool show_scrollbar)
|
|||
int scrollbar_height = (show_scrollbar && preferences->horizontal_scrollbar)?
|
||||
TV_SCROLLBAR_HEIGHT + 1 : 0;
|
||||
|
||||
row_height = preferences->font->height;
|
||||
row_height = rb->font_get(preferences->font_id)->height;
|
||||
|
||||
header.x = 0;
|
||||
header.y = 0;
|
||||
|
@ -282,6 +282,7 @@ void tv_set_layout(bool show_scrollbar)
|
|||
vp_text.y += vertical_scrollbar.y;
|
||||
vp_text.width = horizontal_scrollbar.w;
|
||||
vp_text.height = vertical_scrollbar.h;
|
||||
vp_text.font = preferences->font_id;
|
||||
#else
|
||||
(void) show_scrollbar;
|
||||
|
||||
|
@ -334,16 +335,20 @@ static void tv_change_viewport(void)
|
|||
static bool tv_set_font(const unsigned char *font)
|
||||
{
|
||||
unsigned char path[MAX_PATH];
|
||||
|
||||
if (font != NULL && *font != '\0')
|
||||
{
|
||||
rb->snprintf(path, MAX_PATH, "%s/%s.fnt", FONT_DIR, font);
|
||||
if (rb->font_load(NULL, path) < 0)
|
||||
if (preferences->font_id >= 0 &&
|
||||
(preferences->font_id != rb->global_status->font_id[SCREEN_MAIN]))
|
||||
rb->font_unload(preferences->font_id);
|
||||
tv_change_fontid(rb->font_load(path));
|
||||
if (preferences->font_id < 0)
|
||||
{
|
||||
rb->splash(HZ/2, "font load failed");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
vp_text.font = preferences->font_id;
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
@ -375,7 +380,7 @@ static int tv_change_preferences(const struct tv_preferences *oldp)
|
|||
|
||||
return (tv_set_preferences(&new_prefs))? TV_CALLBACK_STOP : TV_CALLBACK_ERROR;
|
||||
}
|
||||
col_width = 2 * rb->font_get_width(preferences->font, ' ');
|
||||
col_width = 2 * rb->font_get_width(rb->font_get(preferences->font_id), ' ');
|
||||
font_changing = false;
|
||||
}
|
||||
#else
|
||||
|
@ -402,9 +407,10 @@ void tv_finalize_display(void)
|
|||
{
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
/* restore font */
|
||||
if (rb->strcmp(rb->global_settings->font_file, preferences->font_name))
|
||||
if (preferences->font_id >= 0 &&
|
||||
(preferences->font_id != rb->global_status->font_id[SCREEN_MAIN]))
|
||||
{
|
||||
tv_set_font(rb->global_settings->font_file);
|
||||
rb->font_unload(preferences->font_id);
|
||||
}
|
||||
|
||||
/* undo viewport */
|
||||
|
|
|
@ -114,7 +114,7 @@ void tv_set_default_preferences(struct tv_preferences *p)
|
|||
p->footer_mode = true;
|
||||
p->statusbar = true;
|
||||
rb->strlcpy(p->font_name, rb->global_settings->font_file, MAX_PATH);
|
||||
p->font = rb->font_get(FONT_UI);
|
||||
p->font_id = rb->global_status->font_id[SCREEN_MAIN];
|
||||
#else
|
||||
p->header_mode = false;
|
||||
p->footer_mode = false;
|
||||
|
@ -133,3 +133,11 @@ void tv_add_preferences_change_listner(int (*listner)(const struct tv_preference
|
|||
if (listner_count < TV_MAX_LISTNERS)
|
||||
listners[listner_count++] = listner;
|
||||
}
|
||||
|
||||
void tv_change_fontid(int id)
|
||||
{
|
||||
(void)id;
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
prefs.font_id = id;
|
||||
#endif
|
||||
}
|
||||
|
|
|
@ -95,7 +95,7 @@ struct tv_preferences {
|
|||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
unsigned char font_name[MAX_PATH];
|
||||
struct font *font;
|
||||
int font_id;
|
||||
#endif
|
||||
unsigned char file_name[MAX_PATH];
|
||||
};
|
||||
|
@ -151,4 +151,6 @@ void tv_set_default_preferences(struct tv_preferences *p);
|
|||
*/
|
||||
void tv_add_preferences_change_listner(int (*listner)(const struct tv_preferences *oldp));
|
||||
|
||||
|
||||
void tv_change_fontid(int id);
|
||||
#endif
|
||||
|
|
|
@ -218,7 +218,7 @@ static bool tv_read_preferences(int pfd, int version, struct tv_preferences *pre
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
rb->strlcpy(prefs->font_name, buf + read_size - MAX_PATH, MAX_PATH);
|
||||
|
||||
prefs->font = rb->font_get(FONT_UI);
|
||||
prefs->font_id = rb->global_status->font_id[SCREEN_MAIN];
|
||||
#endif
|
||||
|
||||
return true;
|
||||
|
|
|
@ -95,7 +95,7 @@ static int tv_glyph_width(int ch)
|
|||
if (rb->is_diacritic(ch, NULL))
|
||||
return 0;
|
||||
|
||||
return rb->font_get_width(preferences->font, ch);
|
||||
return rb->font_get_width(rb->font_get(preferences->font_id), ch);
|
||||
#else
|
||||
return 1;
|
||||
#endif
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
*
|
||||
****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "string-extra.h"
|
||||
#include "system.h"
|
||||
#include "albumart.h"
|
||||
|
|
|
@ -67,6 +67,15 @@ static int screen_helper_getnblines(void)
|
|||
return height / screens[0].getcharheight();
|
||||
}
|
||||
|
||||
void screen_helper_setfont(int font)
|
||||
{
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
if (font == FONT_UI)
|
||||
font = global_status.font_id[SCREEN_MAIN];
|
||||
lcd_setfont(font);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if NB_SCREENS == 2
|
||||
static int screen_helper_remote_getcharwidth(void)
|
||||
{
|
||||
|
@ -99,6 +108,13 @@ static int screen_helper_remote_getnblines(void)
|
|||
#endif
|
||||
return height / screens[1].getcharheight();
|
||||
}
|
||||
|
||||
void screen_helper_remote_setfont(int font)
|
||||
{
|
||||
if (font == FONT_UI)
|
||||
font = global_status.font_id[SCREEN_REMOTE];
|
||||
lcd_remote_setfont(font);
|
||||
}
|
||||
#endif
|
||||
|
||||
struct screen screens[NB_SCREENS] =
|
||||
|
@ -129,7 +145,7 @@ struct screen screens[NB_SCREENS] =
|
|||
.getheight=&lcd_getheight,
|
||||
.getstringsize=&lcd_getstringsize,
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
.setfont=&lcd_setfont,
|
||||
.setfont=screen_helper_setfont,
|
||||
.getfont=&lcd_getfont,
|
||||
.mono_bitmap=&lcd_mono_bitmap,
|
||||
.mono_bitmap_part=&lcd_mono_bitmap_part,
|
||||
|
@ -229,7 +245,7 @@ struct screen screens[NB_SCREENS] =
|
|||
.getheight=&lcd_remote_getheight,
|
||||
.getstringsize=&lcd_remote_getstringsize,
|
||||
#if 1 /* all remote LCDs are bitmapped so far */
|
||||
.setfont=&lcd_remote_setfont,
|
||||
.setfont=screen_helper_setfont,
|
||||
.getfont=&lcd_remote_getfont,
|
||||
.mono_bitmap=&lcd_remote_mono_bitmap,
|
||||
.mono_bitmap_part=&lcd_remote_mono_bitmap_part,
|
||||
|
|
|
@ -28,9 +28,11 @@
|
|||
|
||||
#if defined(HAVE_REMOTE_LCD) && !defined (ROCKBOX_HAS_LOGF)
|
||||
#define NB_SCREENS 2
|
||||
void screen_helper_remote_setfont(int font);
|
||||
#else
|
||||
#define NB_SCREENS 1
|
||||
#endif
|
||||
void screen_helper_setfont(int font);
|
||||
|
||||
#if NB_SCREENS == 1
|
||||
#define FOR_NB_SCREENS(i) i = 0;
|
||||
|
|
|
@ -876,30 +876,38 @@ void settings_apply(bool read_disk)
|
|||
/* fonts need to be loaded before the WPS */
|
||||
if (global_settings.font_file[0]
|
||||
&& global_settings.font_file[0] != '-') {
|
||||
const char* loaded_font = font_filename(global_status.font_id[SCREEN_MAIN]);
|
||||
|
||||
snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
|
||||
global_settings.font_file);
|
||||
if (!loaded_font || strcmp(loaded_font, buf))
|
||||
{
|
||||
CHART2(">font_load ", global_settings.font_file);
|
||||
rc = font_load(NULL, buf);
|
||||
if (global_status.font_id[SCREEN_MAIN] >= 0)
|
||||
font_unload(global_status.font_id[SCREEN_MAIN]);
|
||||
rc = font_load(buf);
|
||||
CHART2("<font_load ", global_settings.font_file);
|
||||
if (rc < 0)
|
||||
font_reset(NULL);
|
||||
global_status.font_id[SCREEN_MAIN] = rc;
|
||||
lcd_setfont(rc);
|
||||
}
|
||||
}
|
||||
else
|
||||
font_reset(NULL);
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
if ( global_settings.remote_font_file[0]
|
||||
&& global_settings.remote_font_file[0] != '-') {
|
||||
const char* loaded_font = font_filename(global_status.font_id[SCREEN_REMOTE]);
|
||||
snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
|
||||
global_settings.remote_font_file);
|
||||
if (!loaded_font || strcmp(loaded_font, buf))
|
||||
{
|
||||
CHART2(">font_load_remoteui ", global_settings.remote_font_file);
|
||||
rc = font_load_remoteui(buf);
|
||||
if (global_status.font_id[SCREEN_REMOTE] >= 0)
|
||||
font_unload(global_status.font_id[SCREEN_REMOTE]);
|
||||
rc = font_load(buf);
|
||||
CHART2("<font_load_remoteui ", global_settings.remote_font_file);
|
||||
if (rc < 0)
|
||||
font_load_remoteui(NULL);
|
||||
global_status.font_id[SCREEN_REMOTE] = rc;
|
||||
lcd_remote_setfont(rc);
|
||||
}
|
||||
}
|
||||
else
|
||||
font_load_remoteui(NULL);
|
||||
#endif
|
||||
if ( global_settings.kbd_file[0]
|
||||
&& global_settings.kbd_file[0] != '-') {
|
||||
|
@ -1070,6 +1078,16 @@ void settings_reset(void)
|
|||
#if defined (HAVE_RECORDING) && CONFIG_CODEC == SWCODEC
|
||||
enc_global_settings_reset();
|
||||
#endif
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
FOR_NB_SCREENS(i)
|
||||
{
|
||||
if (global_status.font_id[i] > FONT_SYSFIXED)
|
||||
{
|
||||
font_unload(global_status.font_id[i]);
|
||||
global_status.font_id[i] = FONT_SYSFIXED;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/** Changing setting values **/
|
||||
|
|
|
@ -278,6 +278,9 @@ struct system_status
|
|||
signed char last_screen;
|
||||
int viewer_icon_count;
|
||||
int last_volume_change; /* tick the last volume change happened. skins use this */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
int font_id[NB_SCREENS]; /* font id of the settings font for each screen */
|
||||
#endif
|
||||
};
|
||||
|
||||
struct user_settings
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
#define _FONT_H
|
||||
|
||||
#include "inttypes.h"
|
||||
#include "stdbool.h"
|
||||
|
||||
/*
|
||||
* Incore font and image definitions
|
||||
|
@ -46,18 +47,14 @@
|
|||
* Fonts are specified in firmware/font.c.
|
||||
*/
|
||||
enum {
|
||||
FONT_SYSFIXED, /* system fixed pitch font*/
|
||||
FONT_UI, /* system porportional font*/
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
FONT_UI_REMOTE, /* UI font for remote LCD */
|
||||
#endif
|
||||
SYSTEMFONTCOUNT, /* Number of fonts reserved for the system and ui */
|
||||
FONT_FIRSTUSERFONT = 2
|
||||
FONT_SYSFIXED = -1, /* system fixed pitch font*/
|
||||
FONT_FIRSTUSERFONT = 0, /* first id for the user fonts */
|
||||
};
|
||||
#define MAXUSERFONTS 8
|
||||
|
||||
/* SYSFONT, FONT_UI, FONT_UI_REMOTE + MAXUSERFONTS fonts in skins */
|
||||
#define MAXFONTS (SYSTEMFONTCOUNT + MAXUSERFONTS)
|
||||
#define MAXFONTS (FONT_FIRSTUSERFONT + MAXUSERFONTS)
|
||||
#define FONT_UI MAXFONTS
|
||||
|
||||
/*
|
||||
* .fnt loadable font file format definition
|
||||
|
@ -117,17 +114,13 @@ struct font {
|
|||
|
||||
/* font routines*/
|
||||
void font_init(void) INIT_ATTR;
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
/* Load a font into the special remote ui font slot */
|
||||
int font_load_remoteui(const char* path);
|
||||
#endif
|
||||
int font_load(struct font* pf, const char *path);
|
||||
const char* font_filename(int font_id);
|
||||
int font_load(const char *path);
|
||||
int font_glyphs_to_bufsize(const char *path, int glyphs);
|
||||
void font_unload(int font_id);
|
||||
|
||||
struct font* font_get(int font);
|
||||
|
||||
void font_reset(struct font *pf);
|
||||
int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber);
|
||||
int font_get_width(struct font* ft, unsigned short ch);
|
||||
const unsigned char * font_get_bits(struct font* ft, unsigned short ch);
|
||||
|
|
280
firmware/font.c
280
firmware/font.c
|
@ -34,6 +34,7 @@
|
|||
#include "system.h"
|
||||
#include "font.h"
|
||||
#include "file.h"
|
||||
#include "core_alloc.h"
|
||||
#include "debug.h"
|
||||
#include "panic.h"
|
||||
#include "rbunicode.h"
|
||||
|
@ -74,19 +75,58 @@ extern struct font sysfont;
|
|||
|
||||
#ifndef BOOTLOADER
|
||||
|
||||
/* structure filled in by font_load */
|
||||
static struct font font_ui;
|
||||
/* static buffer allocation structures */
|
||||
static unsigned char main_buf[MAX_FONT_SIZE] CACHEALIGN_ATTR;
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
#define REMOTE_FONT_SIZE 10000
|
||||
static struct font remote_font_ui;
|
||||
static unsigned char remote_buf[REMOTE_FONT_SIZE] CACHEALIGN_ATTR;
|
||||
#endif
|
||||
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];
|
||||
};
|
||||
static int buflib_allocations[MAXFONTS];
|
||||
static int handle_for_glyphcache;
|
||||
|
||||
/* system font table, in order of FONT_xxx definition */
|
||||
static struct font* sysfonts[MAXFONTS] = { &sysfont, &font_ui, NULL};
|
||||
static int buflibmove_callback(int handle, void* current, void* new)
|
||||
{
|
||||
(void)handle;
|
||||
struct buflib_alloc_data *alloc = (struct buflib_alloc_data*)current;
|
||||
size_t diff = new - current;
|
||||
|
||||
if (alloc->handle_locked)
|
||||
return BUFLIB_CB_CANNOT_MOVE;
|
||||
|
||||
alloc->font.bits += diff;
|
||||
alloc->font.offset += diff;
|
||||
if (alloc->font.width)
|
||||
alloc->font.width += diff;
|
||||
|
||||
alloc->font.buffer_start += diff;
|
||||
alloc->font.buffer_end += diff;
|
||||
alloc->font.buffer_position += diff;
|
||||
|
||||
alloc->font.cache._index += diff;
|
||||
|
||||
return BUFLIB_CB_OK;
|
||||
}
|
||||
static void lock_font_handle(int handle, bool lock)
|
||||
{
|
||||
struct buflib_alloc_data *alloc = core_get_data(handle);
|
||||
alloc->handle_locked = lock;
|
||||
}
|
||||
|
||||
static struct buflib_callbacks buflibops = {buflibmove_callback, NULL };
|
||||
|
||||
static inline struct font *pf_from_handle(int handle)
|
||||
{
|
||||
struct buflib_alloc_data *alloc = core_get_data(handle);
|
||||
struct font *pf = &alloc->font;
|
||||
return pf;
|
||||
}
|
||||
|
||||
static inline unsigned char *buffer_from_handle(int handle)
|
||||
{
|
||||
struct buflib_alloc_data *alloc = core_get_data(handle);
|
||||
unsigned char* buffer = alloc->buffer;
|
||||
return buffer;
|
||||
}
|
||||
|
||||
/* Font cache structures */
|
||||
static void cache_create(struct font* pf);
|
||||
|
@ -95,13 +135,10 @@ static void glyph_cache_load(struct font* pf);
|
|||
|
||||
void font_init(void)
|
||||
{
|
||||
int i = SYSTEMFONTCOUNT;
|
||||
int i = 0;
|
||||
while (i<MAXFONTS)
|
||||
sysfonts[i++] = NULL;
|
||||
font_reset(NULL);
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
font_reset(&remote_font_ui);
|
||||
#endif
|
||||
buflib_allocations[i++] = -1;
|
||||
handle_for_glyphcache = -1;
|
||||
}
|
||||
|
||||
/* Check if we have x bytes left in the file buffer */
|
||||
|
@ -139,26 +176,6 @@ static int glyph_bytes( struct font *pf, int width )
|
|||
width * ((pf->height + 7) / 8);
|
||||
}
|
||||
|
||||
void font_reset(struct font *pf)
|
||||
{
|
||||
unsigned char* buffer = NULL;
|
||||
size_t buf_size = 0;
|
||||
if (pf == NULL)
|
||||
pf = &font_ui;
|
||||
else
|
||||
{
|
||||
buffer = pf->buffer_start;
|
||||
buf_size = pf->buffer_size;
|
||||
}
|
||||
memset(pf, 0, sizeof(struct font));
|
||||
pf->fd = -1;
|
||||
if (buffer)
|
||||
{
|
||||
pf->buffer_start = buffer;
|
||||
pf->buffer_size = buf_size;
|
||||
}
|
||||
}
|
||||
|
||||
static struct font* font_load_header(struct font *pf)
|
||||
{
|
||||
/* Check we have enough data */
|
||||
|
@ -320,18 +337,27 @@ static struct font* font_load_cached(struct font* pf)
|
|||
return pf;
|
||||
}
|
||||
|
||||
static bool internal_load_font(struct font* pf, const char *path,
|
||||
static void font_reset(int font_id)
|
||||
{
|
||||
struct font *pf = pf_from_handle(buflib_allocations[font_id]);
|
||||
// fixme
|
||||
memset(pf, 0, sizeof(struct font));
|
||||
pf->fd = -1;
|
||||
}
|
||||
|
||||
|
||||
static bool internal_load_font(int font_id, const char *path,
|
||||
char *buf, size_t buf_size)
|
||||
{
|
||||
int size;
|
||||
|
||||
struct font* pf = pf_from_handle(buflib_allocations[font_id]);
|
||||
/* save loaded glyphs */
|
||||
glyph_cache_save(pf);
|
||||
/* Close font file handle */
|
||||
if (pf->fd >= 0)
|
||||
close(pf->fd);
|
||||
|
||||
font_reset(pf);
|
||||
font_reset(font_id);
|
||||
|
||||
/* open and read entire font file*/
|
||||
pf->fd = open(path, O_RDONLY|O_BINARY);
|
||||
|
@ -393,80 +419,117 @@ static bool internal_load_font(struct font* pf, const char *path,
|
|||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
/* Load a font into the special remote ui font slot */
|
||||
int font_load_remoteui(const char* path)
|
||||
static int find_font_index(const char* path)
|
||||
{
|
||||
struct font* pf = &remote_font_ui;
|
||||
if (!path)
|
||||
int index = 0, handle;
|
||||
|
||||
while (index < MAXFONTS)
|
||||
{
|
||||
if (sysfonts[FONT_UI_REMOTE] && sysfonts[FONT_UI_REMOTE] != sysfonts[FONT_UI])
|
||||
font_unload(FONT_UI_REMOTE);
|
||||
sysfonts[FONT_UI_REMOTE] = NULL;
|
||||
return FONT_UI;
|
||||
handle = buflib_allocations[index];
|
||||
if (handle > 0 && !strcmp(core_get_name(handle), path))
|
||||
return index;
|
||||
index++;
|
||||
}
|
||||
if (!internal_load_font(pf, path, remote_buf, REMOTE_FONT_SIZE))
|
||||
{
|
||||
sysfonts[FONT_UI_REMOTE] = NULL;
|
||||
return -1;
|
||||
return FONT_SYSFIXED;
|
||||
}
|
||||
|
||||
sysfonts[FONT_UI_REMOTE] = pf;
|
||||
return FONT_UI_REMOTE;
|
||||
static int alloc_and_init(int font_idx, const char* name)
|
||||
{
|
||||
int *phandle = &buflib_allocations[font_idx];
|
||||
int handle = *phandle;
|
||||
struct buflib_alloc_data *pdata;
|
||||
struct font *pf;
|
||||
if (handle > 0)
|
||||
return handle;
|
||||
*phandle = core_alloc_ex(name, sizeof(struct buflib_alloc_data), &buflibops);
|
||||
handle = *phandle;
|
||||
if (handle < 0)
|
||||
return handle;
|
||||
pdata = core_get_data(handle);
|
||||
pf = &pdata->font;
|
||||
font_reset(font_idx);
|
||||
pdata->handle_locked = false;
|
||||
pdata->refcount = 1;
|
||||
pf->buffer_position = pf->buffer_start = buffer_from_handle(handle);
|
||||
pf->buffer_size = MAX_FONT_SIZE;
|
||||
return handle;
|
||||
}
|
||||
|
||||
const char* font_filename(int font_id)
|
||||
{
|
||||
int handle = buflib_allocations[font_id];
|
||||
if (handle > 0)
|
||||
return core_get_name(handle);
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* read and load font into incore font structure,
|
||||
* returns the font number on success, -1 on failure */
|
||||
int font_load(struct font* pf, const char *path)
|
||||
int font_load(const char *path)
|
||||
{
|
||||
int font_id = -1;
|
||||
int font_id = find_font_index(path);
|
||||
char *buffer;
|
||||
size_t buffer_size;
|
||||
if (pf == NULL)
|
||||
int *handle;
|
||||
|
||||
if (font_id > FONT_SYSFIXED)
|
||||
{
|
||||
pf = &font_ui;
|
||||
font_id = FONT_UI;
|
||||
/* already loaded, no need to reload */
|
||||
struct buflib_alloc_data *pd = core_get_data(buflib_allocations[font_id]);
|
||||
pd->refcount++;
|
||||
//printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount);
|
||||
return font_id;
|
||||
}
|
||||
else
|
||||
|
||||
for (font_id = FONT_FIRSTUSERFONT; font_id < MAXFONTS; font_id++)
|
||||
{
|
||||
for (font_id = SYSTEMFONTCOUNT; font_id < MAXFONTS; font_id++)
|
||||
handle = &buflib_allocations[font_id];
|
||||
if (*handle < 0)
|
||||
{
|
||||
if (sysfonts[font_id] == NULL)
|
||||
break;
|
||||
}
|
||||
if (font_id == MAXFONTS)
|
||||
return -1; /* too many fonts */
|
||||
}
|
||||
|
||||
if (font_id == FONT_UI)
|
||||
{
|
||||
/* currently, font loading replaces earlier font allocation*/
|
||||
buffer = (unsigned char *)(((intptr_t)main_buf + 3) & ~3);
|
||||
/* make sure above doesn't exceed */
|
||||
buffer_size = MAX_FONT_SIZE-3;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = pf->buffer_start;
|
||||
buffer_size = pf->buffer_size;
|
||||
}
|
||||
|
||||
if (!internal_load_font(pf, path, buffer, buffer_size))
|
||||
handle = &buflib_allocations[font_id];
|
||||
*handle = alloc_and_init(font_id, path);
|
||||
if (*handle < 0)
|
||||
return -1;
|
||||
|
||||
sysfonts[font_id] = pf;
|
||||
if (handle_for_glyphcache < 0)
|
||||
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))
|
||||
{
|
||||
lock_font_handle(*handle, false);
|
||||
core_free(*handle);
|
||||
*handle = -1;
|
||||
return -1;
|
||||
}
|
||||
|
||||
lock_font_handle(*handle, false);
|
||||
//printf("%s -> [%d] -> %d\n", path, font_id, *handle);
|
||||
return font_id; /* success!*/
|
||||
}
|
||||
|
||||
void font_unload(int font_id)
|
||||
{
|
||||
struct font* pf = sysfonts[font_id];
|
||||
if (font_id >= SYSTEMFONTCOUNT && pf)
|
||||
int *handle = &buflib_allocations[font_id];
|
||||
struct buflib_alloc_data *pdata = core_get_data(*handle);
|
||||
struct font* pf = &pdata->font;
|
||||
pdata->refcount--;
|
||||
if (pdata->refcount < 1)
|
||||
{
|
||||
if (pf->fd >= 0)
|
||||
//printf("freeing id: %d %s\n", font_id, core_get_name(*handle));
|
||||
if (pf && pf->fd >= 0)
|
||||
close(pf->fd);
|
||||
sysfonts[font_id] = NULL;
|
||||
if (*handle > 0)
|
||||
core_free(*handle);
|
||||
if (handle_for_glyphcache == *handle)
|
||||
handle_for_glyphcache = -1; // should find the next available handle
|
||||
*handle = -1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -478,16 +541,37 @@ void font_unload(int font_id)
|
|||
struct font* font_get(int font)
|
||||
{
|
||||
struct font* pf;
|
||||
if (font == FONT_UI)
|
||||
font = MAXFONTS-1;
|
||||
if (font <= FONT_SYSFIXED)
|
||||
return &sysfont;
|
||||
|
||||
while (1) {
|
||||
pf = sysfonts[font];
|
||||
struct buflib_alloc_data *alloc = core_get_data(buflib_allocations[font]);
|
||||
pf = &alloc->font;
|
||||
if (pf && pf->height)
|
||||
return pf;
|
||||
if (--font < 0)
|
||||
panicf("No font!");
|
||||
return &sysfont;
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
*/
|
||||
|
@ -495,9 +579,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];
|
||||
|
||||
if (handle > 0)
|
||||
lock_font_handle(handle, true);
|
||||
if (pf->file_width_offset)
|
||||
{
|
||||
int width_offset = pf->file_width_offset + char_code;
|
||||
|
@ -531,6 +618,9 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
|
|||
lseek(pf->fd, file_offset, SEEK_SET);
|
||||
int src_bytes = glyph_bytes(pf, p->width);
|
||||
read(pf->fd, p->bitmap, src_bytes);
|
||||
|
||||
if (handle > 0)
|
||||
lock_font_handle(handle, false);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -594,7 +684,8 @@ static int cache_fd;
|
|||
static void glyph_file_write(void* data)
|
||||
{
|
||||
struct font_cache_entry* p = data;
|
||||
struct font* pf = &font_ui;
|
||||
int handle = handle_for_glyphcache;
|
||||
struct font* pf = pf_from_handle(handle);
|
||||
unsigned short ch;
|
||||
unsigned char tmp[2];
|
||||
|
||||
|
@ -617,9 +708,9 @@ static void glyph_file_write(void* data)
|
|||
/* save the char codes of the loaded glyphs to a file */
|
||||
void glyph_cache_save(struct font* pf)
|
||||
{
|
||||
if (!pf)
|
||||
pf = &font_ui;
|
||||
if (pf->fd >= 0 && pf == &font_ui)
|
||||
if (pf != pf_from_handle(handle_for_glyphcache))
|
||||
return;
|
||||
if (pf->fd >= 0)
|
||||
{
|
||||
cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666);
|
||||
if (cache_fd < 0)
|
||||
|
@ -675,9 +766,10 @@ static int ushortcmp(const void *a, const void *b)
|
|||
}
|
||||
static void glyph_cache_load(struct font* pf)
|
||||
{
|
||||
|
||||
if (handle_for_glyphcache <= 0)
|
||||
return;
|
||||
#define MAX_SORT 256
|
||||
if (pf->fd >= 0) {
|
||||
if (pf->fd >= 0 && pf == pf_from_handle(handle_for_glyphcache)) {
|
||||
int fd;
|
||||
int i, size;
|
||||
unsigned char tmp[2];
|
||||
|
|
|
@ -33,4 +33,11 @@ static inline void* core_get_data(int handle)
|
|||
extern struct buflib_context core_ctx;
|
||||
return buflib_get_data(&core_ctx, handle);
|
||||
}
|
||||
|
||||
static inline const char* core_get_name(int handle)
|
||||
{
|
||||
extern struct buflib_context core_ctx;
|
||||
return buflib_get_name(&core_ctx, handle);
|
||||
}
|
||||
|
||||
#endif /* __CORE_ALLOC_H__ */
|
||||
|
|
Loading…
Reference in a new issue