FS#10984 - multifont! 2 major additions:
1) seperate UI font for the remote and main displays 2) allow individual skins to load additional fonts for use in the skin (Uo to 7 extra in this first version) see CustomWPS for info on how to load a font in the skins. Code should always use FONT_UI+screen_number to get the correct user font git-svn-id: svn://svn.rockbox.org/rockbox/trunk@24644 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
ed21ab1c8c
commit
1c2aa35371
|
@ -90,6 +90,9 @@ gui/viewport.c
|
|||
gui/skin_engine/skin_buffer.c
|
||||
gui/skin_engine/wps_debug.c
|
||||
gui/skin_engine/skin_display.c
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
gui/skin_engine/skin_fonts.c
|
||||
#endif
|
||||
gui/skin_engine/skin_parser.c
|
||||
gui/skin_engine/skin_tokens.c
|
||||
|
||||
|
|
|
@ -379,6 +379,32 @@ int ft_load(struct tree_context* c, const char* tempdir)
|
|||
|
||||
return 0;
|
||||
}
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
static void ft_load_font(char *file)
|
||||
{
|
||||
#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);
|
||||
set_file(file, (char *)global_settings.font_file, MAX_FILENAME);
|
||||
break;
|
||||
case 1: /* remote */
|
||||
splash(0, ID2P(LANG_WAIT));
|
||||
font_load_remoteui(file);
|
||||
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
|
||||
}
|
||||
#endif
|
||||
|
||||
int ft_enter(struct tree_context* c)
|
||||
{
|
||||
|
@ -547,9 +573,7 @@ int ft_enter(struct tree_context* c)
|
|||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
case FILE_ATTR_FONT:
|
||||
splash(0, ID2P(LANG_WAIT));
|
||||
font_load(buf);
|
||||
set_file(buf, (char *)global_settings.font_file, MAX_FILENAME);
|
||||
ft_load_font(buf);
|
||||
break;
|
||||
|
||||
case FILE_ATTR_KBD:
|
||||
|
|
|
@ -0,0 +1,139 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: skin_tokens.c 24526 2010-02-05 23:58:53Z jdgordon $
|
||||
*
|
||||
* 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"
|
||||
#define FONT_SIZE 10000
|
||||
|
||||
|
||||
static struct skin_font {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* load a font into the skin buffer. return the font id. */
|
||||
int skin_font_load(char* font_name)
|
||||
{
|
||||
int i;
|
||||
struct font *pf;
|
||||
struct skin_font *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
|
||||
for(i=0;i<MAXUSERFONTS;i++)
|
||||
{
|
||||
if (font_table[i].font_id >= 0 && !strcmp(font_table[i].name, font_name))
|
||||
{
|
||||
font_table[i].ref_count++;
|
||||
return font_table[i].font_id;
|
||||
}
|
||||
else if (!font && font_table[i].font_id == -1)
|
||||
{
|
||||
font = &font_table[i];
|
||||
}
|
||||
}
|
||||
if (!font)
|
||||
return -1; /* too many fonts loaded */
|
||||
|
||||
pf = &font->font;
|
||||
if (!font->buffer)
|
||||
{
|
||||
pf->buffer_start = skin_buffer_alloc(FONT_SIZE);
|
||||
if (!pf->buffer_start)
|
||||
return -1;
|
||||
font->buffer = pf->buffer_start;
|
||||
}
|
||||
else
|
||||
{
|
||||
pf->buffer_start = font->buffer;
|
||||
}
|
||||
pf->buffer_size = FONT_SIZE;
|
||||
|
||||
snprintf(filename, MAX_PATH, FONT_DIR "/%s.fnt", font_name);
|
||||
strcpy(font->name, font_name);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/***************************************************************************
|
||||
* __________ __ ___.
|
||||
* Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
||||
* Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
||||
* Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
||||
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
||||
* \/ \/ \/ \/ \/
|
||||
* $Id: skin_tokens.c 24526 2010-02-05 23:58:53Z jdgordon $
|
||||
*
|
||||
* 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"
|
||||
|
||||
#ifndef _SKINFONTS_H_
|
||||
#define _SKINFONTS_H_
|
||||
|
||||
#define MAXUSERFONTS (MAXFONTS - SYSTEMFONTCOUNT)
|
||||
|
||||
void skin_font_init(void);
|
||||
|
||||
/* load a font into the skin buffer. return the font id. */
|
||||
int skin_font_load(char* font_name);
|
||||
|
||||
/* 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
|
|
@ -52,6 +52,7 @@
|
|||
#include "skin_engine.h"
|
||||
#include "settings.h"
|
||||
#include "settings_list.h"
|
||||
#include "skin_fonts.h"
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
#include "bmp.h"
|
||||
|
@ -157,6 +158,8 @@ static int parse_image_display(const char *wps_bufptr,
|
|||
struct wps_token *token, struct wps_data *wps_data);
|
||||
static int parse_image_load(const char *wps_bufptr,
|
||||
struct wps_token *token, struct wps_data *wps_data);
|
||||
static int parse_font_load(const char *wps_bufptr,
|
||||
struct wps_token *token, struct wps_data *wps_data);
|
||||
#endif /*HAVE_LCD_BITMAP */
|
||||
#if (LCD_DEPTH > 1) || (defined(HAVE_REMOTE_LCD) && (LCD_REMOTE_DEPTH > 1))
|
||||
static int parse_image_special(const char *wps_bufptr,
|
||||
|
@ -353,6 +356,7 @@ static const struct wps_tag all_tags[] = {
|
|||
parse_image_display },
|
||||
|
||||
{ WPS_TOKEN_IMAGE_DISPLAY, "x", 0, parse_image_load },
|
||||
{ WPS_NO_TOKEN, "Fl", 0, parse_font_load },
|
||||
#ifdef HAVE_ALBUMART
|
||||
{ WPS_NO_TOKEN, "Cl", 0, parse_albumart_load },
|
||||
{ WPS_TOKEN_ALBUMART_DISPLAY, "C", WPS_REFRESH_STATIC, parse_albumart_display },
|
||||
|
@ -688,6 +692,39 @@ static int parse_image_load(const char *wps_bufptr,
|
|||
return skip_end_of_line(wps_bufptr);
|
||||
}
|
||||
|
||||
static int font_ids[MAXUSERFONTS];
|
||||
static int parse_font_load(const char *wps_bufptr,
|
||||
struct wps_token *token, struct wps_data *wps_data)
|
||||
{
|
||||
(void)wps_data; (void)token;
|
||||
const char *ptr = wps_bufptr;
|
||||
int id;
|
||||
char *filename, buf[MAX_PATH];
|
||||
|
||||
if (*ptr != '|')
|
||||
return WPS_ERROR_INVALID_PARAM;
|
||||
|
||||
ptr++;
|
||||
|
||||
if (!(ptr = parse_list("ds", NULL, '|', ptr, &id, &filename)))
|
||||
return WPS_ERROR_INVALID_PARAM;
|
||||
|
||||
/* Check there is a terminating | */
|
||||
if (*ptr != '|')
|
||||
return WPS_ERROR_INVALID_PARAM;
|
||||
|
||||
if (id <= FONT_UI || id >= MAXFONTS-1)
|
||||
return WPS_ERROR_INVALID_PARAM;
|
||||
id -= SYSTEMFONTCOUNT;
|
||||
|
||||
memcpy(buf, filename, ptr-filename);
|
||||
buf[ptr-filename] = '\0';
|
||||
font_ids[id] = skin_font_load(buf);
|
||||
|
||||
return font_ids[id] >= 0 ? skip_end_of_line(wps_bufptr) : WPS_ERROR_INVALID_PARAM;
|
||||
}
|
||||
|
||||
|
||||
static int parse_viewport_display(const char *wps_bufptr,
|
||||
struct wps_token *token,
|
||||
struct wps_data *wps_data)
|
||||
|
@ -890,7 +927,8 @@ static int parse_viewport(const char *wps_bufptr,
|
|||
else
|
||||
vp->flags &= ~VP_FLAG_ALIGN_RIGHT; /* ignore right-to-left languages */
|
||||
|
||||
|
||||
if (vp->font >= SYSTEMFONTCOUNT)
|
||||
vp->font = font_ids[vp->font - SYSTEMFONTCOUNT];
|
||||
|
||||
struct skin_token_list *list = new_skin_token_list_item(NULL, skin_vp);
|
||||
if (!list)
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
#include "statusbar.h"
|
||||
#include "statusbar-skinned.h"
|
||||
#include "debug.h"
|
||||
#include "font.h"
|
||||
|
||||
|
||||
/* currently only one wps_state is needed */
|
||||
|
@ -183,7 +184,8 @@ void sb_create_from_settings(enum screen_type screen)
|
|||
default:
|
||||
height = screens[screen].lcdheight;
|
||||
}
|
||||
len = snprintf(ptr, remaining, "%%ax%%Vi|0|%d|-|%d|1|-|-|\n", y, height);
|
||||
len = snprintf(ptr, remaining, "%%ax%%Vi|0|%d|-|%d|%d|-|-|\n",
|
||||
y, height, FONT_UI + screen);
|
||||
}
|
||||
sb_skin_data_load(screen, buf, false);
|
||||
}
|
||||
|
|
|
@ -315,7 +315,7 @@ void viewport_set_fullscreen(struct viewport *vp,
|
|||
#ifndef __PCTOOL__
|
||||
set_default_align_flags(vp);
|
||||
#endif
|
||||
vp->font = FONT_UI; /* default to UI to discourage SYSFONT use */
|
||||
vp->font = FONT_UI + screen; /* default to UI to discourage SYSFONT use */
|
||||
vp->drawmode = DRMODE_SOLID;
|
||||
#if LCD_DEPTH > 1
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
|
@ -453,11 +453,15 @@ const char* viewport_parse_viewport(struct viewport *vp,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Default to using the user font if the font was an invalid number or '-'*/
|
||||
if (((vp->font != FONT_SYSFIXED) && (vp->font != FONT_UI))
|
||||
|| !LIST_VALUE_PARSED(set, PL_FONT)
|
||||
)
|
||||
vp->font = FONT_UI;
|
||||
/* Default to using the user font if the font was an invalid number or '-'
|
||||
* font 1 is *always* the UI font for the current screen
|
||||
* 2 is always the first extra font */
|
||||
if (!LIST_VALUE_PARSED(set, PL_FONT))
|
||||
vp->font = FONT_UI + screen;
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
else if (vp->font == FONT_UI && screen == SCREEN_REMOTE)
|
||||
vp->font = FONT_UI_REMOTE;
|
||||
#endif
|
||||
|
||||
/* Set the defaults for fields not user-specified */
|
||||
vp->drawmode = DRMODE_SOLID;
|
||||
|
|
|
@ -13315,3 +13315,37 @@
|
|||
lcd_bitmap: "Remote Base Skin"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
id: LANG_MAIN_SCREEN
|
||||
desc: in the main menu
|
||||
user: core
|
||||
<source>
|
||||
*:none
|
||||
remote: "Main Screen"
|
||||
</source>
|
||||
<dest>
|
||||
*:none
|
||||
remote: "Main Screen"
|
||||
</dest>
|
||||
<voice>
|
||||
*:none
|
||||
remote: "Main Screen"
|
||||
</voice>
|
||||
</phrase>
|
||||
<phrase>
|
||||
id: LANG_REMOTE_SCREEN
|
||||
desc: in the main menu
|
||||
user: core
|
||||
<source>
|
||||
*:none
|
||||
remote: "Remote Screen"
|
||||
</source>
|
||||
<dest>
|
||||
*:none
|
||||
remote: "Remote Screen"
|
||||
</dest>
|
||||
<voice>
|
||||
*:none
|
||||
remote: "Remote Screen"
|
||||
</voice>
|
||||
</phrase>
|
||||
|
|
|
@ -247,6 +247,10 @@ static const struct plugin_api rockbox_api = {
|
|||
lcd_remote_bitmap,
|
||||
#endif
|
||||
viewport_set_defaults,
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
viewportmanager_theme_enable,
|
||||
viewportmanager_theme_undo,
|
||||
#endif
|
||||
|
||||
/* list */
|
||||
gui_synclist_init,
|
||||
|
@ -292,6 +296,7 @@ static const struct plugin_api rockbox_api = {
|
|||
#endif /* HAVE_BUTTON_LIGHT */
|
||||
|
||||
/* file */
|
||||
open_utf8,
|
||||
#ifdef HAVE_PLUGIN_CHECK_OPEN_CLOSE
|
||||
(open_func)open_wrapper,
|
||||
close_wrapper,
|
||||
|
@ -325,6 +330,7 @@ static const struct plugin_api rockbox_api = {
|
|||
create_numbered_filename,
|
||||
file_exists,
|
||||
strip_extension,
|
||||
crc_32,
|
||||
|
||||
/* dir */
|
||||
opendir,
|
||||
|
@ -432,6 +438,7 @@ static const struct plugin_api rockbox_api = {
|
|||
atoi,
|
||||
strchr,
|
||||
strcat,
|
||||
strlcat,
|
||||
memchr,
|
||||
memcmp,
|
||||
strcasestr,
|
||||
|
@ -476,6 +483,7 @@ static const struct plugin_api rockbox_api = {
|
|||
pcm_get_peak_buffer,
|
||||
pcm_play_lock,
|
||||
pcm_play_unlock,
|
||||
pcmbuf_beep,
|
||||
#ifdef HAVE_RECORDING
|
||||
&rec_freq_sampr[0],
|
||||
pcm_init_recording,
|
||||
|
@ -588,6 +596,9 @@ static const struct plugin_api rockbox_api = {
|
|||
#endif
|
||||
|
||||
/* misc */
|
||||
#if !defined(SIMULATOR) || defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
&errno,
|
||||
#endif
|
||||
srand,
|
||||
rand,
|
||||
(qsort_func)qsort,
|
||||
|
@ -698,19 +709,6 @@ static const struct plugin_api rockbox_api = {
|
|||
appsversion,
|
||||
/* new stuff at the end, sort into place next time
|
||||
the API gets incompatible */
|
||||
#if (CONFIG_CODEC == SWCODEC)
|
||||
pcmbuf_beep,
|
||||
#endif
|
||||
crc_32,
|
||||
open_utf8,
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
viewportmanager_theme_enable,
|
||||
viewportmanager_theme_undo,
|
||||
#endif
|
||||
#if !defined(SIMULATOR) || defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
&errno,
|
||||
#endif
|
||||
strlcat,
|
||||
};
|
||||
|
||||
int plugin_load(const char* plugin, const void* parameter)
|
||||
|
|
|
@ -135,12 +135,12 @@ void* plugin_get_buffer(size_t *buffer_size);
|
|||
#define PLUGIN_MAGIC 0x526F634B /* RocK */
|
||||
|
||||
/* increase this every time the api struct changes */
|
||||
#define PLUGIN_API_VERSION 180
|
||||
#define PLUGIN_API_VERSION 181
|
||||
|
||||
/* update this to latest version if a change to the api struct breaks
|
||||
backwards compatibility (and please take the opportunity to sort in any
|
||||
new function which are "waiting" at the end of the function table) */
|
||||
#define PLUGIN_MIN_API_VERSION 180
|
||||
#define PLUGIN_MIN_API_VERSION 181
|
||||
|
||||
/* plugin return codes */
|
||||
enum plugin_status {
|
||||
|
@ -250,7 +250,7 @@ struct plugin_api {
|
|||
#endif
|
||||
unsigned short *(*bidi_l2v)( const unsigned char *str, int orientation );
|
||||
const unsigned char *(*font_get_bits)( struct font *pf, unsigned short char_code );
|
||||
struct font* (*font_load)(const char *path);
|
||||
int (*font_load)(struct font*, const char *path);
|
||||
struct font* (*font_get)(int font);
|
||||
int (*font_getstringsize)(const unsigned char *str, int *w, int *h,
|
||||
int fontnumber);
|
||||
|
@ -336,7 +336,12 @@ struct plugin_api {
|
|||
int width, int height);
|
||||
#endif
|
||||
void (*viewport_set_defaults)(struct viewport *vp,
|
||||
const enum screen_type screen);
|
||||
const enum screen_type screen);
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
void (*viewportmanager_theme_enable)(enum screen_type screen, bool enable,
|
||||
struct viewport *viewport);
|
||||
void (*viewportmanager_theme_undo)(enum screen_type screen, bool force_redraw);
|
||||
#endif
|
||||
/* list */
|
||||
void (*gui_synclist_init)(struct gui_synclist * lists,
|
||||
list_get_name callback_get_item_name, void * data,
|
||||
|
@ -390,6 +395,7 @@ struct plugin_api {
|
|||
#endif /* HAVE_BUTTON_LIGHT */
|
||||
|
||||
/* file */
|
||||
int (*open_utf8)(const char* pathname, int flags);
|
||||
int (*open)(const char* pathname, int flags);
|
||||
int (*close)(int fd);
|
||||
ssize_t (*read)(int fd, void* buf, size_t count);
|
||||
|
@ -416,6 +422,7 @@ struct plugin_api {
|
|||
int numberlen IF_CNFN_NUM_(, int *num));
|
||||
bool (*file_exists)(const char *file);
|
||||
char* (*strip_extension)(char* buffer, int buffer_size, const char *filename);
|
||||
unsigned (*crc_32)(const void *src, unsigned len, unsigned crc32);
|
||||
|
||||
|
||||
/* dir */
|
||||
|
@ -537,6 +544,7 @@ struct plugin_api {
|
|||
int (*atoi)(const char *str);
|
||||
char *(*strchr)(const char *s, int c);
|
||||
char *(*strcat)(char *s1, const char *s2);
|
||||
size_t (*strlcat)(char *dst, const char *src, size_t length);
|
||||
void *(*memchr)(const void *s1, int c, size_t n);
|
||||
int (*memcmp)(const void *s1, const void *s2, size_t n);
|
||||
char *(*strcasestr) (const char* phaystack, const char* pneedle);
|
||||
|
@ -583,6 +591,9 @@ struct plugin_api {
|
|||
const void* (*pcm_get_peak_buffer)(int *count);
|
||||
void (*pcm_play_lock)(void);
|
||||
void (*pcm_play_unlock)(void);
|
||||
void (*pcmbuf_beep)(unsigned int frequency,
|
||||
size_t duration,
|
||||
int amplitude);
|
||||
#ifdef HAVE_RECORDING
|
||||
const unsigned long *rec_freq_sampr;
|
||||
void (*pcm_init_recording)(void);
|
||||
|
@ -716,6 +727,9 @@ struct plugin_api {
|
|||
#endif
|
||||
|
||||
/* misc */
|
||||
#if !defined(SIMULATOR) || defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
int* __errno;
|
||||
#endif
|
||||
void (*srand)(unsigned int seed);
|
||||
int (*rand)(void);
|
||||
void (*qsort)(void *base, size_t nmemb, size_t size,
|
||||
|
@ -848,23 +862,6 @@ struct plugin_api {
|
|||
const char *appsversion;
|
||||
/* new stuff at the end, sort into place next time
|
||||
the API gets incompatible */
|
||||
|
||||
#if (CONFIG_CODEC == SWCODEC)
|
||||
void (*pcmbuf_beep)(unsigned int frequency,
|
||||
size_t duration,
|
||||
int amplitude);
|
||||
#endif
|
||||
unsigned (*crc_32)(const void *src, unsigned len, unsigned crc32);
|
||||
int (*open_utf8)(const char* pathname, int flags);
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
void (*viewportmanager_theme_enable)(enum screen_type screen, bool enable,
|
||||
struct viewport *viewport);
|
||||
void (*viewportmanager_theme_undo)(enum screen_type screen, bool force_redraw);
|
||||
#endif
|
||||
#if !defined(SIMULATOR) || defined(__MINGW32__) || defined(__CYGWIN__)
|
||||
int* __errno;
|
||||
#endif
|
||||
size_t (*strlcat)(char *dst, const char *src, size_t length);
|
||||
};
|
||||
|
||||
/* plugin header */
|
||||
|
|
|
@ -854,7 +854,7 @@ static bool browse_fonts( char *dst, int dst_size )
|
|||
continue;
|
||||
rb->snprintf( bbuf, MAX_PATH, FONT_DIR "/%s",
|
||||
de->d_name );
|
||||
rb->font_load( bbuf );
|
||||
rb->font_load(NULL, bbuf );
|
||||
rb->font_getstringsize( de->d_name, &fw, &fh, FONT_UI );
|
||||
if( nvih > 0 )
|
||||
{
|
||||
|
@ -887,12 +887,12 @@ static bool browse_fonts( char *dst, int dst_size )
|
|||
{
|
||||
rb->snprintf( bbuf, MAX_PATH, FONT_DIR "/%s",
|
||||
de->d_name );
|
||||
rb->font_load( bbuf );
|
||||
rb->font_load(NULL, bbuf );
|
||||
rb->font_getstringsize( de->d_name, NULL, &fh, FONT_UI );
|
||||
nvih = fh;
|
||||
}
|
||||
}
|
||||
rb->font_load( buffer.text.old_font );
|
||||
rb->font_load(NULL, buffer.text.old_font );
|
||||
rb->closedir( d );
|
||||
}
|
||||
|
||||
|
@ -1526,7 +1526,7 @@ static void draw_text( int x, int y )
|
|||
case TEXT_MENU_FONT:
|
||||
if( browse_fonts( buffer.text.font, MAX_PATH ) )
|
||||
{
|
||||
rb->font_load( buffer.text.font );
|
||||
rb->font_load(NULL, buffer.text.font );
|
||||
}
|
||||
break;
|
||||
|
||||
|
@ -1583,7 +1583,7 @@ static void draw_text( int x, int y )
|
|||
case TEXT_MENU_CANCEL:
|
||||
default:
|
||||
restore_screen();
|
||||
rb->font_load( buffer.text.old_font );
|
||||
rb->font_load(NULL, buffer.text.old_font );
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,6 +68,7 @@
|
|||
#endif
|
||||
#include "wps.h"
|
||||
#include "skin_engine/skin_engine.h"
|
||||
#include "skin_engine/skin_fonts.h"
|
||||
#include "viewport.h"
|
||||
#include "statusbar-skinned.h"
|
||||
|
||||
|
@ -740,6 +741,7 @@ void settings_apply_skins(void)
|
|||
/* re-initialize the skin buffer before we start reloading skins */
|
||||
skin_buffer_init();
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
skin_font_init();
|
||||
if ( global_settings.sbs_file[0] &&
|
||||
global_settings.sbs_file[0] != 0xff )
|
||||
{
|
||||
|
@ -887,18 +889,26 @@ void settings_apply(bool read_disk)
|
|||
|
||||
if (read_disk)
|
||||
{
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
/* fonts need to be loaded before the WPS */
|
||||
if ( global_settings.font_file[0]) {
|
||||
snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
|
||||
global_settings.font_file);
|
||||
if (font_load(buf) == NULL)
|
||||
font_reset();
|
||||
if (font_load(NULL, buf) < 0)
|
||||
font_reset(NULL);
|
||||
}
|
||||
else
|
||||
font_reset();
|
||||
|
||||
font_reset(NULL);
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
if ( global_settings.remote_font_file[0]) {
|
||||
snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
|
||||
global_settings.remote_font_file);
|
||||
if (font_load_remoteui(buf) < 0)
|
||||
font_load_remoteui(NULL);
|
||||
}
|
||||
else
|
||||
font_load_remoteui(NULL);
|
||||
#endif
|
||||
if ( global_settings.kbd_file[0]) {
|
||||
snprintf(buf, sizeof buf, ROCKBOX_DIR "/%s.kbd",
|
||||
global_settings.kbd_file);
|
||||
|
|
|
@ -681,6 +681,9 @@ 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 */
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
unsigned char remote_font_file[MAX_FILENAME+1]; /* last font */
|
||||
#endif
|
||||
unsigned char kbd_file[MAX_FILENAME+1]; /* last keyboard */
|
||||
#endif /* HAVE_LCD_BITMAP */
|
||||
|
||||
|
|
|
@ -1431,6 +1431,10 @@ const struct settings_list settings[] = {
|
|||
#ifdef HAVE_LCD_BITMAP
|
||||
TEXT_SETTING(F_THEMESETTING, font_file, "font",
|
||||
DEFAULT_FONTNAME, FONT_DIR "/", ".fnt"),
|
||||
#endif
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
TEXT_SETTING(F_THEMESETTING, remote_font_file, "remote font",
|
||||
"", FONT_DIR "/", ".fnt"),
|
||||
#endif
|
||||
TEXT_SETTING(F_THEMESETTING,wps_file, "wps",
|
||||
DEFAULT_WPSNAME, WPS_DIR "/", ".wps"),
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
|
||||
#if defined(HAVE_LCD_BITMAP) || defined(SIMULATOR)
|
||||
#ifndef __PCTOOL__
|
||||
#include "font_cache.h"
|
||||
#include "sysfont.h"
|
||||
#endif
|
||||
|
||||
|
@ -47,9 +48,14 @@
|
|||
enum {
|
||||
FONT_SYSFIXED, /* system fixed pitch font*/
|
||||
FONT_UI, /* system porportional font*/
|
||||
MAXFONTS
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
FONT_UI_REMOTE, /* UI font for remote LCD */
|
||||
#endif
|
||||
SYSTEMFONTCOUNT /* Number of fonts reserved for the system and ui */
|
||||
};
|
||||
|
||||
#define MAXFONTS 10
|
||||
|
||||
/*
|
||||
* .fnt loadable font file format definition
|
||||
*
|
||||
|
@ -89,17 +95,38 @@ struct font {
|
|||
const unsigned char *width; /* character widths or NULL if fixed*/
|
||||
int defaultchar; /* default char (not glyph index)*/
|
||||
int32_t bits_size; /* # bytes of glyph bits*/
|
||||
|
||||
/* file, buffer and cache management */
|
||||
int fd; /* fd for the font file. >= 0 if cached */
|
||||
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 */
|
||||
#ifndef __PCTOOL__
|
||||
struct font_cache cache;
|
||||
uint32_t file_width_offset; /* offset to file width data */
|
||||
uint32_t file_offset_offset; /* offset to file offset data */
|
||||
int long_offset;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
/* font routines*/
|
||||
void font_init(void);
|
||||
struct font* font_load(const char *path);
|
||||
#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);
|
||||
void font_unload(int font_id);
|
||||
|
||||
struct font* font_get(int font);
|
||||
void font_reset(void);
|
||||
|
||||
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);
|
||||
void glyph_cache_save(void);
|
||||
void glyph_cache_save(struct font* pf);
|
||||
|
||||
#else /* HAVE_LCD_BITMAP */
|
||||
|
||||
|
|
369
firmware/font.c
369
firmware/font.c
|
@ -75,64 +75,77 @@ extern struct font sysfont;
|
|||
|
||||
/* structure filled in by font_load */
|
||||
static struct font font_ui;
|
||||
/* static buffer allocation structures */
|
||||
static unsigned char main_buf[MAX_FONT_SIZE];
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
#define REMOTE_FONT_SIZE 10000
|
||||
static struct font remote_font_ui;
|
||||
static unsigned char remote_buf[REMOTE_FONT_SIZE];
|
||||
#endif
|
||||
|
||||
/* system font table, in order of FONT_xxx definition */
|
||||
static struct font* const sysfonts[MAXFONTS] = { &sysfont, &font_ui };
|
||||
static struct font* sysfonts[MAXFONTS] = { &sysfont, &font_ui, NULL};
|
||||
|
||||
/* static buffer allocation structures */
|
||||
static unsigned char mbuf[MAX_FONT_SIZE];
|
||||
static unsigned char *freeptr = mbuf;
|
||||
static unsigned char *fileptr;
|
||||
static unsigned char *eofptr;
|
||||
|
||||
/* Font cache structures */
|
||||
static struct font_cache font_cache_ui;
|
||||
static int fnt_file = -1; /* >=0 if font is cached */
|
||||
static uint32_t file_width_offset; /* offset to file width data */
|
||||
static uint32_t file_offset_offset; /* offset to file offset data */
|
||||
static void cache_create(int maxwidth, int height);
|
||||
static int long_offset = 0;
|
||||
static int glyph_file;
|
||||
static void cache_create(struct font* pf, int maxwidth, int height);
|
||||
static void glyph_cache_load(struct font* pf);
|
||||
/* End Font cache structures */
|
||||
|
||||
static void glyph_cache_load(void);
|
||||
|
||||
void font_init(void)
|
||||
{
|
||||
memset(&font_ui, 0, sizeof(struct font));
|
||||
int i = SYSTEMFONTCOUNT;
|
||||
while (i<MAXFONTS)
|
||||
sysfonts[i++] = NULL;
|
||||
font_reset(NULL);
|
||||
}
|
||||
|
||||
/* Check if we have x bytes left in the file buffer */
|
||||
#define HAVEBYTES(x) (fileptr + (x) <= eofptr)
|
||||
#define HAVEBYTES(x) (pf->buffer_position + (x) <= pf->buffer_end)
|
||||
|
||||
/* Helper functions to read big-endian unaligned short or long from
|
||||
the file buffer. Bounds-checking must be done in the calling
|
||||
function.
|
||||
*/
|
||||
|
||||
static short readshort(void)
|
||||
static short readshort(struct font *pf)
|
||||
{
|
||||
unsigned short s;
|
||||
|
||||
s = *fileptr++ & 0xff;
|
||||
s |= (*fileptr++ << 8);
|
||||
s = *pf->buffer_position++ & 0xff;
|
||||
s |= (*pf->buffer_position++ << 8);
|
||||
return s;
|
||||
}
|
||||
|
||||
static int32_t readlong(void)
|
||||
static int32_t readlong(struct font *pf)
|
||||
{
|
||||
uint32_t l;
|
||||
|
||||
l = *fileptr++ & 0xff;
|
||||
l |= *fileptr++ << 8;
|
||||
l |= ((uint32_t)(*fileptr++)) << 16;
|
||||
l |= ((uint32_t)(*fileptr++)) << 24;
|
||||
l = *pf->buffer_position++ & 0xff;
|
||||
l |= *pf->buffer_position++ << 8;
|
||||
l |= ((uint32_t)(*pf->buffer_position++)) << 16;
|
||||
l |= ((uint32_t)(*pf->buffer_position++)) << 24;
|
||||
return l;
|
||||
}
|
||||
|
||||
void font_reset(void)
|
||||
void font_reset(struct font *pf)
|
||||
{
|
||||
memset(&font_ui, 0, sizeof(struct font));
|
||||
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)
|
||||
|
@ -142,23 +155,23 @@ static struct font* font_load_header(struct font *pf)
|
|||
return NULL;
|
||||
|
||||
/* read magic and version #*/
|
||||
if (memcmp(fileptr, VERSION, 4) != 0)
|
||||
if (memcmp(pf->buffer_position, VERSION, 4) != 0)
|
||||
return NULL;
|
||||
|
||||
fileptr += 4;
|
||||
pf->buffer_position += 4;
|
||||
|
||||
/* font info*/
|
||||
pf->maxwidth = readshort();
|
||||
pf->height = readshort();
|
||||
pf->ascent = readshort();
|
||||
fileptr += 2; /* Skip padding */
|
||||
pf->firstchar = readlong();
|
||||
pf->defaultchar = readlong();
|
||||
pf->size = readlong();
|
||||
pf->maxwidth = readshort(pf);
|
||||
pf->height = readshort(pf);
|
||||
pf->ascent = readshort(pf);
|
||||
pf->buffer_position += 2; /* Skip padding */
|
||||
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->bits_size = readlong(pf);
|
||||
|
||||
return pf;
|
||||
}
|
||||
|
@ -171,32 +184,32 @@ static struct font* font_load_in_memory(struct font* pf)
|
|||
return NULL;
|
||||
|
||||
/* # longs of offset*/
|
||||
noffset = readlong();
|
||||
noffset = readlong(pf);
|
||||
|
||||
/* # bytes of width*/
|
||||
nwidth = readlong();
|
||||
nwidth = readlong(pf);
|
||||
|
||||
/* variable font data*/
|
||||
pf->bits = (unsigned char *)fileptr;
|
||||
fileptr += pf->bits_size*sizeof(unsigned char);
|
||||
pf->bits = (unsigned char *)pf->buffer_position;
|
||||
pf->buffer_position += pf->bits_size*sizeof(unsigned char);
|
||||
|
||||
if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
|
||||
{
|
||||
/* pad to 16-bit boundary */
|
||||
fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1);
|
||||
pf->buffer_position = (unsigned char *)(((intptr_t)pf->buffer_position + 1) & ~1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* pad to 32-bit boundary*/
|
||||
fileptr = (unsigned char *)(((intptr_t)fileptr + 3) & ~3);
|
||||
pf->buffer_position = (unsigned char *)(((intptr_t)pf->buffer_position + 3) & ~3);
|
||||
}
|
||||
|
||||
if (noffset)
|
||||
{
|
||||
if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
|
||||
{
|
||||
long_offset = 0;
|
||||
pf->offset = (uint16_t*)fileptr;
|
||||
pf->long_offset = 0;
|
||||
pf->offset = (uint16_t*)pf->buffer_position;
|
||||
|
||||
/* Check we have sufficient buffer */
|
||||
if (!HAVEBYTES(noffset * sizeof(uint16_t)))
|
||||
|
@ -204,13 +217,13 @@ static struct font* font_load_in_memory(struct font* pf)
|
|||
|
||||
for (i=0; i<noffset; ++i)
|
||||
{
|
||||
((uint16_t*)(pf->offset))[i] = (uint16_t)readshort();
|
||||
((uint16_t*)(pf->offset))[i] = (uint16_t)readshort(pf);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
long_offset = 1;
|
||||
pf->offset = (uint16_t*)fileptr;
|
||||
pf->long_offset = 1;
|
||||
pf->offset = (uint16_t*)pf->buffer_position;
|
||||
|
||||
/* Check we have sufficient buffer */
|
||||
if (!HAVEBYTES(noffset * sizeof(int32_t)))
|
||||
|
@ -218,7 +231,7 @@ static struct font* font_load_in_memory(struct font* pf)
|
|||
|
||||
for (i=0; i<noffset; ++i)
|
||||
{
|
||||
((uint32_t*)(pf->offset))[i] = (uint32_t)readlong();
|
||||
((uint32_t*)(pf->offset))[i] = (uint32_t)readlong(pf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -226,13 +239,13 @@ static struct font* font_load_in_memory(struct font* pf)
|
|||
pf->offset = NULL;
|
||||
|
||||
if (nwidth) {
|
||||
pf->width = (unsigned char *)fileptr;
|
||||
fileptr += nwidth*sizeof(unsigned char);
|
||||
pf->width = (unsigned char *)pf->buffer_position;
|
||||
pf->buffer_position += nwidth*sizeof(unsigned char);
|
||||
}
|
||||
else
|
||||
pf->width = NULL;
|
||||
|
||||
if (fileptr > eofptr)
|
||||
if (pf->buffer_position > pf->buffer_end)
|
||||
return NULL;
|
||||
|
||||
return pf; /* success!*/
|
||||
|
@ -242,135 +255,203 @@ static struct font* font_load_in_memory(struct font* pf)
|
|||
static struct font* font_load_cached(struct font* pf)
|
||||
{
|
||||
uint32_t noffset, nwidth;
|
||||
unsigned char* oldfileptr = fileptr;
|
||||
unsigned char* oldfileptr = pf->buffer_position;
|
||||
|
||||
if (!HAVEBYTES(2 * sizeof(int32_t)))
|
||||
return NULL;
|
||||
|
||||
/* # longs of offset*/
|
||||
noffset = readlong();
|
||||
noffset = readlong(pf);
|
||||
|
||||
/* # bytes of width*/
|
||||
nwidth = readlong();
|
||||
nwidth = readlong(pf);
|
||||
|
||||
/* We are now at the bitmap data, this is fixed at 36.. */
|
||||
pf->bits = NULL;
|
||||
|
||||
/* Calculate offset to offset data */
|
||||
fileptr += pf->bits_size * sizeof(unsigned char);
|
||||
pf->buffer_position += pf->bits_size * sizeof(unsigned char);
|
||||
|
||||
if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
|
||||
{
|
||||
long_offset = 0;
|
||||
pf->long_offset = 0;
|
||||
/* pad to 16-bit boundary */
|
||||
fileptr = (unsigned char *)(((intptr_t)fileptr + 1) & ~1);
|
||||
pf->buffer_position = (unsigned char *)(((intptr_t)pf->buffer_position + 1) & ~1);
|
||||
}
|
||||
else
|
||||
{
|
||||
long_offset = 1;
|
||||
pf->long_offset = 1;
|
||||
/* pad to 32-bit boundary*/
|
||||
fileptr = (unsigned char *)(((intptr_t)fileptr + 3) & ~3);
|
||||
pf->buffer_position = (unsigned char *)(((intptr_t)pf->buffer_position + 3) & ~3);
|
||||
}
|
||||
|
||||
if (noffset)
|
||||
file_offset_offset = (uint32_t)(fileptr - freeptr);
|
||||
pf->file_offset_offset = (uint32_t)(pf->buffer_position - pf->buffer_start);
|
||||
else
|
||||
file_offset_offset = 0;
|
||||
pf->file_offset_offset = 0;
|
||||
|
||||
/* Calculate offset to widths data */
|
||||
if (pf->bits_size < MAX_FONTSIZE_FOR_16_BIT_OFFSETS)
|
||||
fileptr += noffset * sizeof(uint16_t);
|
||||
pf->buffer_position += noffset * sizeof(uint16_t);
|
||||
else
|
||||
fileptr += noffset * sizeof(uint32_t);
|
||||
pf->buffer_position += noffset * sizeof(uint32_t);
|
||||
|
||||
if (nwidth)
|
||||
file_width_offset = (uint32_t)(fileptr - freeptr);
|
||||
pf->file_width_offset = (uint32_t)(pf->buffer_position - pf->buffer_start);
|
||||
else
|
||||
file_width_offset = 0;
|
||||
pf->file_width_offset = 0;
|
||||
|
||||
fileptr = oldfileptr;
|
||||
pf->buffer_position = oldfileptr;
|
||||
|
||||
/* Create the cache */
|
||||
cache_create(pf->maxwidth, pf->height);
|
||||
cache_create(pf, pf->maxwidth, pf->height);
|
||||
|
||||
return pf;
|
||||
}
|
||||
|
||||
/* read and load font into incore font structure*/
|
||||
struct font* font_load(const char *path)
|
||||
static bool internal_load_font(struct font* pf, const char *path,
|
||||
char *buf, size_t buf_size)
|
||||
{
|
||||
int size;
|
||||
struct font* pf = &font_ui;
|
||||
|
||||
|
||||
/* save loaded glyphs */
|
||||
glyph_cache_save();
|
||||
|
||||
glyph_cache_save(pf);
|
||||
/* Close font file handle */
|
||||
if (fnt_file >= 0)
|
||||
close(fnt_file);
|
||||
if (pf->fd >= 0)
|
||||
close(pf->fd);
|
||||
|
||||
font_reset(pf);
|
||||
|
||||
/* open and read entire font file*/
|
||||
fnt_file = open(path, O_RDONLY|O_BINARY);
|
||||
pf->fd = open(path, O_RDONLY|O_BINARY);
|
||||
|
||||
if (fnt_file < 0) {
|
||||
if (pf->fd < 0) {
|
||||
DEBUGF("Can't open font: %s\n", path);
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Check file size */
|
||||
size = filesize(fnt_file);
|
||||
|
||||
font_reset();
|
||||
|
||||
/* currently, font loading replaces earlier font allocation*/
|
||||
freeptr = (unsigned char *)(((intptr_t)mbuf + 3) & ~3);
|
||||
fileptr = freeptr;
|
||||
|
||||
|
||||
if (size > MAX_FONT_SIZE)
|
||||
size = filesize(pf->fd);
|
||||
pf->buffer_start = buf;
|
||||
pf->buffer_size = buf_size;
|
||||
|
||||
pf->buffer_position = buf;
|
||||
|
||||
if (size > pf->buffer_size)
|
||||
{
|
||||
read(fnt_file, fileptr, FONT_HEADER_SIZE);
|
||||
eofptr = fileptr + FONT_HEADER_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");
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!font_load_cached(pf))
|
||||
{
|
||||
DEBUGF("Failed font cache load");
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
glyph_cache_load();
|
||||
glyph_cache_load(pf);
|
||||
}
|
||||
else
|
||||
{
|
||||
read(fnt_file, fileptr, MAX_FONT_SIZE);
|
||||
eofptr = fileptr + size;
|
||||
close(fnt_file);
|
||||
fnt_file = -1;
|
||||
read(pf->fd, pf->buffer_position, pf->buffer_size);
|
||||
pf->buffer_end = pf->buffer_position + size;
|
||||
close(pf->fd);
|
||||
pf->fd = -1;
|
||||
|
||||
if (!font_load_header(pf))
|
||||
{
|
||||
DEBUGF("Failed font header load");
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!font_load_in_memory(pf))
|
||||
{
|
||||
DEBUGF("Failed mem load");
|
||||
return NULL;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifdef HAVE_REMOTE_LCD
|
||||
/* Load a font into the special remote ui font slot */
|
||||
int font_load_remoteui(const char* path)
|
||||
{
|
||||
struct font* pf = &remote_font_ui;
|
||||
if (!path)
|
||||
{
|
||||
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;
|
||||
}
|
||||
if (!internal_load_font(pf, path, remote_buf, REMOTE_FONT_SIZE))
|
||||
{
|
||||
sysfonts[FONT_UI_REMOTE] = NULL;
|
||||
return -1;
|
||||
}
|
||||
|
||||
sysfonts[FONT_UI_REMOTE] = pf;
|
||||
return FONT_UI_REMOTE;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* no need for multiple font loads currently*/
|
||||
/*freeptr += filesize;*/
|
||||
/*freeptr = (unsigned char *)(freeptr + 3) & ~3;*/ /* pad freeptr*/
|
||||
/* 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_id = -1;
|
||||
char *buffer;
|
||||
size_t buffer_size;
|
||||
if (pf == NULL)
|
||||
{
|
||||
pf = &font_ui;
|
||||
font_id = FONT_UI;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (font_id = SYSTEMFONTCOUNT; font_id < MAXFONTS; font_id++)
|
||||
{
|
||||
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);
|
||||
buffer_size = MAX_FONT_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
buffer = pf->buffer_start;
|
||||
buffer_size = pf->buffer_size;
|
||||
}
|
||||
|
||||
if (!internal_load_font(pf, path, buffer, buffer_size))
|
||||
return -1;
|
||||
|
||||
sysfonts[font_id] = pf;
|
||||
return font_id; /* success!*/
|
||||
}
|
||||
|
||||
return pf; /* success!*/
|
||||
void font_unload(int font_id)
|
||||
{
|
||||
struct font* pf = sysfonts[font_id];
|
||||
if (font_id >= SYSTEMFONTCOUNT && pf)
|
||||
{
|
||||
if (pf->fd >= 0)
|
||||
close(pf->fd);
|
||||
sysfonts[font_id] = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -382,9 +463,6 @@ struct font* font_get(int font)
|
|||
{
|
||||
struct font* pf;
|
||||
|
||||
if (font >= MAXFONTS)
|
||||
font = 0;
|
||||
|
||||
while (1) {
|
||||
pf = sysfonts[font];
|
||||
if (pf && pf->height)
|
||||
|
@ -404,11 +482,11 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
|
|||
unsigned short char_code = p->_char_code;
|
||||
unsigned char tmp[2];
|
||||
|
||||
if (file_width_offset)
|
||||
if (pf->file_width_offset)
|
||||
{
|
||||
int width_offset = file_width_offset + char_code;
|
||||
lseek(fnt_file, width_offset, SEEK_SET);
|
||||
read(fnt_file, &(p->width), 1);
|
||||
int width_offset = pf->file_width_offset + char_code;
|
||||
lseek(pf->fd, width_offset, SEEK_SET);
|
||||
read(pf->fd, &(p->width), 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -417,14 +495,14 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
|
|||
|
||||
int32_t bitmap_offset = 0;
|
||||
|
||||
if (file_offset_offset)
|
||||
if (pf->file_offset_offset)
|
||||
{
|
||||
int32_t offset = file_offset_offset + char_code * (long_offset ? sizeof(int32_t) : sizeof(int16_t));
|
||||
lseek(fnt_file, offset, SEEK_SET);
|
||||
read (fnt_file, tmp, 2);
|
||||
int32_t offset = pf->file_offset_offset + char_code * (pf->long_offset ? sizeof(int32_t) : sizeof(int16_t));
|
||||
lseek(pf->fd, offset, SEEK_SET);
|
||||
read (pf->fd, tmp, 2);
|
||||
bitmap_offset = tmp[0] | (tmp[1] << 8);
|
||||
if (long_offset) {
|
||||
read (fnt_file, tmp, 2);
|
||||
if (pf->long_offset) {
|
||||
read (pf->fd, tmp, 2);
|
||||
bitmap_offset |= (tmp[0] << 16) | (tmp[1] << 24);
|
||||
}
|
||||
}
|
||||
|
@ -434,22 +512,22 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data)
|
|||
}
|
||||
|
||||
int32_t file_offset = FONT_HEADER_SIZE + bitmap_offset;
|
||||
lseek(fnt_file, file_offset, SEEK_SET);
|
||||
lseek(pf->fd, file_offset, SEEK_SET);
|
||||
|
||||
int src_bytes = p->width * ((pf->height + 7) / 8);
|
||||
read(fnt_file, p->bitmap, src_bytes);
|
||||
read(pf->fd, p->bitmap, src_bytes);
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts cbuf into a font cache
|
||||
*/
|
||||
static void cache_create(int maxwidth, int height)
|
||||
static void cache_create(struct font* pf, int maxwidth, int height)
|
||||
{
|
||||
/* maximum size of rotated bitmap */
|
||||
int bitmap_size = maxwidth * ((height + 7) / 8);
|
||||
|
||||
/* Initialise cache */
|
||||
font_cache_create(&font_cache_ui, mbuf, MAX_FONT_SIZE, bitmap_size);
|
||||
font_cache_create(&pf->cache, pf->buffer_start, pf->buffer_size, bitmap_size);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -462,8 +540,8 @@ int font_get_width(struct font* pf, unsigned short char_code)
|
|||
char_code = pf->defaultchar;
|
||||
char_code -= pf->firstchar;
|
||||
|
||||
return (fnt_file >= 0 && pf != &sysfont)?
|
||||
font_cache_get(&font_cache_ui,char_code,load_cache_entry,pf)->width:
|
||||
return (pf->fd >= 0 && pf != &sysfont)?
|
||||
font_cache_get(&pf->cache,char_code,load_cache_entry,pf)->width:
|
||||
pf->width? pf->width[char_code]: pf->maxwidth;
|
||||
}
|
||||
|
||||
|
@ -476,10 +554,10 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
|
|||
char_code = pf->defaultchar;
|
||||
char_code -= pf->firstchar;
|
||||
|
||||
if (fnt_file >= 0 && pf != &sysfont)
|
||||
if (pf->fd >= 0 && pf != &sysfont)
|
||||
{
|
||||
bits =
|
||||
(unsigned char*)font_cache_get(&font_cache_ui,char_code,load_cache_entry,pf)->bitmap;
|
||||
(unsigned char*)font_cache_get(&pf->cache,char_code,load_cache_entry,pf)->bitmap;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -497,7 +575,7 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
|
|||
|
||||
return bits;
|
||||
}
|
||||
|
||||
static int cache_fd;
|
||||
static void glyph_file_write(void* data)
|
||||
{
|
||||
struct font_cache_entry* p = data;
|
||||
|
@ -507,45 +585,48 @@ static void glyph_file_write(void* data)
|
|||
|
||||
ch = p->_char_code + pf->firstchar;
|
||||
|
||||
if (ch != 0xffff && glyph_file >= 0) {
|
||||
if (ch != 0xffff && cache_fd >= 0) {
|
||||
tmp[0] = ch >> 8;
|
||||
tmp[1] = ch & 0xff;
|
||||
if (write(glyph_file, tmp, 2) != 2) {
|
||||
close(glyph_file);
|
||||
glyph_file = -1;
|
||||
if (write(cache_fd, tmp, 2) != 2) {
|
||||
close(cache_fd);
|
||||
cache_fd = -1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
/* save the char codes of the loaded glyphs to a file */
|
||||
void glyph_cache_save(void)
|
||||
void glyph_cache_save(struct font* pf)
|
||||
{
|
||||
|
||||
if (fnt_file >= 0) {
|
||||
if (!pf)
|
||||
pf = &font_ui;
|
||||
if (pf->fd >= 0 && pf == &font_ui)
|
||||
{
|
||||
#ifdef WPSEDITOR
|
||||
glyph_file = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC);
|
||||
cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC);
|
||||
#else
|
||||
glyph_file = creat(GLYPH_CACHE_FILE);
|
||||
cache_fd = creat(GLYPH_CACHE_FILE);
|
||||
#endif
|
||||
if (glyph_file < 0) return;
|
||||
if (cache_fd < 0) return;
|
||||
|
||||
lru_traverse(&font_cache_ui._lru, glyph_file_write);
|
||||
|
||||
if (glyph_file >= 0)
|
||||
close(glyph_file);
|
||||
lru_traverse(&pf->cache._lru, glyph_file_write);
|
||||
|
||||
if (cache_fd < 0)
|
||||
{
|
||||
close(cache_fd);
|
||||
cache_fd = -1;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
static void glyph_cache_load(void)
|
||||
static void glyph_cache_load(struct font* pf)
|
||||
{
|
||||
if (fnt_file >= 0) {
|
||||
|
||||
if (pf->fd >= 0) {
|
||||
int fd;
|
||||
unsigned char tmp[2];
|
||||
unsigned short ch;
|
||||
struct font* pf = &font_ui;
|
||||
|
||||
fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY);
|
||||
|
||||
|
|
|
@ -744,7 +744,7 @@ void shutdown_hw(void)
|
|||
|
||||
if (battery_level_safe()) { /* do not save on critical battery */
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
glyph_cache_save();
|
||||
glyph_cache_save(NULL);
|
||||
#endif
|
||||
|
||||
/* Commit pending writes if needed. Even though we don't do write caching,
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
../../apps/gui/skin_engine/wps_debug.c
|
||||
../../apps/gui/skin_engine/skin_parser.c
|
||||
../../apps/gui/skin_engine/skin_buffer.c
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
../../apps/gui/skin_engine/skin_fonts.c
|
||||
#endif
|
||||
../../apps/gui/viewport.c
|
||||
../../apps/misc.c
|
||||
../../firmware/common/strlcpy.c
|
||||
|
|
|
@ -31,6 +31,7 @@
|
|||
#include "settings.h"
|
||||
#include "viewport.h"
|
||||
#include "file.h"
|
||||
#include "font.h"
|
||||
|
||||
bool debug_wps = true;
|
||||
int wps_verbose_level = 0;
|
||||
|
@ -236,6 +237,21 @@ void screen_clear_area(struct screen * display, int xstart, int ystart,
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LCD_BITMAP
|
||||
static int loaded_fonts = 0;
|
||||
int font_load(struct font* pf, const char *path)
|
||||
{
|
||||
int id = SYSTEMFONTCOUNT + loaded_fonts;
|
||||
loaded_fonts++;
|
||||
return id;
|
||||
}
|
||||
|
||||
void font_unload(int font_id)
|
||||
{
|
||||
(void)font_id;
|
||||
}
|
||||
#endif
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int res;
|
||||
|
|
|
@ -1393,7 +1393,16 @@ int gen_c_source(struct font* pf, char *path)
|
|||
" %s /* offset */\n"
|
||||
" %s\n"
|
||||
" %d, /* defaultchar */\n"
|
||||
" %d /* bits_size */\n"
|
||||
" %d, /* bits_size */\n"
|
||||
" -1, /* font fd */\n"
|
||||
" 0, /* buffer start */\n"
|
||||
" 0, /* ^ position */\n"
|
||||
" 0, /* ^ end */\n"
|
||||
" 0, /* ^ size */\n"
|
||||
" {{0,0,0,0,0},0,0,0}, /* cache */\n"
|
||||
" 0, /* */\n"
|
||||
" 0, /* */\n"
|
||||
" 0, /* */\n"
|
||||
"};\n"
|
||||
"#endif /* HAVE_LCD_BITMAP */\n",
|
||||
pf->maxwidth, pf->height,
|
||||
|
|
Loading…
Reference in New Issue