1
0
Fork 0
forked from len0rd/rockbox

Player: Only use one software definable character for different characters using the same glyph. * Some cleanup.

git-svn-id: svn://svn.rockbox.org/rockbox/trunk@13043 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
Jens Arnold 2007-04-06 11:20:39 +00:00
parent 4303ab02a3
commit 60b99811eb
2 changed files with 49 additions and 46 deletions

View file

@ -26,7 +26,6 @@
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "file.h" #include "file.h"
#include "debug.h"
#include "system.h" #include "system.h"
#include "lcd-charcell.h" #include "lcd-charcell.h"
#include "rbunicode.h" #include "rbunicode.h"
@ -35,6 +34,8 @@
#define SCROLLABLE_LINES LCD_HEIGHT #define SCROLLABLE_LINES LCD_HEIGHT
#define VARIABLE_XCHARS 16 /* number of software user-definable characters */ #define VARIABLE_XCHARS 16 /* number of software user-definable characters */
/* There must be mappings for this many characters in the 0xe000 unicode range
* in lcd-charset-<target>.c */
#define NO_PATTERN (-1) #define NO_PATTERN (-1)
@ -42,8 +43,8 @@ static int find_xchar(unsigned long ucs);
/** globals **/ /** globals **/
/* The "frame"buffer */ unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH]; /* The "frame"buffer */
unsigned char lcd_charbuffer[LCD_HEIGHT][LCD_WIDTH]; static unsigned char lcd_substbuffer[LCD_HEIGHT][LCD_WIDTH];
struct pattern_info lcd_patterns[MAX_HW_PATTERNS]; struct pattern_info lcd_patterns[MAX_HW_PATTERNS];
struct cursor_info lcd_cursor; struct cursor_info lcd_cursor;
@ -141,44 +142,30 @@ static int find_xchar(unsigned long ucs)
return xchar_info_size - 1; return xchar_info_size - 1;
} }
static int xchar_to_pat(int xchar) static int glyph_to_pat(unsigned glyph)
{ {
int i; int i;
for (i = 0; i < lcd_pattern_count; i++) for (i = 0; i < lcd_pattern_count; i++)
if (lcd_patterns[i].xchar == xchar) if (lcd_patterns[i].glyph == glyph)
return i; return i;
return NO_PATTERN; return NO_PATTERN;
} }
static const unsigned char *xchar_to_glyph(int xchar) static void lcd_free_pat(int pat)
{
unsigned index = xchar_info[xchar].glyph;
if (index & 0x8000)
return xfont_variable[index & 0x7fff];
else
return xfont_fixed[index];
}
static void lcd_free_pat(int xchar)
{ {
int x, y; int x, y;
unsigned char substitute;
int pat = xchar_to_pat(xchar);
if (pat != NO_PATTERN) if (pat != NO_PATTERN)
{ {
substitute = xchar_info[xchar].hw_char;
for (x = 0; x < LCD_WIDTH; x++) for (x = 0; x < LCD_WIDTH; x++)
for (y = 0; y < LCD_HEIGHT; y++) for (y = 0; y < LCD_HEIGHT; y++)
if (pat == lcd_charbuffer[y][x]) if (pat == lcd_charbuffer[y][x])
lcd_charbuffer[y][x] = substitute; lcd_charbuffer[y][x] = lcd_substbuffer[y][x];
if (lcd_cursor.enabled && pat == lcd_cursor.hw_char) if (lcd_cursor.enabled && pat == lcd_cursor.hw_char)
lcd_cursor.hw_char = substitute; lcd_cursor.hw_char = lcd_cursor.subst_char;
lcd_patterns[pat].count = 0; lcd_patterns[pat].count = 0;
} }
@ -190,7 +177,7 @@ static int lcd_get_free_pat(int xchar)
int pat = last_used_pat; /* start from last used pattern */ int pat = last_used_pat; /* start from last used pattern */
int least_pat = pat; /* pattern with least priority */ int least_pat = pat; /* pattern with least priority */
int least_priority = xchar_info[lcd_patterns[pat].xchar].priority; int least_priority = lcd_patterns[pat].priority;
int i; int i;
for (i = 0; i < lcd_pattern_count; i++) for (i = 0; i < lcd_pattern_count; i++)
@ -200,44 +187,58 @@ static int lcd_get_free_pat(int xchar)
if (lcd_patterns[pat].count == 0) if (lcd_patterns[pat].count == 0)
{ {
lcd_patterns[pat].xchar = xchar;
last_used_pat = pat; last_used_pat = pat;
return pat; return pat;
} }
if (xchar_info[lcd_patterns[pat].xchar].priority < least_priority) if (lcd_patterns[pat].priority < least_priority)
{ {
least_priority = xchar_info[lcd_patterns[pat].xchar].priority; least_priority = lcd_patterns[pat].priority;
least_pat = pat; least_pat = pat;
} }
} }
if (xchar_info[xchar].priority > least_priority) /* prioritized char */ if (xchar_info[xchar].priority > least_priority) /* prioritized char */
{ {
lcd_free_pat(lcd_patterns[least_pat].xchar); lcd_free_pat(least_pat);
lcd_patterns[least_pat].xchar = xchar;
last_used_pat = least_pat; last_used_pat = least_pat;
return least_pat; return least_pat;
} }
return NO_PATTERN; return NO_PATTERN;
} }
static int map_xchar(int xchar) static const unsigned char *glyph_to_pattern(unsigned glyph)
{
if (glyph & 0x8000)
return xfont_variable[glyph & 0x7fff];
else
return xfont_fixed[glyph];
}
static int map_xchar(int xchar, unsigned char *substitute)
{ {
int pat; int pat;
unsigned glyph;
if (xchar_info[xchar].priority > 0) /* soft char */ if (xchar_info[xchar].priority > 0) /* soft char */
{ {
pat = xchar_to_pat(xchar); glyph = xchar_info[xchar].glyph;
pat = glyph_to_pat(glyph);
if (pat == NO_PATTERN) /* not yet mapped */ if (pat == NO_PATTERN) /* not yet mapped */
{ {
pat = lcd_get_free_pat(xchar); /* try to map */ pat = lcd_get_free_pat(xchar); /* try to map */
if (pat == NO_PATTERN) /* failed: just use substitute */ if (pat == NO_PATTERN) /* failed: just use substitute */
return xchar_info[xchar].hw_char; return xchar_info[xchar].hw_char;
else /* define pattern */ else
memcpy(lcd_patterns[pat].pattern, xchar_to_glyph(xchar), { /* define pattern */
lcd_patterns[pat].priority = xchar_info[xchar].priority;
lcd_patterns[pat].glyph = glyph;
memcpy(lcd_patterns[pat].pattern, glyph_to_pattern(glyph),
HW_PATTERN_SIZE); HW_PATTERN_SIZE);
}
} }
lcd_patterns[pat].count++; /* increase reference count */ lcd_patterns[pat].count++; /* increase reference count */
*substitute = xchar_info[xchar].hw_char;
return pat; return pat;
} }
else /* hardware char */ else /* hardware char */
@ -248,10 +249,10 @@ static void lcd_putxchar(int x, int y, int xchar)
{ {
int lcd_char = lcd_charbuffer[y][x]; int lcd_char = lcd_charbuffer[y][x];
if (lcd_char < lcd_pattern_count) /* old char was soft */ if (lcd_char < lcd_pattern_count) /* old char was soft */
lcd_patterns[lcd_char].count--; /* decrease old reference count */ lcd_patterns[lcd_char].count--; /* decrease old reference count */
lcd_charbuffer[y][x] = map_xchar(xchar); lcd_charbuffer[y][x] = map_xchar(xchar, &lcd_substbuffer[y][x]);
} }
/** user-definable pattern handling **/ /** user-definable pattern handling **/
@ -274,25 +275,25 @@ unsigned long lcd_get_locked_pattern(void)
void lcd_unlock_pattern(unsigned long ucs) void lcd_unlock_pattern(unsigned long ucs)
{ {
int xchar = find_xchar(ucs); int xchar = find_xchar(ucs);
int index = xchar_info[xchar].glyph; unsigned glyph = xchar_info[xchar].glyph;
if (index & 0x8000) /* variable extended char */ if (glyph & 0x8000) /* variable extended char */
{ {
lcd_free_pat(xchar); lcd_free_pat(glyph_to_pat(glyph));
xfont_variable_locked[index & 0x7fff] = false; xfont_variable_locked[glyph & 0x7fff] = false;
} }
} }
void lcd_define_pattern(unsigned long ucs, const char *pattern) void lcd_define_pattern(unsigned long ucs, const char *pattern)
{ {
int xchar = find_xchar(ucs); int xchar = find_xchar(ucs);
int index = xchar_info[xchar].glyph; unsigned glyph = xchar_info[xchar].glyph;
int pat; int pat;
if (index & 0x8000) /* variable extended char */ if (glyph & 0x8000) /* variable extended char */
{ {
memcpy(xfont_variable[index & 0x7fff], pattern, HW_PATTERN_SIZE); memcpy(xfont_variable[glyph & 0x7fff], pattern, HW_PATTERN_SIZE);
pat = xchar_to_pat(xchar); pat = glyph_to_pat(glyph);
if (pat != NO_PATTERN) if (pat != NO_PATTERN)
{ {
memcpy(lcd_patterns[pat].pattern, pattern, HW_PATTERN_SIZE); memcpy(lcd_patterns[pat].pattern, pattern, HW_PATTERN_SIZE);
@ -337,7 +338,7 @@ void lcd_put_cursor(int x, int y, unsigned long cursor_ucs)
lcd_cursor.enabled = true; lcd_cursor.enabled = true;
lcd_cursor.visible = false; lcd_cursor.visible = false;
lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs)); lcd_cursor.hw_char = map_xchar(find_xchar(cursor_ucs), &lcd_cursor.subst_char);
lcd_cursor.x = x; lcd_cursor.x = x;
lcd_cursor.y = y; lcd_cursor.y = y;
lcd_cursor.downcount = 0; lcd_cursor.downcount = 0;

View file

@ -25,6 +25,7 @@
struct cursor_info { struct cursor_info {
unsigned char hw_char; unsigned char hw_char;
unsigned char subst_char;
bool enabled; bool enabled;
bool visible; bool visible;
int x; int x;
@ -47,7 +48,8 @@ struct xchar_info {
/* track usage of user-definable characters */ /* track usage of user-definable characters */
struct pattern_info { struct pattern_info {
short count; short count;
unsigned short xchar; unsigned short glyph;
unsigned char priority;
unsigned char pattern[HW_PATTERN_SIZE]; unsigned char pattern[HW_PATTERN_SIZE];
}; };