summaryrefslogtreecommitdiff
path: root/apps/plugins/text_viewer/tv_text_processor.c
diff options
context:
space:
mode:
authorRafaël Carré <rafael.carre@gmail.com>2010-06-20 21:53:47 +0000
committerRafaël Carré <rafael.carre@gmail.com>2010-06-20 21:53:47 +0000
commit298316d19297eea82869b63235b535e5904fc0dd (patch)
tree0426e9c8cecac7532a88888e78e5e54ea9bb6145 /apps/plugins/text_viewer/tv_text_processor.c
parent17a2f9d8d2dfddd8d2d81ff638e21302efef1c8e (diff)
downloadrockbox-298316d19297eea82869b63235b535e5904fc0dd.tar.gz
rockbox-298316d19297eea82869b63235b535e5904fc0dd.zip
text_viewer: cleanup & bugfix
cleanup: - don't use enum in struct / return values - don't use a getter for preferences but a global pointer - explicitely make enums start at 0 - use static tables for header/footer settings - remove unneeded memset before strlcpy - use static buffer allocation, not dynamic - check header/footer preferences before using the callbacks - don't include font filename in archos player preferences (break file format) bugfix: - statically allocate old preferences in tv_set_preferences() Sometimes I can read a file on Clipv2, but it still aborts quite often refs: FS#11399 git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26998 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/text_viewer/tv_text_processor.c')
-rw-r--r--apps/plugins/text_viewer/tv_text_processor.c68
1 files changed, 26 insertions, 42 deletions
diff --git a/apps/plugins/text_viewer/tv_text_processor.c b/apps/plugins/text_viewer/tv_text_processor.c
index 5e30f0b078..f9a2fad1f2 100644
--- a/apps/plugins/text_viewer/tv_text_processor.c
+++ b/apps/plugins/text_viewer/tv_text_processor.c
@@ -25,7 +25,7 @@
25#include "tv_preferences.h" 25#include "tv_preferences.h"
26#include "tv_text_processor.h" 26#include "tv_text_processor.h"
27 27
28enum tv_text_type { 28enum{
29 TV_TEXT_UNKNOWN, 29 TV_TEXT_UNKNOWN,
30 TV_TEXT_MAC, 30 TV_TEXT_MAC,
31 TV_TEXT_UNIX, 31 TV_TEXT_UNIX,
@@ -41,13 +41,12 @@ enum tv_text_type {
41 41
42#define TV_MAX_BLOCKS 5 42#define TV_MAX_BLOCKS 5
43 43
44static const struct tv_preferences *prefs; 44static unsigned text_type = TV_TEXT_UNKNOWN;
45static enum tv_text_type text_type = TV_TEXT_UNKNOWN;
46 45
47static const unsigned char *end_ptr; 46static const unsigned char *end_ptr;
48 47
49static unsigned short *ucsbuf[TV_MAX_BLOCKS]; 48static unsigned short ucsbuf[TV_MAX_BLOCKS][TV_MAX_CHARS_PER_BLOCK];
50static unsigned char *utf8buf; 49static unsigned char utf8buf[TV_MAX_CHARS_PER_BLOCK * (2 * 3)];
51static unsigned char *outbuf; 50static unsigned char *outbuf;
52 51
53static int block_count; 52static int block_count;
@@ -96,7 +95,7 @@ static int tv_glyph_width(int ch)
96 if (rb->is_diacritic(ch, NULL)) 95 if (rb->is_diacritic(ch, NULL))
97 return 0; 96 return 0;
98 97
99 return rb->font_get_width(prefs->font, ch); 98 return rb->font_get_width(preferences->font, ch);
100#else 99#else
101 return 1; 100 return 1;
102#endif 101#endif
@@ -136,13 +135,13 @@ static unsigned char *tv_get_ucs(const unsigned char *str, unsigned short *ch)
136 return (unsigned char *)str + 1; 135 return (unsigned char *)str + 1;
137 } 136 }
138 137
139 if (prefs->encoding == UTF_8) 138 if (preferences->encoding == UTF_8)
140 return (unsigned char*)rb->utf8decode(str, ch); 139 return (unsigned char*)rb->utf8decode(str, ch);
141 140
142#ifdef HAVE_LCD_BITMAP 141#ifdef HAVE_LCD_BITMAP
143 if ((*str >= 0x80) && 142 if ((*str >= 0x80) &&
144 ((prefs->encoding > SJIS) || 143 ((preferences->encoding > SJIS) ||
145 (prefs->encoding == SJIS && (*str <= 0xa0 || *str >= 0xe0)))) 144 (preferences->encoding == SJIS && (*str <= 0xa0 || *str >= 0xe0))))
146 { 145 {
147 if (str + 1 >= end_ptr) 146 if (str + 1 >= end_ptr)
148 { 147 {
@@ -153,7 +152,7 @@ static unsigned char *tv_get_ucs(const unsigned char *str, unsigned short *ch)
153 count = 2; 152 count = 2;
154 } 153 }
155#endif 154#endif
156 rb->iso_decode(str, utf8_tmp, prefs->encoding, count); 155 rb->iso_decode(str, utf8_tmp, preferences->encoding, count);
157 rb->utf8decode(utf8_tmp, ch); 156 rb->utf8decode(utf8_tmp, ch);
158 return (unsigned char *)str + count; 157 return (unsigned char *)str + count;
159} 158}
@@ -173,7 +172,7 @@ static bool tv_is_line_break_char(unsigned short ch)
173 size_t i; 172 size_t i;
174 173
175 /* when the word mode is CHOP, all characters does not break line. */ 174 /* when the word mode is CHOP, all characters does not break line. */
176 if (prefs->word_mode == CHOP) 175 if (preferences->word_mode == CHOP)
177 return false; 176 return false;
178 177
179 for (i = 0; i < sizeof(break_chars); i++) 178 for (i = 0; i < sizeof(break_chars); i++)
@@ -222,7 +221,7 @@ static int tv_form_reflow_line(unsigned short *ucs, int chars)
222 int spaces = 0; 221 int spaces = 0;
223 int words_spaces; 222 int words_spaces;
224 223
225 if (prefs->alignment == LEFT) 224 if (preferences->alignment == LEFT)
226 { 225 {
227 while (chars > 0 && ucs[chars-1] == ' ') 226 while (chars > 0 && ucs[chars-1] == ' ')
228 chars--; 227 chars--;
@@ -368,7 +367,6 @@ static int tv_parse_text(const unsigned char *src, unsigned short *ucs,
368 unsigned short prev_ch; 367 unsigned short prev_ch;
369 int chars = 0; 368 int chars = 0;
370 int gw; 369 int gw;
371 int i;
372 int line_break_width = 0; 370 int line_break_width = 0;
373 int line_end_chars = 0; 371 int line_end_chars = 0;
374 int width = 0; 372 int width = 0;
@@ -388,7 +386,7 @@ static int tv_parse_text(const unsigned char *src, unsigned short *ucs,
388 next = tv_get_ucs(cur, &ch); 386 next = tv_get_ucs(cur, &ch);
389 if (ch == '\n') 387 if (ch == '\n')
390 { 388 {
391 if (prefs->line_mode != JOIN || tv_is_break_line_join_mode(next)) 389 if (preferences->line_mode != JOIN || tv_is_break_line_join_mode(next))
392 { 390 {
393 line_end_ptr = next; 391 line_end_ptr = next;
394 line_end_chars = chars; 392 line_end_chars = chars;
@@ -396,7 +394,7 @@ static int tv_parse_text(const unsigned char *src, unsigned short *ucs,
396 break; 394 break;
397 } 395 }
398 396
399 if (prefs->word_mode == CHOP || tv_isspace(prev_ch)) 397 if (preferences->word_mode == CHOP || tv_isspace(prev_ch))
400 continue; 398 continue;
401 399
402 /* 400 /*
@@ -413,7 +411,7 @@ static int tv_parse_text(const unsigned char *src, unsigned short *ucs,
413 * (1) spacelike character convert to ' ' 411 * (1) spacelike character convert to ' '
414 * (2) plural spaces are collected to one 412 * (2) plural spaces are collected to one
415 */ 413 */
416 if (prefs->line_mode == REFLOW) 414 if (preferences->line_mode == REFLOW)
417 { 415 {
418 ch = ' '; 416 ch = ' ';
419 if (prev_ch == ch) 417 if (prev_ch == ch)
@@ -421,14 +419,14 @@ static int tv_parse_text(const unsigned char *src, unsigned short *ucs,
421 } 419 }
422 420
423 /* when the alignment is RIGHT, ignores indent spaces. */ 421 /* when the alignment is RIGHT, ignores indent spaces. */
424 if (prefs->alignment == RIGHT && is_indent) 422 if (preferences->alignment == RIGHT && is_indent)
425 continue; 423 continue;
426 } 424 }
427 else 425 else
428 is_indent = false; 426 is_indent = false;
429 427
430 if (prefs->line_mode == REFLOW && is_indent) 428 if (preferences->line_mode == REFLOW && is_indent)
431 gw = tv_glyph_width(ch) * prefs->indent_spaces; 429 gw = tv_glyph_width(ch) * preferences->indent_spaces;
432 else 430 else
433 gw = tv_glyph_width(ch); 431 gw = tv_glyph_width(ch);
434 432
@@ -445,11 +443,12 @@ static int tv_parse_text(const unsigned char *src, unsigned short *ucs,
445 break; 443 break;
446 } 444 }
447 445
448 if (prefs->line_mode != REFLOW || !is_indent) 446 if (preferences->line_mode != REFLOW || !is_indent)
449 ucs[chars++] = ch; 447 ucs[chars++] = ch;
450 else 448 else
451 { 449 {
452 for (i = 0; i < prefs->indent_spaces; i++) 450 unsigned char i;
451 for (i = 0; i < preferences->indent_spaces; i++)
453 ucs[chars++] = ch; 452 ucs[chars++] = ch;
454 } 453 }
455 454
@@ -473,7 +472,7 @@ static int tv_parse_text(const unsigned char *src, unsigned short *ucs,
473 * when the last line break position is too short (line length < 0.75 * block width), 472 * when the last line break position is too short (line length < 0.75 * block width),
474 * the line is cut off at the position where it is closest to the displayed width. 473 * the line is cut off at the position where it is closest to the displayed width.
475 */ 474 */
476 if ((prefs->line_mode == REFLOW && line_break_ptr == NULL) || 475 if ((preferences->line_mode == REFLOW && line_break_ptr == NULL) ||
477 (4 * line_break_width < 3 * block_width)) 476 (4 * line_break_width < 3 * block_width))
478 { 477 {
479 line_end_ptr = cur; 478 line_end_ptr = cur;
@@ -505,7 +504,7 @@ int tv_create_formed_text(const unsigned char *src, ssize_t bufsize,
505 if (dst != NULL) 504 if (dst != NULL)
506 *dst = utf8buf; 505 *dst = utf8buf;
507 506
508 if (prefs->line_mode == EXPAND && (expand_extra_line = !expand_extra_line) == true) 507 if (preferences->line_mode == EXPAND && (expand_extra_line = !expand_extra_line) == true)
509 return 0; 508 return 0;
510 509
511 end_ptr = src + bufsize; 510 end_ptr = src + bufsize;
@@ -513,7 +512,7 @@ int tv_create_formed_text(const unsigned char *src, ssize_t bufsize,
513 tv_get_ucs(src, &ch); 512 tv_get_ucs(src, &ch);
514 is_indent = (tv_isspace(ch) && !is_break_line); 513 is_indent = (tv_isspace(ch) && !is_break_line);
515 514
516 if (is_indent && prefs->indent_spaces == 0 && (expand_extra_line = !expand_extra_line) == true) 515 if (is_indent && preferences->indent_spaces == 0 && (expand_extra_line = !expand_extra_line) == true)
517 return 0; 516 return 0;
518 517
519 for (i = 0; i < block_count; i++) 518 for (i = 0; i < block_count; i++)
@@ -527,14 +526,14 @@ int tv_create_formed_text(const unsigned char *src, ssize_t bufsize,
527 526
528 if (dst != NULL) 527 if (dst != NULL)
529 { 528 {
530 if (prefs->alignment == RIGHT) 529 if (preferences->alignment == RIGHT)
531 tv_align_right(chars); 530 tv_align_right(chars);
532 531
533 for (i = 0; i < block_count; i++) 532 for (i = 0; i < block_count; i++)
534 { 533 {
535 if (i == block || (is_multi && i == block + 1)) 534 if (i == block || (is_multi && i == block + 1))
536 { 535 {
537 if (is_break_line && prefs->line_mode == REFLOW) 536 if (is_break_line && preferences->line_mode == REFLOW)
538 chars[i] = tv_form_reflow_line(ucsbuf[i], chars[i]); 537 chars[i] = tv_form_reflow_line(ucsbuf[i], chars[i]);
539 538
540 tv_decode2utf8(ucsbuf[i], chars[i]); 539 tv_decode2utf8(ucsbuf[i], chars[i]);
@@ -545,26 +544,11 @@ int tv_create_formed_text(const unsigned char *src, ssize_t bufsize,
545 return size; 544 return size;
546} 545}
547 546
548bool tv_init_text_processor(unsigned char *buf, size_t bufsize, size_t *used_size) 547void tv_init_text_processor(void)
549{ 548{
550 int i;
551
552 *used_size = TV_MAX_CHARS_PER_BLOCK * (2 * 3 + TV_MAX_BLOCKS * sizeof(unsigned short));
553 if (bufsize < *used_size)
554 return false;
555
556 prefs = tv_get_preferences();
557 text_type = TV_TEXT_UNKNOWN; 549 text_type = TV_TEXT_UNKNOWN;
558 expand_extra_line = false; 550 expand_extra_line = false;
559 is_break_line = false; 551 is_break_line = false;
560
561 ucsbuf[0] = (unsigned short*)buf;
562 for (i = 1; i < TV_MAX_BLOCKS; i++)
563 ucsbuf[i] = ucsbuf[i - 1] + TV_MAX_CHARS_PER_BLOCK;
564
565 utf8buf = buf + TV_MAX_CHARS_PER_BLOCK * TV_MAX_BLOCKS * sizeof(unsigned short);
566
567 return true;
568} 552}
569 553
570void tv_set_creation_conditions(int blocks, int width) 554void tv_set_creation_conditions(int blocks, int width)