diff options
author | Fred Bauer <fred.w.bauer@gmail.com> | 2011-11-19 23:34:26 +0000 |
---|---|---|
committer | Fred Bauer <fred.w.bauer@gmail.com> | 2011-11-19 23:34:26 +0000 |
commit | ea7a89606cfaffb2ae2c843ea9868bd8c8dd16c9 (patch) | |
tree | 5ff1f18c66be4c25f32e03ffadeb6bb3cb568656 /firmware/font.c | |
parent | d78e05c5722356fd8ce20cdb4c40df44cc2b4d33 (diff) | |
download | rockbox-ea7a89606cfaffb2ae2c843ea9868bd8c8dd16c9.tar.gz rockbox-ea7a89606cfaffb2ae2c843ea9868bd8c8dd16c9.zip |
FS#12293 Global default glyph setting in System > Limits > Glyphs To Cache. Defaults to 250. This saves a lot of RAM while still allowing non-English users to have adequate glyph coverage.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@31031 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware/font.c')
-rw-r--r-- | firmware/font.c | 455 |
1 files changed, 202 insertions, 253 deletions
diff --git a/firmware/font.c b/firmware/font.c index ff5bc4b008..5dd080b89c 100644 --- a/firmware/font.c +++ b/firmware/font.c | |||
@@ -55,6 +55,11 @@ | |||
55 | #define MAX_FONT_SIZE 4000 | 55 | #define MAX_FONT_SIZE 4000 |
56 | #endif | 56 | #endif |
57 | #endif | 57 | #endif |
58 | #define GLYPHS_TO_CACHE 256 | ||
59 | |||
60 | #if MEMORYSIZE < 4 | ||
61 | #define FONT_HARD_LIMIT | ||
62 | #endif | ||
58 | 63 | ||
59 | #ifndef FONT_HEADER_SIZE | 64 | #ifndef FONT_HEADER_SIZE |
60 | #define FONT_HEADER_SIZE 36 | 65 | #define FONT_HEADER_SIZE 36 |
@@ -117,6 +122,8 @@ static int buflibmove_callback(int handle, void* current, void* new) | |||
117 | } | 122 | } |
118 | static void lock_font_handle(int handle, bool lock) | 123 | static void lock_font_handle(int handle, bool lock) |
119 | { | 124 | { |
125 | if ( handle < 0 ) | ||
126 | return; | ||
120 | struct buflib_alloc_data *alloc = core_get_data(handle); | 127 | struct buflib_alloc_data *alloc = core_get_data(handle); |
121 | if ( lock ) | 128 | if ( lock ) |
122 | alloc->handle_locks++; | 129 | alloc->handle_locks++; |
@@ -150,7 +157,7 @@ static inline unsigned char *buffer_from_handle(int handle) | |||
150 | 157 | ||
151 | /* Font cache structures */ | 158 | /* Font cache structures */ |
152 | static void cache_create(struct font* pf); | 159 | static void cache_create(struct font* pf); |
153 | static void glyph_cache_load(int fond_id); | 160 | static void glyph_cache_load(const char *font_path, struct font *pf); |
154 | /* End Font cache structures */ | 161 | /* End Font cache structures */ |
155 | 162 | ||
156 | void font_init(void) | 163 | void font_init(void) |
@@ -199,48 +206,14 @@ static int glyph_bytes( struct font *pf, int width ) | |||
199 | return (ret + 1) & ~1; | 206 | return (ret + 1) & ~1; |
200 | } | 207 | } |
201 | 208 | ||
202 | static struct font* font_load_header(struct font *pf) | ||
203 | { | ||
204 | /* Check we have enough data */ | ||
205 | if (!HAVEBYTES(28)) | ||
206 | return NULL; | ||
207 | |||
208 | /* read magic and version #*/ | ||
209 | if (memcmp(pf->buffer_position, VERSION, 4) != 0) | ||
210 | return NULL; | ||
211 | |||
212 | pf->buffer_position += 4; | ||
213 | |||
214 | /* font info*/ | ||
215 | pf->maxwidth = readshort(pf); | ||
216 | pf->height = readshort(pf); | ||
217 | pf->ascent = readshort(pf); | ||
218 | pf->depth = readshort(pf); | ||
219 | pf->firstchar = readlong(pf); | ||
220 | pf->defaultchar = readlong(pf); | ||
221 | pf->size = readlong(pf); | ||
222 | |||
223 | /* get variable font data sizes*/ | ||
224 | /* # words of bitmap_t*/ | ||
225 | pf->bits_size = readlong(pf); | ||
226 | |||
227 | return pf; | ||
228 | } | ||
229 | /* Load memory font */ | 209 | /* Load memory font */ |
230 | static struct font* font_load_in_memory(struct font* pf) | 210 | static struct font* font_load_in_memory(struct font* pf, |
211 | int32_t noffset, | ||
212 | int32_t nwidth ) | ||
231 | { | 213 | { |
232 | int32_t i, noffset, nwidth; | 214 | int i; |
233 | |||
234 | if (!HAVEBYTES(4)) | ||
235 | return NULL; | ||
236 | |||
237 | /* # longs of offset*/ | ||
238 | noffset = readlong(pf); | ||
239 | |||
240 | /* # bytes of width*/ | ||
241 | nwidth = readlong(pf); | ||
242 | |||
243 | /* variable font data*/ | 215 | /* variable font data*/ |
216 | pf->buffer_position = pf->buffer_start + 36; | ||
244 | pf->bits = (unsigned char *)pf->buffer_position; | 217 | pf->bits = (unsigned char *)pf->buffer_position; |
245 | pf->buffer_position += pf->bits_size*sizeof(unsigned char); | 218 | pf->buffer_position += pf->bits_size*sizeof(unsigned char); |
246 | 219 | ||
@@ -303,20 +276,10 @@ static struct font* font_load_in_memory(struct font* pf) | |||
303 | } | 276 | } |
304 | 277 | ||
305 | /* Load cached font */ | 278 | /* Load cached font */ |
306 | static struct font* font_load_cached(struct font* pf) | 279 | static struct font* font_load_cached(struct font* pf, |
280 | int32_t nwidth, | ||
281 | int32_t noffset) | ||
307 | { | 282 | { |
308 | uint32_t noffset, nwidth; | ||
309 | unsigned char* oldfileptr = pf->buffer_position; | ||
310 | |||
311 | if (!HAVEBYTES(2 * sizeof(int32_t))) | ||
312 | return NULL; | ||
313 | |||
314 | /* # longs of offset*/ | ||
315 | noffset = readlong(pf); | ||
316 | |||
317 | /* # bytes of width*/ | ||
318 | nwidth = readlong(pf); | ||
319 | |||
320 | /* We are now at the bitmap data, this is fixed at 36.. */ | 283 | /* We are now at the bitmap data, this is fixed at 36.. */ |
321 | pf->bits = NULL; | 284 | pf->bits = NULL; |
322 | 285 | ||
@@ -352,96 +315,12 @@ static struct font* font_load_cached(struct font* pf) | |||
352 | else | 315 | else |
353 | pf->file_width_offset = 0; | 316 | pf->file_width_offset = 0; |
354 | 317 | ||
355 | pf->buffer_position = oldfileptr; | ||
356 | |||
357 | /* Create the cache */ | 318 | /* Create the cache */ |
358 | cache_create(pf); | 319 | cache_create(pf); |
359 | 320 | ||
360 | return pf; | 321 | return pf; |
361 | } | 322 | } |
362 | 323 | ||
363 | static bool internal_load_font(int font_id, const char *path, char *buf, | ||
364 | size_t buf_size, int handle) | ||
365 | { | ||
366 | size_t size; | ||
367 | struct font* pf = pf_from_handle(handle); | ||
368 | |||
369 | /* open and read entire font file*/ | ||
370 | pf->fd = open(path, O_RDONLY|O_BINARY); | ||
371 | |||
372 | if (pf->fd < 0) { | ||
373 | DEBUGF("Can't open font: %s\n", path); | ||
374 | return false; | ||
375 | } | ||
376 | |||
377 | /* Check file size */ | ||
378 | size = filesize(pf->fd); | ||
379 | pf->buffer_start = buf; | ||
380 | pf->buffer_size = buf_size; | ||
381 | |||
382 | pf->buffer_position = buf; | ||
383 | |||
384 | if (size > pf->buffer_size) | ||
385 | { | ||
386 | read(pf->fd, pf->buffer_position, FONT_HEADER_SIZE); | ||
387 | pf->buffer_end = pf->buffer_position + FONT_HEADER_SIZE; | ||
388 | |||
389 | if (!font_load_header(pf)) | ||
390 | { | ||
391 | DEBUGF("Failed font header load"); | ||
392 | close(pf->fd); | ||
393 | pf->fd = -1; | ||
394 | return false; | ||
395 | } | ||
396 | |||
397 | if (!font_load_cached(pf)) | ||
398 | { | ||
399 | DEBUGF("Failed font cache load"); | ||
400 | close(pf->fd); | ||
401 | pf->fd = -1; | ||
402 | return false; | ||
403 | } | ||
404 | |||
405 | /* Cheat to get sector cache for different parts of font * | ||
406 | * file while preloading glyphs. Without this the disk head * | ||
407 | * thrashes between the width, offset, and bitmap data * | ||
408 | * in glyph_cache_load(). */ | ||
409 | pf->fd_width = open(path, O_RDONLY|O_BINARY); | ||
410 | pf->fd_offset = open(path, O_RDONLY|O_BINARY); | ||
411 | |||
412 | glyph_cache_load(font_id); | ||
413 | |||
414 | if(pf->fd_width >= 0) | ||
415 | close(pf->fd_width); | ||
416 | pf->fd_width = -1; | ||
417 | |||
418 | if(pf->fd_offset >= 0) | ||
419 | close(pf->fd_offset); | ||
420 | pf->fd_offset = -1; | ||
421 | } | ||
422 | else | ||
423 | { | ||
424 | read(pf->fd, pf->buffer_position, pf->buffer_size); | ||
425 | pf->buffer_end = pf->buffer_position + size; | ||
426 | close(pf->fd); | ||
427 | pf->fd = -1; | ||
428 | pf->fd_width = -1; | ||
429 | pf->fd_offset = -1; | ||
430 | |||
431 | if (!font_load_header(pf)) | ||
432 | { | ||
433 | DEBUGF("Failed font header load"); | ||
434 | return false; | ||
435 | } | ||
436 | |||
437 | if (!font_load_in_memory(pf)) | ||
438 | { | ||
439 | DEBUGF("Failed mem load"); | ||
440 | return false; | ||
441 | } | ||
442 | } | ||
443 | return true; | ||
444 | } | ||
445 | 324 | ||
446 | static int find_font_index(const char* path) | 325 | static int find_font_index(const char* path) |
447 | { | 326 | { |
@@ -457,30 +336,6 @@ static int find_font_index(const char* path) | |||
457 | return FONT_SYSFIXED; | 336 | return FONT_SYSFIXED; |
458 | } | 337 | } |
459 | 338 | ||
460 | static int alloc_and_init(int font_idx, const char* name, size_t size) | ||
461 | { | ||
462 | int *phandle = &buflib_allocations[font_idx]; | ||
463 | int handle = *phandle; | ||
464 | struct buflib_alloc_data *pdata; | ||
465 | struct font *pf; | ||
466 | size_t alloc_size = size + sizeof(struct buflib_alloc_data); | ||
467 | if (handle > 0) | ||
468 | return handle; | ||
469 | *phandle = core_alloc_ex(name, alloc_size, &buflibops); | ||
470 | handle = *phandle; | ||
471 | if (handle < 0) | ||
472 | return handle; | ||
473 | pdata = core_get_data(handle); | ||
474 | pf = &pdata->font; | ||
475 | pdata->handle_locks = 0; | ||
476 | pdata->refcount = 1; | ||
477 | pf->buffer_position = pf->buffer_start = buffer_from_handle(handle); | ||
478 | pf->buffer_size = size; | ||
479 | pf->fd_width = -1; | ||
480 | pf->fd_offset = -1; | ||
481 | return handle; | ||
482 | } | ||
483 | |||
484 | const char* font_filename(int font_id) | 339 | const char* font_filename(int font_id) |
485 | { | 340 | { |
486 | int handle = buflib_allocations[font_id]; | 341 | int handle = buflib_allocations[font_id]; |
@@ -488,22 +343,118 @@ const char* font_filename(int font_id) | |||
488 | return core_get_name(handle); | 343 | return core_get_name(handle); |
489 | return NULL; | 344 | return NULL; |
490 | } | 345 | } |
491 | 346 | ||
492 | /* read and load font into incore font structure, | 347 | size_t font_glyphs_to_bufsize(struct font *pf, int glyphs) |
493 | * returns the font number on success, -1 on failure */ | 348 | { |
494 | int font_load_ex(const char *path, size_t buffer_size) | 349 | size_t bufsize; |
350 | |||
351 | /* LRU bytes per glyph */ | ||
352 | bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) + | ||
353 | sizeof( unsigned short); | ||
354 | /* Image bytes per glyph */ | ||
355 | bufsize += glyph_bytes(pf, pf->maxwidth); | ||
356 | bufsize *= glyphs; | ||
357 | |||
358 | return bufsize; | ||
359 | } | ||
360 | |||
361 | static struct font* font_load_header(int fd, struct font *pheader, | ||
362 | struct font *pf, | ||
363 | uint32_t *nwidth, uint32_t *noffset) | ||
364 | { | ||
365 | /* Load the header. Readshort() and readlong() * | ||
366 | * update buffer_position address as they read */ | ||
367 | pheader->buffer_start = pheader->buffer_position = (char *)pheader; | ||
368 | pheader->buffer_size = FONT_HEADER_SIZE; | ||
369 | pheader->buffer_end = pheader->buffer_start + pheader->buffer_size; | ||
370 | |||
371 | if (read(fd, pheader, FONT_HEADER_SIZE) != FONT_HEADER_SIZE) | ||
372 | return NULL; | ||
373 | |||
374 | /* read magic and version #*/ | ||
375 | if (memcmp(pheader->buffer_position, VERSION, 4) != 0) | ||
376 | return NULL; | ||
377 | |||
378 | pheader->buffer_position += 4; | ||
379 | |||
380 | /* font info*/ | ||
381 | pf->maxwidth = readshort(pheader); | ||
382 | pf->height = readshort(pheader); | ||
383 | pf->ascent = readshort(pheader); | ||
384 | pf->depth = readshort(pheader); | ||
385 | pf->firstchar = readlong(pheader); | ||
386 | pf->defaultchar = readlong(pheader); | ||
387 | pf->size = readlong(pheader); | ||
388 | |||
389 | /* get variable font data sizes*/ | ||
390 | /* # words of bitmap_t*/ | ||
391 | pf->bits_size = readlong(pheader); | ||
392 | *noffset = readlong(pheader); | ||
393 | *nwidth = readlong(pheader); | ||
394 | |||
395 | return pf; | ||
396 | } | ||
397 | |||
398 | /* load a font with room for glyphs, limited to bufsize if not zero */ | ||
399 | int font_load_ex( const char *path, size_t buf_size, int glyphs ) | ||
495 | { | 400 | { |
401 | //printf("\nfont_load_ex(%s, %d, %d)\n", path, buf_size, glyphs); | ||
402 | int fd = open(path, O_RDONLY|O_BINARY); | ||
403 | if ( fd < 0 ) | ||
404 | return -1; | ||
405 | |||
406 | /* load font struct f with file header */ | ||
407 | int file_size = filesize( fd ); | ||
408 | struct font header; | ||
409 | struct font *pheader = &header; | ||
410 | struct font f; | ||
411 | |||
412 | uint32_t nwidth, noffset; | ||
413 | if ( !font_load_header( fd, pheader, &f, &nwidth, &noffset ) | ||
414 | #if LCD_DEPTH < 16 | ||
415 | || f.depth | ||
416 | #endif | ||
417 | ) | ||
418 | { | ||
419 | close(fd); | ||
420 | return -1; | ||
421 | } | ||
422 | |||
423 | /* examine f and calc buffer size */ | ||
424 | bool cached = false; | ||
425 | size_t bufsize = buf_size; | ||
426 | size_t glyph_buf_size = font_glyphs_to_bufsize( &f, glyphs ); | ||
427 | |||
428 | if ( bufsize && glyphs && bufsize > glyph_buf_size) | ||
429 | bufsize = glyph_buf_size; | ||
430 | else | ||
431 | { | ||
432 | if ( glyphs ) | ||
433 | bufsize = glyph_buf_size; | ||
434 | else | ||
435 | bufsize = MAX_FONT_SIZE; | ||
436 | } | ||
437 | #ifdef FONT_HARD_LIMIT | ||
438 | if ( bufsize > MAX_FONT_SIZE ) | ||
439 | bufsize = MAX_FONT_SIZE; | ||
440 | #endif | ||
441 | if ( bufsize < (size_t) file_size ) | ||
442 | cached = true; | ||
443 | else | ||
444 | bufsize = file_size; | ||
445 | |||
446 | /* check already loaded */ | ||
496 | int font_id = find_font_index(path); | 447 | int font_id = find_font_index(path); |
497 | char *buffer; | ||
498 | int handle; | ||
499 | 448 | ||
500 | if (font_id > FONT_SYSFIXED) | 449 | if (font_id > FONT_SYSFIXED) |
501 | { | 450 | { |
502 | /* already loaded, no need to reload */ | 451 | /* already loaded, no need to reload */ |
503 | struct buflib_alloc_data *pd = core_get_data(buflib_allocations[font_id]); | 452 | struct buflib_alloc_data *pd = core_get_data(buflib_allocations[font_id]); |
504 | if (pd->font.buffer_size < buffer_size) | 453 | if (pd->font.buffer_size < bufsize) |
505 | { | 454 | { |
506 | int old_refcount, old_id; | 455 | int old_refcount, old_id; |
456 | size_t old_bufsize = pd->font.buffer_size; | ||
457 | bool failed = false; | ||
507 | /* reload the font: | 458 | /* reload the font: |
508 | * 1) save of refcont and id | 459 | * 1) save of refcont and id |
509 | * 2) force unload (set refcount to 1 to make sure it get unloaded) | 460 | * 2) force unload (set refcount to 1 to make sure it get unloaded) |
@@ -514,11 +465,14 @@ int font_load_ex(const char *path, size_t buffer_size) | |||
514 | old_refcount = pd->refcount; | 465 | old_refcount = pd->refcount; |
515 | pd->refcount = 1; | 466 | pd->refcount = 1; |
516 | font_unload(font_id); | 467 | font_unload(font_id); |
517 | font_id = font_load_ex(path, buffer_size); | 468 | font_id = font_load_ex(path, bufsize, glyphs); |
518 | if (font_id < 0) | 469 | if (font_id < 0) |
519 | { | 470 | { |
520 | // not much we can do here, maybe try reloading with the small buffer again | 471 | failed = true; |
521 | return -1; | 472 | font_id = font_load_ex(path, old_bufsize, 0); |
473 | /* we couldn't even get the old size, this shouldn't happen */ | ||
474 | if ( font_id < 0 ) | ||
475 | return -1; | ||
522 | } | 476 | } |
523 | if (old_id != font_id) | 477 | if (old_id != font_id) |
524 | { | 478 | { |
@@ -528,51 +482,100 @@ int font_load_ex(const char *path, size_t buffer_size) | |||
528 | } | 482 | } |
529 | pd = core_get_data(buflib_allocations[font_id]); | 483 | pd = core_get_data(buflib_allocations[font_id]); |
530 | pd->refcount = old_refcount; | 484 | pd->refcount = old_refcount; |
485 | if(failed) | ||
486 | /* return error because we didn't satisfy the new buffer size */ | ||
487 | return -1; | ||
531 | } | 488 | } |
532 | pd->refcount++; | 489 | pd->refcount++; |
533 | //printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount); | 490 | //printf("reusing handle %d for %s (count: %d)\n", font_id, path, pd->refcount); |
491 | close(fd); | ||
534 | return font_id; | 492 | return font_id; |
535 | } | 493 | } |
536 | 494 | ||
495 | int open_slot = -1; | ||
496 | |||
537 | for (font_id = FONT_FIRSTUSERFONT; font_id < MAXFONTS; font_id++) | 497 | for (font_id = FONT_FIRSTUSERFONT; font_id < MAXFONTS; font_id++) |
538 | { | 498 | { |
539 | handle = buflib_allocations[font_id]; | 499 | if (buflib_allocations[ font_id ] < 0) |
540 | if (handle < 0) | ||
541 | { | 500 | { |
501 | open_slot = font_id; | ||
542 | break; | 502 | break; |
543 | } | 503 | } |
544 | } | 504 | } |
545 | handle = alloc_and_init(font_id, path, buffer_size); | 505 | if ( open_slot == -1 ) |
546 | if (handle < 0) | ||
547 | return -1; | 506 | return -1; |
507 | font_id = open_slot; | ||
548 | 508 | ||
549 | buffer = buffer_from_handle(handle); | 509 | /* allocate mem */ |
550 | lock_font_handle(handle, true); | 510 | int handle = core_alloc_ex( path, |
551 | 511 | bufsize + sizeof( struct buflib_alloc_data ), | |
552 | if (!internal_load_font(font_id, path, buffer, buffer_size, handle)) | 512 | &buflibops ); |
513 | if ( handle < 0 ) | ||
553 | { | 514 | { |
554 | lock_font_handle(handle, false); | ||
555 | core_free(handle); | ||
556 | buflib_allocations[font_id] = -1; | ||
557 | return -1; | 515 | return -1; |
558 | } | 516 | } |
559 | 517 | struct buflib_alloc_data *pdata; | |
560 | lock_font_handle(handle, false); | 518 | pdata = core_get_data(handle); |
519 | pdata->handle_locks = 1; | ||
520 | pdata->refcount = 1; | ||
521 | |||
522 | /* load and init */ | ||
523 | struct font *pf = pf_from_handle( handle ); | ||
524 | memcpy(pf, &f, sizeof( struct font) ); | ||
525 | |||
526 | pf->fd = fd; | ||
527 | pf->fd_width = pf->fd_offset = -1; | ||
528 | pf->handle = handle; | ||
529 | |||
530 | pf->buffer_start = buffer_from_handle( pf->handle ); | ||
531 | pf->buffer_position = pf->buffer_start + FONT_HEADER_SIZE; | ||
532 | pf->buffer_size = bufsize; | ||
533 | pf->buffer_end = pf->buffer_start + bufsize; | ||
534 | |||
535 | if ( cached ) | ||
536 | { | ||
537 | if ( ! font_load_cached( pf, nwidth, noffset ) ) | ||
538 | { | ||
539 | core_free( handle ); | ||
540 | return -1; | ||
541 | } | ||
542 | |||
543 | /* trick to get a small cache for each file section * | ||
544 | * during glyph_cache_load() */ | ||
545 | pf->fd_width = open( path, O_RDONLY|O_BINARY ); | ||
546 | pf->fd_offset = open( path, O_RDONLY|O_BINARY ); | ||
547 | |||
548 | glyph_cache_load( path, pf ); | ||
549 | |||
550 | /* cached font: pf->fd stays open until the font is unloaded */ | ||
551 | close( pf->fd_width ); | ||
552 | pf->fd_width = -1; | ||
553 | close( pf->fd_offset ); | ||
554 | pf->fd_offset = -1; | ||
555 | } | ||
556 | else | ||
557 | { | ||
558 | lseek( fd, 0, SEEK_SET); | ||
559 | read(fd, pf->buffer_start, pf->buffer_size); | ||
560 | |||
561 | close( fd ); | ||
562 | pf->fd = -1; | ||
563 | |||
564 | if ( ! font_load_in_memory( pf, nwidth, noffset ) ) | ||
565 | { | ||
566 | core_free( handle ); | ||
567 | return -1; | ||
568 | } | ||
569 | } | ||
561 | buflib_allocations[font_id] = handle; | 570 | buflib_allocations[font_id] = handle; |
562 | //printf("%s -> [%d] -> %d\n", path, font_id, *handle); | 571 | //printf("%s -> [%d] -> %d\n", path, font_id, *handle); |
572 | lock_font_handle( handle, false ); | ||
563 | return font_id; /* success!*/ | 573 | return font_id; /* success!*/ |
564 | } | 574 | } |
575 | |||
565 | int font_load(const char *path) | 576 | int font_load(const char *path) |
566 | { | 577 | { |
567 | int size; | 578 | return font_load_ex(path, MAX_FONT_SIZE, GLYPHS_TO_CACHE); |
568 | int fd = open( path, O_RDONLY ); | ||
569 | if ( fd < 0 ) | ||
570 | return -1; | ||
571 | size = filesize(fd); | ||
572 | if (size > MAX_FONT_SIZE) | ||
573 | size = MAX_FONT_SIZE; | ||
574 | close(fd); | ||
575 | return font_load_ex(path, size); | ||
576 | } | 579 | } |
577 | 580 | ||
578 | void font_unload(int font_id) | 581 | void font_unload(int font_id) |
@@ -640,22 +643,6 @@ struct font* font_get(int font) | |||
640 | } | 643 | } |
641 | } | 644 | } |
642 | 645 | ||
643 | static int pf_to_handle(struct font* pf) | ||
644 | { | ||
645 | int i; | ||
646 | for (i=0; i<MAXFONTS; i++) | ||
647 | { | ||
648 | int handle = buflib_allocations[i]; | ||
649 | if (handle > 0) | ||
650 | { | ||
651 | struct buflib_alloc_data *pdata = core_get_data(handle); | ||
652 | if (pf == &pdata->font) | ||
653 | return handle; | ||
654 | } | ||
655 | } | ||
656 | return -1; | ||
657 | } | ||
658 | |||
659 | /* | 646 | /* |
660 | * Reads an entry into cache entry | 647 | * Reads an entry into cache entry |
661 | */ | 648 | */ |
@@ -663,13 +650,12 @@ static void | |||
663 | load_cache_entry(struct font_cache_entry* p, void* callback_data) | 650 | load_cache_entry(struct font_cache_entry* p, void* callback_data) |
664 | { | 651 | { |
665 | struct font* pf = callback_data; | 652 | struct font* pf = callback_data; |
666 | int handle = pf_to_handle(pf); | 653 | |
667 | unsigned short char_code = p->_char_code; | 654 | unsigned short char_code = p->_char_code; |
668 | unsigned char tmp[2]; | 655 | unsigned char tmp[2]; |
669 | int fd; | 656 | int fd; |
670 | 657 | ||
671 | if (handle > 0) | 658 | lock_font_handle(pf->handle, true); |
672 | lock_font_handle(handle, true); | ||
673 | if (pf->file_width_offset) | 659 | if (pf->file_width_offset) |
674 | { | 660 | { |
675 | int width_offset = pf->file_width_offset + char_code; | 661 | int width_offset = pf->file_width_offset + char_code; |
@@ -714,8 +700,7 @@ load_cache_entry(struct font_cache_entry* p, void* callback_data) | |||
714 | int src_bytes = glyph_bytes(pf, p->width); | 700 | int src_bytes = glyph_bytes(pf, p->width); |
715 | read(pf->fd, p->bitmap, src_bytes); | 701 | read(pf->fd, p->bitmap, src_bytes); |
716 | 702 | ||
717 | if (handle > 0) | 703 | lock_font_handle(pf->handle, false); |
718 | lock_font_handle(handle, false); | ||
719 | } | 704 | } |
720 | 705 | ||
721 | /* | 706 | /* |
@@ -756,7 +741,7 @@ const unsigned char* font_get_bits(struct font* pf, unsigned short char_code) | |||
756 | 741 | ||
757 | if (pf->fd >= 0 && pf != &sysfont) | 742 | if (pf->fd >= 0 && pf != &sysfont) |
758 | { | 743 | { |
759 | bits = | 744 | bits = |
760 | (unsigned char*)font_cache_get(&pf->cache,char_code,load_cache_entry, pf)->bitmap; | 745 | (unsigned char*)font_cache_get(&pf->cache,char_code,load_cache_entry, pf)->bitmap; |
761 | } | 746 | } |
762 | else | 747 | else |
@@ -850,49 +835,13 @@ void glyph_cache_save(int font_id) | |||
850 | return; | 835 | return; |
851 | } | 836 | } |
852 | 837 | ||
853 | int font_glyphs_to_bufsize(const char *path, int glyphs) | ||
854 | { | ||
855 | struct font f; | ||
856 | int bufsize; | ||
857 | char buf[FONT_HEADER_SIZE]; | ||
858 | |||
859 | f.buffer_start = buf; | ||
860 | f.buffer_size = sizeof(buf); | ||
861 | f.buffer_position = buf; | ||
862 | |||
863 | f.fd = open(path, O_RDONLY|O_BINARY); | ||
864 | if(f.fd < 0) | ||
865 | return 0; | ||
866 | |||
867 | read(f.fd, f.buffer_position, FONT_HEADER_SIZE); | ||
868 | f.buffer_end = f.buffer_position + FONT_HEADER_SIZE; | ||
869 | |||
870 | if( !font_load_header(&f) ) | ||
871 | { | ||
872 | close(f.fd); | ||
873 | return 0; | ||
874 | } | ||
875 | close(f.fd); | ||
876 | |||
877 | bufsize = LRU_SLOT_OVERHEAD + sizeof(struct font_cache_entry) + | ||
878 | sizeof( unsigned short); | ||
879 | bufsize += glyph_bytes(&f, f.maxwidth); | ||
880 | bufsize *= glyphs; | ||
881 | if ( bufsize < FONT_HEADER_SIZE ) | ||
882 | bufsize = FONT_HEADER_SIZE; | ||
883 | return bufsize; | ||
884 | } | ||
885 | 838 | ||
886 | static int ushortcmp(const void *a, const void *b) | 839 | static int ushortcmp(const void *a, const void *b) |
887 | { | 840 | { |
888 | return ((int)(*(unsigned short*)a - *(unsigned short*)b)); | 841 | return ((int)(*(unsigned short*)a - *(unsigned short*)b)); |
889 | } | 842 | } |
890 | static void glyph_cache_load(int font_id) | 843 | static void glyph_cache_load(const char *font_path, struct font *pf) |
891 | { | 844 | { |
892 | int handle = buflib_allocations[font_id]; | ||
893 | if (handle < 0) | ||
894 | return; | ||
895 | struct font *pf = pf_from_handle(handle); | ||
896 | #define MAX_SORT 256 | 845 | #define MAX_SORT 256 |
897 | if (pf->fd >= 0) { | 846 | if (pf->fd >= 0) { |
898 | int i, size, fd; | 847 | int i, size, fd; |
@@ -907,7 +856,7 @@ static void glyph_cache_load(int font_id) | |||
907 | sort_size = MAX_SORT; | 856 | sort_size = MAX_SORT; |
908 | 857 | ||
909 | char filename[MAX_PATH]; | 858 | char filename[MAX_PATH]; |
910 | font_path_to_glyph_path(font_filename(font_id), filename); | 859 | font_path_to_glyph_path(font_path, filename); |
911 | 860 | ||
912 | fd = open(filename, O_RDONLY|O_BINARY); | 861 | fd = open(filename, O_RDONLY|O_BINARY); |
913 | #ifdef TRY_DEFAULT_GLYPHCACHE | 862 | #ifdef TRY_DEFAULT_GLYPHCACHE |