From 1c2aa35371aed8d895b3448dad865b913da57cfb Mon Sep 17 00:00:00 2001 From: Jonathan Gordon Date: Sun, 14 Feb 2010 06:26:16 +0000 Subject: [PATCH] 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 --- apps/SOURCES | 3 + apps/filetree.c | 30 ++- apps/gui/skin_engine/skin_fonts.c | 139 +++++++++++ apps/gui/skin_engine/skin_fonts.h | 46 ++++ apps/gui/skin_engine/skin_parser.c | 40 +++- apps/gui/statusbar-skinned.c | 4 +- apps/gui/viewport.c | 16 +- apps/lang/english.lang | 34 +++ apps/plugin.c | 24 +- apps/plugin.h | 39 ++- apps/plugins/rockpaint.c | 10 +- apps/settings.c | 20 +- apps/settings.h | 3 + apps/settings_list.c | 4 + firmware/export/font.h | 35 ++- firmware/font.c | 369 ++++++++++++++++++----------- firmware/powermgmt.c | 2 +- tools/checkwps/SOURCES | 3 + tools/checkwps/checkwps.c | 16 ++ tools/convbdf.c | 11 +- 20 files changed, 643 insertions(+), 205 deletions(-) create mode 100644 apps/gui/skin_engine/skin_fonts.c create mode 100644 apps/gui/skin_engine/skin_fonts.h diff --git a/apps/SOURCES b/apps/SOURCES index 7580caabc9..cd7cde7639 100644 --- a/apps/SOURCES +++ b/apps/SOURCES @@ -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 diff --git a/apps/filetree.c b/apps/filetree.c index 6062080baa..c9c8b3810a 100644 --- a/apps/filetree.c +++ b/apps/filetree.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: diff --git a/apps/gui/skin_engine/skin_fonts.c b/apps/gui/skin_engine/skin_fonts.c new file mode 100644 index 0000000000..1d3ef84271 --- /dev/null +++ b/apps/gui/skin_engine/skin_fonts.c @@ -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 +#include +#include + +#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= 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 ) \___| < | \_\ ( <_> > < < + * 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 +#include +#include + +#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 diff --git a/apps/gui/skin_engine/skin_parser.c b/apps/gui/skin_engine/skin_parser.c index 4655bf0dff..034ff532f0 100644 --- a/apps/gui/skin_engine/skin_parser.c +++ b/apps/gui/skin_engine/skin_parser.c @@ -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) diff --git a/apps/gui/statusbar-skinned.c b/apps/gui/statusbar-skinned.c index 9d447f62db..fac6756aec 100644 --- a/apps/gui/statusbar-skinned.c +++ b/apps/gui/statusbar-skinned.c @@ -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); } diff --git a/apps/gui/viewport.c b/apps/gui/viewport.c index eaee2cc8a5..ee233b9c46 100644 --- a/apps/gui/viewport.c +++ b/apps/gui/viewport.c @@ -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; diff --git a/apps/lang/english.lang b/apps/lang/english.lang index afb60e107c..ecbd41505d 100644 --- a/apps/lang/english.lang +++ b/apps/lang/english.lang @@ -13315,3 +13315,37 @@ lcd_bitmap: "Remote Base Skin" + + id: LANG_MAIN_SCREEN + desc: in the main menu + user: core + + *:none + remote: "Main Screen" + + + *:none + remote: "Main Screen" + + + *:none + remote: "Main Screen" + + + + id: LANG_REMOTE_SCREEN + desc: in the main menu + user: core + + *:none + remote: "Remote Screen" + + + *:none + remote: "Remote Screen" + + + *:none + remote: "Remote Screen" + + diff --git a/apps/plugin.c b/apps/plugin.c index 0d4d8ed0f6..46ab6e6429 100644 --- a/apps/plugin.c +++ b/apps/plugin.c @@ -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) diff --git a/apps/plugin.h b/apps/plugin.h index e5766c68b5..b1cfa30b87 100644 --- a/apps/plugin.h +++ b/apps/plugin.h @@ -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 */ diff --git a/apps/plugins/rockpaint.c b/apps/plugins/rockpaint.c index 96de7abab1..ae28258e3b 100644 --- a/apps/plugins/rockpaint.c +++ b/apps/plugins/rockpaint.c @@ -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; } } diff --git a/apps/settings.c b/apps/settings.c index becb516a81..574aa27159 100644 --- a/apps/settings.c +++ b/apps/settings.c @@ -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); diff --git a/apps/settings.h b/apps/settings.h index ea7138c8b0..6a42ca3c0c 100644 --- a/apps/settings.h +++ b/apps/settings.h @@ -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 */ diff --git a/apps/settings_list.c b/apps/settings_list.c index c5f9932125..d2700b39c4 100644 --- a/apps/settings_list.c +++ b/apps/settings_list.c @@ -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"), diff --git a/firmware/export/font.h b/firmware/export/font.h index 0fe6c30f2c..e9bf086423 100644 --- a/firmware/export/font.h +++ b/firmware/export/font.h @@ -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 */ diff --git a/firmware/font.c b/firmware/font.c index a8734e93a1..52c6ffae6a 100644 --- a/firmware/font.c +++ b/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 (ibuffer_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; ioffset))[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; ioffset))[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); diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c index 5f488810ac..3f2b3c0f85 100644 --- a/firmware/powermgmt.c +++ b/firmware/powermgmt.c @@ -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, diff --git a/tools/checkwps/SOURCES b/tools/checkwps/SOURCES index 06ef3b9ee5..6223b97178 100644 --- a/tools/checkwps/SOURCES +++ b/tools/checkwps/SOURCES @@ -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 diff --git a/tools/checkwps/checkwps.c b/tools/checkwps/checkwps.c index 38a650a878..32b6daa88b 100644 --- a/tools/checkwps/checkwps.c +++ b/tools/checkwps/checkwps.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; diff --git a/tools/convbdf.c b/tools/convbdf.c index fd82fb5a73..9e42cb8d01 100644 --- a/tools/convbdf.c +++ b/tools/convbdf.c @@ -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,