1.  
  2. diff --git a/apps/settings.c b/apps/settings.c
  3. index a698606..a1ebf29 100644
  4. --- a/apps/settings.c
  5. +++ b/apps/settings.c
  6. @@ -880,7 +880,7 @@ void settings_apply(bool read_disk)
  7.  
  8. snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
  9. global_settings.font_file);
  10. - if (!loaded_font || strcmp(loaded_font, buf))
  11. + if (!loaded_font || strcmp(loaded_font, global_settings.font_file))
  12. {
  13. CHART2(">font_load ", global_settings.font_file);
  14. if (global_status.font_id[SCREEN_MAIN] >= 0)
  15. @@ -897,7 +897,7 @@ void settings_apply(bool read_disk)
  16. const char* loaded_font = font_filename(global_status.font_id[SCREEN_REMOTE]);
  17. snprintf(buf, sizeof buf, FONT_DIR "/%s.fnt",
  18. global_settings.remote_font_file);
  19. - if (!loaded_font || strcmp(loaded_font, buf))
  20. + if (!loaded_font || strcmp(loaded_font, global_settings.remote_font_file))
  21. {
  22. CHART2(">font_load_remoteui ", global_settings.remote_font_file);
  23. if (global_status.font_id[SCREEN_REMOTE] >= 0)
  24. diff --git a/firmware/drivers/lcd-bitmap-common.c b/firmware/drivers/lcd-bitmap-common.c
  25. index fc84fdd..4111530 100644
  26. --- a/firmware/drivers/lcd-bitmap-common.c
  27. +++ b/firmware/drivers/lcd-bitmap-common.c
  28. @@ -457,6 +457,7 @@ void LCDFN(scroll_fn)(void)
  29. else
  30. s->offset += LCDFN(scroll_info).step;
  31.  
  32. + font_lock(current_vp->font, true);
  33. pf = font_get(current_vp->font);
  34. xpos = s->startx;
  35. ypos = s->y * pf->height + s->y_offset;
  36. @@ -492,6 +493,7 @@ void LCDFN(scroll_fn)(void)
  37. pf->height, s->offset);
  38. LCDFN(update_viewport_rect)(xpos, ypos, current_vp->width - xpos,
  39. pf->height);
  40. + font_lock(current_vp->font, false);
  41. }
  42. LCDFN(set_viewport)(old_vp);
  43. }
  44. diff --git a/firmware/export/font.h b/firmware/export/font.h
  45. index 582c08f..9bebd90 100644
  46. --- a/firmware/export/font.h
  47. +++ b/firmware/export/font.h
  48. @@ -120,18 +120,21 @@ int font_load(const char *path);
  49. int font_load_ex(const char *path, size_t buffer_size);
  50. int font_glyphs_to_bufsize(const char *path, int glyphs);
  51. void font_unload(int font_id);
  52. +void font_unload_all(void);
  53. +
  54. +void font_lock(int font_id, bool lock);
  55.  
  56. struct font* font_get(int font);
  57.  
  58. int font_getstringsize(const unsigned char *str, int *w, int *h, int fontnumber);
  59. int font_get_width(struct font* ft, unsigned short ch);
  60. const unsigned char * font_get_bits(struct font* ft, unsigned short ch);
  61. -void glyph_cache_save(struct font* pf);
  62.  
  63. #else /* HAVE_LCD_BITMAP */
  64.  
  65. #define font_init()
  66. #define font_load(x)
  67. +#define font_unload_all()
  68.  
  69. #endif
  70.  
  71. diff --git a/firmware/font.c b/firmware/font.c
  72. index 0546061..c834685 100644
  73. --- a/firmware/font.c
  74. +++ b/firmware/font.c
  75. @@ -77,20 +77,19 @@ extern struct font sysfont;
  76.  
  77. struct buflib_alloc_data {
  78. struct font font;
  79. - bool handle_locked; /* is the buflib handle currently locked? */
  80. + int lock_count; /* is the buflib handle currently locked? */
  81. int refcount; /* how many times has this font been loaded? */
  82. unsigned char buffer[];
  83. };
  84. static int buflib_allocations[MAXFONTS];
  85. -static int handle_for_glyphcache;
  86.  
  87. static int buflibmove_callback(int handle, void* current, void* new)
  88. {
  89. (void)handle;
  90. struct buflib_alloc_data *alloc = (struct buflib_alloc_data*)current;
  91. - size_t diff = new - current;
  92. + ptrdiff_t diff = new - current;
  93.  
  94. - if (alloc->handle_locked)
  95. + if (alloc->lock_count > 0)
  96. return BUFLIB_CB_CANNOT_MOVE;
  97.  
  98. if (alloc->font.bits)
  99. @@ -105,7 +104,7 @@ static int buflibmove_callback(int handle, void* current, void* new)
  100. alloc->font.buffer_position += diff;
  101.  
  102. if (alloc->font.cache._index)
  103. - alloc->font.cache._index += diff;
  104. + alloc->font.cache._index = (void*)alloc->font.cache._index + diff;
  105. if (alloc->font.cache._lru._base)
  106. alloc->font.cache._lru._base += diff;
  107.  
  108. @@ -114,7 +113,14 @@ static int buflibmove_callback(int handle, void* current, void* new)
  109. static void lock_font_handle(int handle, bool lock)
  110. {
  111. struct buflib_alloc_data *alloc = core_get_data(handle);
  112. - alloc->handle_locked = lock;
  113. + alloc->lock_count += lock ? 1 : -1;
  114. +}
  115. +
  116. +void font_lock(int font_id, bool lock)
  117. +{
  118. + int handle = buflib_allocations[font_id];
  119. + if (handle > 0)
  120. + lock_font_handle(handle, lock);
  121. }
  122.  
  123. static struct buflib_callbacks buflibops = {buflibmove_callback, NULL };
  124. @@ -135,7 +141,8 @@ static inline unsigned char *buffer_from_handle(int handle)
  125.  
  126. /* Font cache structures */
  127. static void cache_create(struct font* pf);
  128. -static void glyph_cache_load(struct font* pf);
  129. +static void glyph_cache_load(int font_id);
  130. +static void glyph_cache_save(int font_id);
  131. /* End Font cache structures */
  132.  
  133. void font_init(void)
  134. @@ -143,7 +150,6 @@ void font_init(void)
  135. int i = 0;
  136. while (i<MAXFONTS)
  137. buflib_allocations[i++] = -1;
  138. - handle_for_glyphcache = -1;
  139. }
  140.  
  141. /* Check if we have x bytes left in the file buffer */
  142. @@ -359,13 +365,6 @@ static bool internal_load_font(int font_id, const char *path,
  143. {
  144. size_t size;
  145. struct font* pf = pf_from_handle(buflib_allocations[font_id]);
  146. - /* save loaded glyphs */
  147. - glyph_cache_save(pf);
  148. - /* Close font file handle */
  149. - if (pf->fd >= 0)
  150. - close(pf->fd);
  151. -
  152. - font_reset(font_id);
  153.  
  154. /* open and read entire font file*/
  155. pf->fd = open(path, O_RDONLY|O_BINARY);
  156. @@ -403,7 +402,7 @@ static bool internal_load_font(int font_id, const char *path,
  157. return false;
  158. }
  159.  
  160. - glyph_cache_load(pf);
  161. + glyph_cache_load(font_id);
  162. }
  163. else
  164. {
  165. @@ -427,14 +426,28 @@ static bool internal_load_font(int font_id, const char *path,
  166. return true;
  167. }
  168.  
  169. +static const char* font_shrinkfilename(const char* path)
  170. +{
  171. + static char filename[MAX_PATH];
  172. + char *end = strrchr(path, '/');
  173. + if (!end)
  174. + return NULL;
  175. + strlcpy(filename, end+1, MAX_PATH);
  176. + end = strrchr(filename, '.');
  177. + if (end)
  178. + *end = '\0';
  179. + return filename;
  180. +}
  181. +
  182. static int find_font_index(const char* path)
  183. {
  184. int index = 0, handle;
  185. + const char* shortname = font_shrinkfilename(path);
  186.  
  187. while (index < MAXFONTS)
  188. {
  189. handle = buflib_allocations[index];
  190. - if (handle > 0 && !strcmp(core_get_name(handle), path))
  191. + if (handle > 0 && !strcmp(core_get_name(handle), shortname))
  192. return index;
  193. index++;
  194. }
  195. @@ -450,14 +463,14 @@ static int alloc_and_init(int font_idx, const char* name, size_t size)
  196. size_t alloc_size = size + sizeof(struct buflib_alloc_data);
  197. if (handle > 0)
  198. return handle;
  199. - *phandle = core_alloc_ex(name, alloc_size, &buflibops);
  200. + *phandle = core_alloc_ex(font_shrinkfilename(name), alloc_size, &buflibops);
  201. handle = *phandle;
  202. if (handle < 0)
  203. return handle;
  204. pdata = core_get_data(handle);
  205. pf = &pdata->font;
  206. font_reset(font_idx);
  207. - pdata->handle_locked = false;
  208. + pdata->lock_count = 0;
  209. pdata->refcount = 1;
  210. pf->buffer_position = pf->buffer_start = buffer_from_handle(handle);
  211. pf->buffer_size = size;
  212. @@ -530,9 +543,6 @@ int font_load_ex(const char *path, size_t buffer_size)
  213. if (*handle < 0)
  214. return -1;
  215.  
  216. - if (handle_for_glyphcache < 0)
  217. - handle_for_glyphcache = *handle;
  218. -
  219. buffer = buffer_from_handle(*handle);
  220. lock_font_handle(*handle, true);
  221.  
  222. @@ -570,16 +580,27 @@ void font_unload(int font_id)
  223. if (pdata->refcount < 1)
  224. {
  225. //printf("freeing id: %d %s\n", font_id, core_get_name(*handle));
  226. + lock_font_handle(*handle, true);
  227. + glyph_cache_save(font_id);
  228. if (pf && pf->fd >= 0)
  229. close(pf->fd);
  230. + lock_font_handle(*handle, false);
  231. if (*handle > 0)
  232. core_free(*handle);
  233. - if (handle_for_glyphcache == *handle)
  234. - handle_for_glyphcache = -1; // should find the next available handle
  235. *handle = -1;
  236. }
  237. }
  238.  
  239. +void font_unload_all(void)
  240. +{
  241. + int i;
  242. + for (i=0; i<MAXFONTS; i++)
  243. + {
  244. + if (buflib_allocations[i] > 0)
  245. + font_unload(i);
  246. + }
  247. +}
  248. +
  249. /*
  250. * Return a pointer to an incore font structure.
  251. * If the requested font isn't loaded/compiled-in,
  252. @@ -604,7 +625,7 @@ struct font* font_get(int font)
  253. if (--font < 0)
  254. return &sysfont;
  255. }
  256. -}
  257. +}
  258.  
  259. static int pf_to_handle(struct font* pf)
  260. {
  261. @@ -731,11 +752,11 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code)
  262. return bits;
  263. }
  264. static int cache_fd;
  265. +static struct font* cache_pf;
  266. static void glyph_file_write(void* data)
  267. {
  268. struct font_cache_entry* p = data;
  269. - int handle = handle_for_glyphcache;
  270. - struct font* pf = pf_from_handle(handle);
  271. + struct font* pf = cache_pf;
  272. unsigned short ch;
  273. unsigned char tmp[2];
  274.  
  275. @@ -756,16 +777,19 @@ static void glyph_file_write(void* data)
  276. }
  277.  
  278. /* save the char codes of the loaded glyphs to a file */
  279. -void glyph_cache_save(struct font* pf)
  280. +static void glyph_cache_save(int font_id)
  281. {
  282. - if (pf != pf_from_handle(handle_for_glyphcache))
  283. - return;
  284. + struct font *pf = pf_from_handle(buflib_allocations[font_id]);
  285. if (pf->fd >= 0)
  286. {
  287. - cache_fd = open(GLYPH_CACHE_FILE, O_WRONLY|O_CREAT|O_TRUNC, 0666);
  288. + char filename[MAX_PATH];
  289. + snprintf(filename, MAX_PATH, ROCKBOX_DIR "/%s.glyphcache",
  290. + font_filename(font_id));
  291. + cache_fd = open(filename, O_WRONLY|O_CREAT|O_TRUNC, 0666);
  292. if (cache_fd < 0)
  293. return;
  294.  
  295. + cache_pf = pf;
  296. lru_traverse(&pf->cache._lru, glyph_file_write);
  297.  
  298. if (cache_fd >= 0)
  299. @@ -814,12 +838,11 @@ static int ushortcmp(const void *a, const void *b)
  300. {
  301. return ((int)(*(unsigned short*)a - *(unsigned short*)b));
  302. }
  303. -static void glyph_cache_load(struct font* pf)
  304. +static void glyph_cache_load(int font_id)
  305. {
  306. - if (handle_for_glyphcache <= 0)
  307. - return;
  308. + struct font* pf = pf_from_handle(buflib_allocations[font_id]);
  309. #define MAX_SORT 256
  310. - if (pf->fd >= 0 && pf == pf_from_handle(handle_for_glyphcache)) {
  311. + if (pf && pf->fd >= 0) {
  312. int fd;
  313. int i, size;
  314. unsigned char tmp[2];
  315. @@ -832,7 +855,10 @@ static void glyph_cache_load(struct font* pf)
  316. if ( sort_size > MAX_SORT )
  317. sort_size = MAX_SORT;
  318.  
  319. - fd = open(GLYPH_CACHE_FILE, O_RDONLY|O_BINARY);
  320. + char filename[MAX_PATH];
  321. + snprintf(filename, MAX_PATH, ROCKBOX_DIR "/%s.glyphcache",
  322. + font_filename(font_id));
  323. + fd = open(filename, O_RDONLY|O_BINARY);
  324. if (fd >= 0) {
  325.  
  326. /* only read what fits */
  327. diff --git a/firmware/powermgmt.c b/firmware/powermgmt.c
  328. index 79a7a90..c0f0f09 100644
  329. --- a/firmware/powermgmt.c
  330. +++ b/firmware/powermgmt.c
  331. @@ -655,9 +655,7 @@ void shutdown_hw(void)
  332. audio_stop();
  333.  
  334. if (battery_level_safe()) { /* do not save on critical battery */
  335. -#ifdef HAVE_LCD_BITMAP
  336. - glyph_cache_save(NULL);
  337. -#endif
  338. + font_unload_all();
  339.  
  340. /* Commit pending writes if needed. Even though we don't do write caching,
  341. things like flash translation layers may need this to commit scattered
  342.  
  343.