diff options
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/font.c | 62 |
1 files changed, 55 insertions, 7 deletions
diff --git a/firmware/font.c b/firmware/font.c index b8ad76ec3a..d4f0dfa77a 100644 --- a/firmware/font.c +++ b/firmware/font.c | |||
@@ -28,6 +28,7 @@ | |||
28 | 28 | ||
29 | #include <stdio.h> | 29 | #include <stdio.h> |
30 | #include <string.h> | 30 | #include <string.h> |
31 | #include <stdlib.h> | ||
31 | #include "inttypes.h" | 32 | #include "inttypes.h" |
32 | #include "lcd.h" | 33 | #include "lcd.h" |
33 | #include "font.h" | 34 | #include "font.h" |
@@ -57,7 +58,6 @@ | |||
57 | #define FONT_HEADER_SIZE 36 | 58 | #define FONT_HEADER_SIZE 36 |
58 | #endif | 59 | #endif |
59 | 60 | ||
60 | |||
61 | #ifndef BOOTLOADER | 61 | #ifndef BOOTLOADER |
62 | /* Font cache includes */ | 62 | /* Font cache includes */ |
63 | #include "font_cache.h" | 63 | #include "font_cache.h" |
@@ -586,9 +586,12 @@ static void glyph_file_write(void* data) | |||
586 | unsigned short ch; | 586 | unsigned short ch; |
587 | unsigned char tmp[2]; | 587 | unsigned char tmp[2]; |
588 | 588 | ||
589 | if ( p->_char_code == 0xffff ) | ||
590 | return; | ||
591 | |||
589 | ch = p->_char_code + pf->firstchar; | 592 | ch = p->_char_code + pf->firstchar; |
590 | 593 | ||
591 | if (ch != 0xffff && cache_fd >= 0) { | 594 | if ( cache_fd >= 0) { |
592 | tmp[0] = ch >> 8; | 595 | tmp[0] = ch >> 8; |
593 | tmp[1] = ch & 0xff; | 596 | tmp[1] = ch & 0xff; |
594 | if (write(cache_fd, tmp, 2) != 2) { | 597 | if (write(cache_fd, tmp, 2) != 2) { |
@@ -625,28 +628,73 @@ void glyph_cache_save(struct font* pf) | |||
625 | return; | 628 | return; |
626 | } | 629 | } |
627 | 630 | ||
631 | static int ushortcmp(const void *a, const void *b) | ||
632 | { | ||
633 | return ((int)(*(unsigned short*)a - *(unsigned short*)b)); | ||
634 | } | ||
628 | static void glyph_cache_load(struct font* pf) | 635 | static void glyph_cache_load(struct font* pf) |
629 | { | 636 | { |
637 | |||
638 | #define MAX_SORT 256 | ||
630 | if (pf->fd >= 0) { | 639 | if (pf->fd >= 0) { |
631 | int fd; | 640 | int fd; |
641 | int i, size; | ||
632 | unsigned char tmp[2]; | 642 | unsigned char tmp[2]; |
633 | unsigned short ch; | 643 | unsigned short ch; |
634 | char path[MAX_PATH]; | 644 | char path[MAX_PATH]; |
645 | unsigned short glyphs[MAX_SORT]; | ||
646 | unsigned short glyphs_lru_order[MAX_SORT]; | ||
647 | int glyph_file_skip=0, glyph_file_size=0; | ||
648 | |||
649 | int sort_size = pf->cache._capacity; | ||
650 | if ( sort_size > MAX_SORT ) | ||
651 | sort_size = MAX_SORT; | ||
635 | 652 | ||
636 | fd = open(get_user_file_path(GLYPH_CACHE_FILE, IS_FILE|NEED_WRITE, | 653 | fd = open(get_user_file_path(GLYPH_CACHE_FILE, IS_FILE|NEED_WRITE, |
637 | path, sizeof(path)), O_RDONLY|O_BINARY); | 654 | path, sizeof(path)), O_RDONLY|O_BINARY); |
638 | if (fd >= 0) { | 655 | if (fd >= 0) { |
656 | |||
657 | /* only read what fits */ | ||
658 | glyph_file_size = filesize( fd ); | ||
659 | if ( glyph_file_size > 2*pf->cache._capacity ) { | ||
660 | glyph_file_skip = glyph_file_size - 2*pf->cache._capacity; | ||
661 | lseek( fd, glyph_file_skip, SEEK_SET ); | ||
662 | } | ||
639 | 663 | ||
640 | while (read(fd, tmp, 2) == 2) { | 664 | while(1) { |
641 | ch = (tmp[0] << 8) | tmp[1]; | 665 | |
642 | font_get_bits(pf, ch); | 666 | for ( size = 0; |
667 | read( fd, tmp, 2 ) == 2 && size < sort_size; | ||
668 | size++ ) | ||
669 | { | ||
670 | glyphs[size] = (tmp[0] << 8) | tmp[1]; | ||
671 | glyphs_lru_order[size] = glyphs[size]; | ||
672 | } | ||
673 | |||
674 | /* sort glyphs array to make sector cache happy */ | ||
675 | qsort((void *)glyphs, size, sizeof(unsigned short), | ||
676 | ushortcmp ); | ||
677 | |||
678 | /* load font bitmaps */ | ||
679 | i = 0; | ||
680 | font_get_bits(pf, glyphs[i]); | ||
681 | for ( i = 1; i < size ; i++) { | ||
682 | if ( glyphs[i] != glyphs[i-1] ) | ||
683 | font_get_bits(pf, glyphs[i]); | ||
684 | } | ||
685 | |||
686 | /* redo to fix lru order */ | ||
687 | for ( i = 0; i < size ; i++) | ||
688 | font_get_bits(pf, glyphs_lru_order[i]); | ||
689 | |||
690 | if ( size < sort_size ) | ||
691 | break; | ||
643 | } | 692 | } |
644 | 693 | ||
645 | close(fd); | 694 | close(fd); |
646 | } else { | 695 | } else { |
647 | /* load latin1 chars into cache */ | 696 | /* load latin1 chars into cache */ |
648 | ch = 256; | 697 | for ( ch = 32 ; ch < 256 ; ch++ ); |
649 | while (ch-- > 32) | ||
650 | font_get_bits(pf, ch); | 698 | font_get_bits(pf, ch); |
651 | } | 699 | } |
652 | } | 700 | } |