mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-12-07 13:45:03 -05:00
keyboard: change how charactars are stored in the buffer.
* try to keep the layout when font is changed or when the buffer is fully used. * don't waste the buffer by filling by spaces. git-svn-id: svn://svn.rockbox.org/rockbox/trunk@27370 a1c6a512-1295-4272-9138-f99709370657
This commit is contained in:
parent
1423874007
commit
3d29faa011
1 changed files with 82 additions and 86 deletions
|
|
@ -79,7 +79,8 @@ struct keyboard_parameters
|
||||||
unsigned short kbd_buf[KBD_BUF_SIZE];
|
unsigned short kbd_buf[KBD_BUF_SIZE];
|
||||||
unsigned short max_line_len;
|
unsigned short max_line_len;
|
||||||
int default_lines;
|
int default_lines;
|
||||||
int nchars;
|
int last_k;
|
||||||
|
int last_i;
|
||||||
int font_w;
|
int font_w;
|
||||||
int font_h;
|
int font_h;
|
||||||
int text_w;
|
int text_w;
|
||||||
|
|
@ -143,6 +144,7 @@ int load_kbd(unsigned char* filename)
|
||||||
int fd, l;
|
int fd, l;
|
||||||
int i, line_len, max_line_len;
|
int i, line_len, max_line_len;
|
||||||
unsigned char buf[4];
|
unsigned char buf[4];
|
||||||
|
unsigned short *pbuf;
|
||||||
|
|
||||||
if (filename == NULL)
|
if (filename == NULL)
|
||||||
{
|
{
|
||||||
|
|
@ -154,10 +156,11 @@ int load_kbd(unsigned char* filename)
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
pbuf = kbd_param[0].kbd_buf;
|
||||||
line_len = 0;
|
line_len = 0;
|
||||||
max_line_len = 1;
|
max_line_len = 1;
|
||||||
i = 0;
|
i = 1;
|
||||||
while (read(fd, buf, 1) == 1 && i < KBD_BUF_SIZE)
|
while (read(fd, buf, 1) == 1 && i < KBD_BUF_SIZE-1)
|
||||||
{
|
{
|
||||||
/* check how many bytes to read for this character */
|
/* check how many bytes to read for this character */
|
||||||
static const unsigned char sizes[4] = { 0x80, 0xe0, 0xf0, 0xf5 };
|
static const unsigned char sizes[4] = { 0x80, 0xe0, 0xf0, 0xf5 };
|
||||||
|
|
@ -183,17 +186,17 @@ int load_kbd(unsigned char* filename)
|
||||||
utf8decode(buf, &ch);
|
utf8decode(buf, &ch);
|
||||||
if (ch != 0xFEFF && ch != '\r') /* skip BOM & carriage returns */
|
if (ch != 0xFEFF && ch != '\r') /* skip BOM & carriage returns */
|
||||||
{
|
{
|
||||||
FOR_NB_SCREENS(l)
|
|
||||||
kbd_param[l].kbd_buf[i] = ch;
|
|
||||||
i++;
|
i++;
|
||||||
if (ch == '\n')
|
if (ch == '\n')
|
||||||
{
|
{
|
||||||
if (max_line_len < line_len)
|
if (max_line_len < line_len)
|
||||||
max_line_len = line_len;
|
max_line_len = line_len;
|
||||||
|
*pbuf = line_len;
|
||||||
|
pbuf += line_len + 1;
|
||||||
line_len = 0;
|
line_len = 0;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
line_len++;
|
pbuf[++line_len] = ch;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -202,11 +205,20 @@ int load_kbd(unsigned char* filename)
|
||||||
|
|
||||||
if (max_line_len < line_len)
|
if (max_line_len < line_len)
|
||||||
max_line_len = line_len;
|
max_line_len = line_len;
|
||||||
|
if (i == 1 || line_len != 0) /* ignore last empty line */
|
||||||
|
{
|
||||||
|
*pbuf = line_len;
|
||||||
|
pbuf += line_len + 1;
|
||||||
|
}
|
||||||
|
*pbuf = 0xFEFF; /* mark end of characters */
|
||||||
|
i++;
|
||||||
FOR_NB_SCREENS(l)
|
FOR_NB_SCREENS(l)
|
||||||
{
|
{
|
||||||
struct keyboard_parameters *pm = &kbd_param[l];
|
struct keyboard_parameters *pm = &kbd_param[l];
|
||||||
pm->nchars = i;
|
#if NB_SCREENS > 1
|
||||||
|
if (l > 0)
|
||||||
|
memcpy(pm->kbd_buf, kbd_param[0].kbd_buf, i*sizeof(unsigned short));
|
||||||
|
#endif
|
||||||
/* initialize parameters */
|
/* initialize parameters */
|
||||||
pm->x = pm->y = pm->page = 0;
|
pm->x = pm->y = pm->page = 0;
|
||||||
pm->default_lines = 0;
|
pm->default_lines = 0;
|
||||||
|
|
@ -269,10 +281,28 @@ static void kbd_delchar(struct edit_state *state)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Lookup k value based on state of param (pm) */
|
/* Lookup k value based on state of param (pm) */
|
||||||
static unsigned short get_kbd_ch(const struct keyboard_parameters *pm)
|
static unsigned short get_kbd_ch(struct keyboard_parameters *pm, int x, int y)
|
||||||
{
|
{
|
||||||
int k = (pm->page*pm->lines + pm->y)*pm->max_chars + pm->x;
|
int i = 0, k = pm->page*pm->lines + y, n;
|
||||||
return (k < pm->nchars)? pm->kbd_buf[k]: ' ';
|
unsigned short *pbuf;
|
||||||
|
if (k >= pm->last_k)
|
||||||
|
{
|
||||||
|
i = pm->last_i;
|
||||||
|
k -= pm->last_k;
|
||||||
|
}
|
||||||
|
for (pbuf = &pm->kbd_buf[i]; (i = *pbuf) != 0xFEFF; pbuf += i + 1)
|
||||||
|
{
|
||||||
|
n = i ? (i + pm->max_chars - 1) / pm->max_chars : 1;
|
||||||
|
if (k < n) break;
|
||||||
|
k -= n;
|
||||||
|
}
|
||||||
|
if (y == 0 && i != 0xFEFF)
|
||||||
|
{
|
||||||
|
pm->last_k = pm->page*pm->lines - k;
|
||||||
|
pm->last_i = pbuf - pm->kbd_buf;
|
||||||
|
}
|
||||||
|
k = k * pm->max_chars + x;
|
||||||
|
return (*pbuf != 0xFEFF && k < *pbuf)? pbuf[k+1]: ' ';
|
||||||
}
|
}
|
||||||
|
|
||||||
static void kbd_calc_params(struct keyboard_parameters *pm,
|
static void kbd_calc_params(struct keyboard_parameters *pm,
|
||||||
|
|
@ -341,8 +371,9 @@ int kbd_input(char* text, int buflen)
|
||||||
FOR_NB_SCREENS(l)
|
FOR_NB_SCREENS(l)
|
||||||
{
|
{
|
||||||
struct keyboard_parameters *pm = ¶m[l];
|
struct keyboard_parameters *pm = ¶m[l];
|
||||||
|
unsigned short *pbuf;
|
||||||
const unsigned char *p;
|
const unsigned char *p;
|
||||||
int i = 0;
|
int len = 0;
|
||||||
|
|
||||||
#if LCD_WIDTH >= 160 && LCD_HEIGHT >= 96
|
#if LCD_WIDTH >= 160 && LCD_HEIGHT >= 96
|
||||||
struct screen *sc = &screens[l];
|
struct screen *sc = &screens[l];
|
||||||
|
|
@ -383,10 +414,22 @@ int kbd_input(char* text, int buflen)
|
||||||
pm->max_line_len = 18;
|
pm->max_line_len = 18;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pbuf = pm->kbd_buf;
|
||||||
while (*p)
|
while (*p)
|
||||||
p = utf8decode(p, &pm->kbd_buf[i++]);
|
{
|
||||||
|
p = utf8decode(p, &pbuf[len+1]);
|
||||||
|
if (pbuf[len+1] == '\n')
|
||||||
|
{
|
||||||
|
*pbuf = len;
|
||||||
|
pbuf += len+1;
|
||||||
|
len = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
len++;
|
||||||
|
}
|
||||||
|
*pbuf = len;
|
||||||
|
pbuf[len+1] = 0xFEFF; /* mark end of characters */
|
||||||
|
|
||||||
pm->nchars = i;
|
|
||||||
/* initialize parameters */
|
/* initialize parameters */
|
||||||
pm->x = pm->y = pm->page = 0;
|
pm->x = pm->y = pm->page = 0;
|
||||||
}
|
}
|
||||||
|
|
@ -628,7 +671,7 @@ int kbd_input(char* text, int buflen)
|
||||||
if (!state.morse_mode)
|
if (!state.morse_mode)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
ch = get_kbd_ch(pm);
|
ch = get_kbd_ch(pm, pm->x, pm->y);
|
||||||
kbd_spellchar(ch);
|
kbd_spellchar(ch);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -671,7 +714,7 @@ static void kbd_calc_params(struct keyboard_parameters *pm,
|
||||||
{
|
{
|
||||||
struct font* font;
|
struct font* font;
|
||||||
const unsigned char *p;
|
const unsigned char *p;
|
||||||
unsigned short ch;
|
unsigned short ch, *pbuf;
|
||||||
int icon_w, sc_w, sc_h, w;
|
int icon_w, sc_w, sc_h, w;
|
||||||
int i, total_lines;
|
int i, total_lines;
|
||||||
#ifdef HAVE_TOUCHSCREEN
|
#ifdef HAVE_TOUCHSCREEN
|
||||||
|
|
@ -700,11 +743,11 @@ static void kbd_calc_params(struct keyboard_parameters *pm,
|
||||||
* since we're going to be adding spaces,
|
* since we're going to be adding spaces,
|
||||||
* max width is at least their width */
|
* max width is at least their width */
|
||||||
pm->font_w = font_get_width(font, ' ');
|
pm->font_w = font_get_width(font, ' ');
|
||||||
for (i = 0; i < pm->nchars; i++)
|
for (pbuf = pm->kbd_buf; *pbuf != 0xFEFF; pbuf += i)
|
||||||
{
|
{
|
||||||
if (pm->kbd_buf[i] != '\n')
|
for (i = 0; ++i <= *pbuf; )
|
||||||
{
|
{
|
||||||
w = font_get_width(font, pm->kbd_buf[i]);
|
w = font_get_width(font, pbuf[i]);
|
||||||
if (pm->font_w < w)
|
if (pm->font_w < w)
|
||||||
pm->font_w = w;
|
pm->font_w = w;
|
||||||
}
|
}
|
||||||
|
|
@ -734,54 +777,6 @@ static void kbd_calc_params(struct keyboard_parameters *pm,
|
||||||
if (pm->max_chars_text < 3 && icon_w > pm->text_w)
|
if (pm->max_chars_text < 3 && icon_w > pm->text_w)
|
||||||
pm->max_chars_text = sc_w / pm->text_w - 2;
|
pm->max_chars_text = sc_w / pm->text_w - 2;
|
||||||
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
/* Pad lines with spaces */
|
|
||||||
while (i < pm->nchars)
|
|
||||||
{
|
|
||||||
if (pm->kbd_buf[i] == '\n')
|
|
||||||
{
|
|
||||||
int k = pm->max_chars - i % ( pm->max_chars ) - 1;
|
|
||||||
int j;
|
|
||||||
|
|
||||||
if (k == pm->max_chars - 1)
|
|
||||||
{
|
|
||||||
pm->nchars--;
|
|
||||||
|
|
||||||
for (j = i; j < pm->nchars; j++)
|
|
||||||
{
|
|
||||||
pm->kbd_buf[j] = pm->kbd_buf[j + 1];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (pm->nchars + k - 1 >= KBD_BUF_SIZE)
|
|
||||||
{ /* We don't want to overflow the buffer */
|
|
||||||
k = KBD_BUF_SIZE - pm->nchars;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (j = pm->nchars + k - 1; j > i + k; j--)
|
|
||||||
{
|
|
||||||
pm->kbd_buf[j] = pm->kbd_buf[j-k];
|
|
||||||
}
|
|
||||||
|
|
||||||
pm->nchars += k;
|
|
||||||
k++;
|
|
||||||
|
|
||||||
while (k--)
|
|
||||||
{
|
|
||||||
pm->kbd_buf[i++] = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pm->nchars == 0)
|
|
||||||
pm->kbd_buf[pm->nchars++] = ' ';
|
|
||||||
|
|
||||||
/* calculate pm->pages and pm->lines */
|
/* calculate pm->pages and pm->lines */
|
||||||
sc_h = sc->getheight();
|
sc_h = sc->getheight();
|
||||||
#ifdef HAVE_TOUCHSCREEN
|
#ifdef HAVE_TOUCHSCREEN
|
||||||
|
|
@ -811,7 +806,10 @@ recalc_param:
|
||||||
if (pm->keyboard_margin > DEFAULT_MARGIN)
|
if (pm->keyboard_margin > DEFAULT_MARGIN)
|
||||||
pm->keyboard_margin = DEFAULT_MARGIN;
|
pm->keyboard_margin = DEFAULT_MARGIN;
|
||||||
|
|
||||||
total_lines = (pm->nchars + pm->max_chars - 1) / pm->max_chars;
|
total_lines = 0;
|
||||||
|
for (pbuf = pm->kbd_buf; (i = *pbuf) != 0xFEFF; pbuf += i + 1)
|
||||||
|
total_lines += (i ? (i + pm->max_chars - 1) / pm->max_chars : 1);
|
||||||
|
|
||||||
pm->pages = (total_lines + pm->lines - 1) / pm->lines;
|
pm->pages = (total_lines + pm->lines - 1) / pm->lines;
|
||||||
pm->lines = (total_lines + pm->pages - 1) / pm->pages;
|
pm->lines = (total_lines + pm->pages - 1) / pm->pages;
|
||||||
#ifdef HAVE_TOUCHSCREEN
|
#ifdef HAVE_TOUCHSCREEN
|
||||||
|
|
@ -823,6 +821,8 @@ recalc_param:
|
||||||
goto recalc_param;
|
goto recalc_param;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
if (pm->page >= pm->pages)
|
||||||
|
pm->x = pm->y = pm->page = 0;
|
||||||
|
|
||||||
pm->main_y = pm->font_h*pm->lines + pm->keyboard_margin;
|
pm->main_y = pm->font_h*pm->lines + pm->keyboard_margin;
|
||||||
pm->keyboard_margin -= pm->keyboard_margin/2;
|
pm->keyboard_margin -= pm->keyboard_margin/2;
|
||||||
|
|
@ -899,28 +899,24 @@ static void kbd_draw_picker(struct keyboard_parameters *pm,
|
||||||
#endif /* HAVE_MORSE_INPUT */
|
#endif /* HAVE_MORSE_INPUT */
|
||||||
{
|
{
|
||||||
/* draw page */
|
/* draw page */
|
||||||
int i, j, k;
|
int i, j;
|
||||||
|
int w, h;
|
||||||
|
unsigned short ch;
|
||||||
|
unsigned char *utf8;
|
||||||
|
|
||||||
sc->setfont(pm->curfont);
|
sc->setfont(pm->curfont);
|
||||||
|
|
||||||
k = pm->page*pm->max_chars*pm->lines;
|
for (j = 0; j < pm->lines; j++)
|
||||||
|
|
||||||
for (i = j = 0; k < pm->nchars; k++)
|
|
||||||
{
|
{
|
||||||
int w, h;
|
for (i = 0; i < pm->max_chars; i++)
|
||||||
unsigned char *utf8;
|
|
||||||
utf8 = utf8encode(pm->kbd_buf[k], outline);
|
|
||||||
*utf8 = 0;
|
|
||||||
|
|
||||||
sc->getstringsize(outline, &w, &h);
|
|
||||||
sc->putsxy(i*pm->font_w + (pm->font_w-w) / 2,
|
|
||||||
j*pm->font_h + (pm->font_h-h) / 2, outline);
|
|
||||||
|
|
||||||
if (++i >= pm->max_chars)
|
|
||||||
{
|
{
|
||||||
i = 0;
|
ch = get_kbd_ch(pm, i, j);
|
||||||
if (++j >= pm->lines)
|
utf8 = utf8encode(ch, outline);
|
||||||
break;
|
*utf8 = 0;
|
||||||
|
|
||||||
|
sc->getstringsize(outline, &w, &h);
|
||||||
|
sc->putsxy(i*pm->font_w + (pm->font_w-w) / 2,
|
||||||
|
j*pm->font_h + (pm->font_h-h) / 2, outline);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1131,7 +1127,7 @@ static void kbd_insert_selected(struct keyboard_parameters *pm,
|
||||||
struct edit_state *state)
|
struct edit_state *state)
|
||||||
{
|
{
|
||||||
/* find input char */
|
/* find input char */
|
||||||
unsigned short ch = get_kbd_ch(pm);
|
unsigned short ch = get_kbd_ch(pm, pm->x, pm->y);
|
||||||
|
|
||||||
/* check for hangul input */
|
/* check for hangul input */
|
||||||
if (ch >= 0x3131 && ch <= 0x3163)
|
if (ch >= 0x3131 && ch <= 0x3163)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue