summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTeruaki Kawashima <teru@rockbox.org>2010-07-10 13:09:39 +0000
committerTeruaki Kawashima <teru@rockbox.org>2010-07-10 13:09:39 +0000
commit3d29faa0116f6354df04679987906153ff0a6d17 (patch)
tree781fff1ef5e4e1dfa012f7c64f88e544750a821d
parent14238740074945d8f61e445c5d6211e1c7a50566 (diff)
downloadrockbox-3d29faa0116f6354df04679987906153ff0a6d17.tar.gz
rockbox-3d29faa0116f6354df04679987906153ff0a6d17.zip
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
-rw-r--r--apps/recorder/keyboard.c168
1 files changed, 82 insertions, 86 deletions
diff --git a/apps/recorder/keyboard.c b/apps/recorder/keyboard.c
index 2ec14a8d09..8dea52799f 100644
--- a/apps/recorder/keyboard.c
+++ b/apps/recorder/keyboard.c
@@ -79,7 +79,8 @@ struct keyboard_parameters
79 unsigned short kbd_buf[KBD_BUF_SIZE]; 79 unsigned short kbd_buf[KBD_BUF_SIZE];
80 unsigned short max_line_len; 80 unsigned short max_line_len;
81 int default_lines; 81 int default_lines;
82 int nchars; 82 int last_k;
83 int last_i;
83 int font_w; 84 int font_w;
84 int font_h; 85 int font_h;
85 int text_w; 86 int text_w;
@@ -143,6 +144,7 @@ int load_kbd(unsigned char* filename)
143 int fd, l; 144 int fd, l;
144 int i, line_len, max_line_len; 145 int i, line_len, max_line_len;
145 unsigned char buf[4]; 146 unsigned char buf[4];
147 unsigned short *pbuf;
146 148
147 if (filename == NULL) 149 if (filename == NULL)
148 { 150 {
@@ -154,10 +156,11 @@ int load_kbd(unsigned char* filename)
154 if (fd < 0) 156 if (fd < 0)
155 return 1; 157 return 1;
156 158
159 pbuf = kbd_param[0].kbd_buf;
157 line_len = 0; 160 line_len = 0;
158 max_line_len = 1; 161 max_line_len = 1;
159 i = 0; 162 i = 1;
160 while (read(fd, buf, 1) == 1 && i < KBD_BUF_SIZE) 163 while (read(fd, buf, 1) == 1 && i < KBD_BUF_SIZE-1)
161 { 164 {
162 /* check how many bytes to read for this character */ 165 /* check how many bytes to read for this character */
163 static const unsigned char sizes[4] = { 0x80, 0xe0, 0xf0, 0xf5 }; 166 static const unsigned char sizes[4] = { 0x80, 0xe0, 0xf0, 0xf5 };
@@ -183,17 +186,17 @@ int load_kbd(unsigned char* filename)
183 utf8decode(buf, &ch); 186 utf8decode(buf, &ch);
184 if (ch != 0xFEFF && ch != '\r') /* skip BOM & carriage returns */ 187 if (ch != 0xFEFF && ch != '\r') /* skip BOM & carriage returns */
185 { 188 {
186 FOR_NB_SCREENS(l)
187 kbd_param[l].kbd_buf[i] = ch;
188 i++; 189 i++;
189 if (ch == '\n') 190 if (ch == '\n')
190 { 191 {
191 if (max_line_len < line_len) 192 if (max_line_len < line_len)
192 max_line_len = line_len; 193 max_line_len = line_len;
194 *pbuf = line_len;
195 pbuf += line_len + 1;
193 line_len = 0; 196 line_len = 0;
194 } 197 }
195 else 198 else
196 line_len++; 199 pbuf[++line_len] = ch;
197 } 200 }
198 } 201 }
199 202
@@ -202,11 +205,20 @@ int load_kbd(unsigned char* filename)
202 205
203 if (max_line_len < line_len) 206 if (max_line_len < line_len)
204 max_line_len = line_len; 207 max_line_len = line_len;
205 208 if (i == 1 || line_len != 0) /* ignore last empty line */
209 {
210 *pbuf = line_len;
211 pbuf += line_len + 1;
212 }
213 *pbuf = 0xFEFF; /* mark end of characters */
214 i++;
206 FOR_NB_SCREENS(l) 215 FOR_NB_SCREENS(l)
207 { 216 {
208 struct keyboard_parameters *pm = &kbd_param[l]; 217 struct keyboard_parameters *pm = &kbd_param[l];
209 pm->nchars = i; 218#if NB_SCREENS > 1
219 if (l > 0)
220 memcpy(pm->kbd_buf, kbd_param[0].kbd_buf, i*sizeof(unsigned short));
221#endif
210 /* initialize parameters */ 222 /* initialize parameters */
211 pm->x = pm->y = pm->page = 0; 223 pm->x = pm->y = pm->page = 0;
212 pm->default_lines = 0; 224 pm->default_lines = 0;
@@ -269,10 +281,28 @@ static void kbd_delchar(struct edit_state *state)
269} 281}
270 282
271/* Lookup k value based on state of param (pm) */ 283/* Lookup k value based on state of param (pm) */
272static unsigned short get_kbd_ch(const struct keyboard_parameters *pm) 284static unsigned short get_kbd_ch(struct keyboard_parameters *pm, int x, int y)
273{ 285{
274 int k = (pm->page*pm->lines + pm->y)*pm->max_chars + pm->x; 286 int i = 0, k = pm->page*pm->lines + y, n;
275 return (k < pm->nchars)? pm->kbd_buf[k]: ' '; 287 unsigned short *pbuf;
288 if (k >= pm->last_k)
289 {
290 i = pm->last_i;
291 k -= pm->last_k;
292 }
293 for (pbuf = &pm->kbd_buf[i]; (i = *pbuf) != 0xFEFF; pbuf += i + 1)
294 {
295 n = i ? (i + pm->max_chars - 1) / pm->max_chars : 1;
296 if (k < n) break;
297 k -= n;
298 }
299 if (y == 0 && i != 0xFEFF)
300 {
301 pm->last_k = pm->page*pm->lines - k;
302 pm->last_i = pbuf - pm->kbd_buf;
303 }
304 k = k * pm->max_chars + x;
305 return (*pbuf != 0xFEFF && k < *pbuf)? pbuf[k+1]: ' ';
276} 306}
277 307
278static void kbd_calc_params(struct keyboard_parameters *pm, 308static void kbd_calc_params(struct keyboard_parameters *pm,
@@ -341,8 +371,9 @@ int kbd_input(char* text, int buflen)
341 FOR_NB_SCREENS(l) 371 FOR_NB_SCREENS(l)
342 { 372 {
343 struct keyboard_parameters *pm = &param[l]; 373 struct keyboard_parameters *pm = &param[l];
374 unsigned short *pbuf;
344 const unsigned char *p; 375 const unsigned char *p;
345 int i = 0; 376 int len = 0;
346 377
347#if LCD_WIDTH >= 160 && LCD_HEIGHT >= 96 378#if LCD_WIDTH >= 160 && LCD_HEIGHT >= 96
348 struct screen *sc = &screens[l]; 379 struct screen *sc = &screens[l];
@@ -383,10 +414,22 @@ int kbd_input(char* text, int buflen)
383 pm->max_line_len = 18; 414 pm->max_line_len = 18;
384 } 415 }
385 416
417 pbuf = pm->kbd_buf;
386 while (*p) 418 while (*p)
387 p = utf8decode(p, &pm->kbd_buf[i++]); 419 {
420 p = utf8decode(p, &pbuf[len+1]);
421 if (pbuf[len+1] == '\n')
422 {
423 *pbuf = len;
424 pbuf += len+1;
425 len = 0;
426 }
427 else
428 len++;
429 }
430 *pbuf = len;
431 pbuf[len+1] = 0xFEFF; /* mark end of characters */
388 432
389 pm->nchars = i;
390 /* initialize parameters */ 433 /* initialize parameters */
391 pm->x = pm->y = pm->page = 0; 434 pm->x = pm->y = pm->page = 0;
392 } 435 }
@@ -628,7 +671,7 @@ int kbd_input(char* text, int buflen)
628 if (!state.morse_mode) 671 if (!state.morse_mode)
629#endif 672#endif
630 { 673 {
631 ch = get_kbd_ch(pm); 674 ch = get_kbd_ch(pm, pm->x, pm->y);
632 kbd_spellchar(ch); 675 kbd_spellchar(ch);
633 } 676 }
634 } 677 }
@@ -671,7 +714,7 @@ static void kbd_calc_params(struct keyboard_parameters *pm,
671{ 714{
672 struct font* font; 715 struct font* font;
673 const unsigned char *p; 716 const unsigned char *p;
674 unsigned short ch; 717 unsigned short ch, *pbuf;
675 int icon_w, sc_w, sc_h, w; 718 int icon_w, sc_w, sc_h, w;
676 int i, total_lines; 719 int i, total_lines;
677#ifdef HAVE_TOUCHSCREEN 720#ifdef HAVE_TOUCHSCREEN
@@ -700,11 +743,11 @@ static void kbd_calc_params(struct keyboard_parameters *pm,
700 * since we're going to be adding spaces, 743 * since we're going to be adding spaces,
701 * max width is at least their width */ 744 * max width is at least their width */
702 pm->font_w = font_get_width(font, ' '); 745 pm->font_w = font_get_width(font, ' ');
703 for (i = 0; i < pm->nchars; i++) 746 for (pbuf = pm->kbd_buf; *pbuf != 0xFEFF; pbuf += i)
704 { 747 {
705 if (pm->kbd_buf[i] != '\n') 748 for (i = 0; ++i <= *pbuf; )
706 { 749 {
707 w = font_get_width(font, pm->kbd_buf[i]); 750 w = font_get_width(font, pbuf[i]);
708 if (pm->font_w < w) 751 if (pm->font_w < w)
709 pm->font_w = w; 752 pm->font_w = w;
710 } 753 }
@@ -734,54 +777,6 @@ static void kbd_calc_params(struct keyboard_parameters *pm,
734 if (pm->max_chars_text < 3 && icon_w > pm->text_w) 777 if (pm->max_chars_text < 3 && icon_w > pm->text_w)
735 pm->max_chars_text = sc_w / pm->text_w - 2; 778 pm->max_chars_text = sc_w / pm->text_w - 2;
736 779
737
738 i = 0;
739 /* Pad lines with spaces */
740 while (i < pm->nchars)
741 {
742 if (pm->kbd_buf[i] == '\n')
743 {
744 int k = pm->max_chars - i % ( pm->max_chars ) - 1;
745 int j;
746
747 if (k == pm->max_chars - 1)
748 {
749 pm->nchars--;
750
751 for (j = i; j < pm->nchars; j++)
752 {
753 pm->kbd_buf[j] = pm->kbd_buf[j + 1];
754 }
755 }
756 else
757 {
758 if (pm->nchars + k - 1 >= KBD_BUF_SIZE)
759 { /* We don't want to overflow the buffer */
760 k = KBD_BUF_SIZE - pm->nchars;
761 }
762
763 for (j = pm->nchars + k - 1; j > i + k; j--)
764 {
765 pm->kbd_buf[j] = pm->kbd_buf[j-k];
766 }
767
768 pm->nchars += k;
769 k++;
770
771 while (k--)
772 {
773 pm->kbd_buf[i++] = ' ';
774 }
775 }
776 }
777 else
778 {
779 i++;
780 }
781 }
782 if (pm->nchars == 0)
783 pm->kbd_buf[pm->nchars++] = ' ';
784
785 /* calculate pm->pages and pm->lines */ 780 /* calculate pm->pages and pm->lines */
786 sc_h = sc->getheight(); 781 sc_h = sc->getheight();
787#ifdef HAVE_TOUCHSCREEN 782#ifdef HAVE_TOUCHSCREEN
@@ -811,7 +806,10 @@ recalc_param:
811 if (pm->keyboard_margin > DEFAULT_MARGIN) 806 if (pm->keyboard_margin > DEFAULT_MARGIN)
812 pm->keyboard_margin = DEFAULT_MARGIN; 807 pm->keyboard_margin = DEFAULT_MARGIN;
813 808
814 total_lines = (pm->nchars + pm->max_chars - 1) / pm->max_chars; 809 total_lines = 0;
810 for (pbuf = pm->kbd_buf; (i = *pbuf) != 0xFEFF; pbuf += i + 1)
811 total_lines += (i ? (i + pm->max_chars - 1) / pm->max_chars : 1);
812
815 pm->pages = (total_lines + pm->lines - 1) / pm->lines; 813 pm->pages = (total_lines + pm->lines - 1) / pm->lines;
816 pm->lines = (total_lines + pm->pages - 1) / pm->pages; 814 pm->lines = (total_lines + pm->pages - 1) / pm->pages;
817#ifdef HAVE_TOUCHSCREEN 815#ifdef HAVE_TOUCHSCREEN
@@ -823,6 +821,8 @@ recalc_param:
823 goto recalc_param; 821 goto recalc_param;
824 } 822 }
825#endif 823#endif
824 if (pm->page >= pm->pages)
825 pm->x = pm->y = pm->page = 0;
826 826
827 pm->main_y = pm->font_h*pm->lines + pm->keyboard_margin; 827 pm->main_y = pm->font_h*pm->lines + pm->keyboard_margin;
828 pm->keyboard_margin -= pm->keyboard_margin/2; 828 pm->keyboard_margin -= pm->keyboard_margin/2;
@@ -899,28 +899,24 @@ static void kbd_draw_picker(struct keyboard_parameters *pm,
899#endif /* HAVE_MORSE_INPUT */ 899#endif /* HAVE_MORSE_INPUT */
900 { 900 {
901 /* draw page */ 901 /* draw page */
902 int i, j, k; 902 int i, j;
903 int w, h;
904 unsigned short ch;
905 unsigned char *utf8;
903 906
904 sc->setfont(pm->curfont); 907 sc->setfont(pm->curfont);
905 908
906 k = pm->page*pm->max_chars*pm->lines; 909 for (j = 0; j < pm->lines; j++)
907
908 for (i = j = 0; k < pm->nchars; k++)
909 { 910 {
910 int w, h; 911 for (i = 0; i < pm->max_chars; i++)
911 unsigned char *utf8;
912 utf8 = utf8encode(pm->kbd_buf[k], outline);
913 *utf8 = 0;
914
915 sc->getstringsize(outline, &w, &h);
916 sc->putsxy(i*pm->font_w + (pm->font_w-w) / 2,
917 j*pm->font_h + (pm->font_h-h) / 2, outline);
918
919 if (++i >= pm->max_chars)
920 { 912 {
921 i = 0; 913 ch = get_kbd_ch(pm, i, j);
922 if (++j >= pm->lines) 914 utf8 = utf8encode(ch, outline);
923 break; 915 *utf8 = 0;
916
917 sc->getstringsize(outline, &w, &h);
918 sc->putsxy(i*pm->font_w + (pm->font_w-w) / 2,
919 j*pm->font_h + (pm->font_h-h) / 2, outline);
924 } 920 }
925 } 921 }
926 922
@@ -1131,7 +1127,7 @@ static void kbd_insert_selected(struct keyboard_parameters *pm,
1131 struct edit_state *state) 1127 struct edit_state *state)
1132{ 1128{
1133 /* find input char */ 1129 /* find input char */
1134 unsigned short ch = get_kbd_ch(pm); 1130 unsigned short ch = get_kbd_ch(pm, pm->x, pm->y);
1135 1131
1136 /* check for hangul input */ 1132 /* check for hangul input */
1137 if (ch >= 0x3131 && ch <= 0x3163) 1133 if (ch >= 0x3131 && ch <= 0x3163)