diff options
author | Yoshihisa Uchida <uchida@rockbox.org> | 2010-04-12 12:02:05 +0000 |
---|---|---|
committer | Yoshihisa Uchida <uchida@rockbox.org> | 2010-04-12 12:02:05 +0000 |
commit | bc28939e04fab65518204d7cc5fff2c2016f96c2 (patch) | |
tree | 71bb20a75aad03b285e179e97ed3d06b20bcfef6 /apps | |
parent | 2252b2dcec4a8a6ae8e54834e05351b46b632804 (diff) | |
download | rockbox-bc28939e04fab65518204d7cc5fff2c2016f96c2.tar.gz rockbox-bc28939e04fab65518204d7cc5fff2c2016f96c2.zip |
viewer plugin: when the alignment is RIGHT, supports WIDE screen.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25605 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps')
-rw-r--r-- | apps/plugins/viewer.c | 200 |
1 files changed, 124 insertions, 76 deletions
diff --git a/apps/plugins/viewer.c b/apps/plugins/viewer.c index 5678c5ef7d..83dab4137d 100644 --- a/apps/plugins/viewer.c +++ b/apps/plugins/viewer.c | |||
@@ -639,6 +639,13 @@ static int bookmark_count; | |||
639 | 639 | ||
640 | static bool is_bom = false; | 640 | static bool is_bom = false; |
641 | 641 | ||
642 | /* We draw a diacritic char over a non-diacritic one. Therefore, such chars are | ||
643 | * not considered to occupy space, therefore buffers might have more than | ||
644 | * max_columns characters. The DIACRITIC_FACTOR is the max ratio between all | ||
645 | * characters and non-diacritic characters in the buffer | ||
646 | */ | ||
647 | #define DIACRITIC_FACTOR 2 | ||
648 | |||
642 | /* calculate the width of a UCS character (zero width for diacritics) */ | 649 | /* calculate the width of a UCS character (zero width for diacritics) */ |
643 | static int glyph_width(unsigned short ch) | 650 | static int glyph_width(unsigned short ch) |
644 | { | 651 | { |
@@ -659,12 +666,11 @@ static int glyph_width(unsigned short ch) | |||
659 | static unsigned char* get_ucs(const unsigned char* str, unsigned short* ch) | 666 | static unsigned char* get_ucs(const unsigned char* str, unsigned short* ch) |
660 | { | 667 | { |
661 | unsigned char utf8_tmp[6]; | 668 | unsigned char utf8_tmp[6]; |
662 | int count; | 669 | int count = 2; |
663 | 670 | ||
664 | if (prefs.encoding == UTF_8) | 671 | if (prefs.encoding == UTF_8) |
665 | return (unsigned char*)rb->utf8decode(str, ch); | 672 | return (unsigned char*)rb->utf8decode(str, ch); |
666 | 673 | ||
667 | count = BUFFER_OOB(str+2)? 1:2; | ||
668 | rb->iso_decode(str, utf8_tmp, prefs.encoding, count); | 674 | rb->iso_decode(str, utf8_tmp, prefs.encoding, count); |
669 | rb->utf8decode(utf8_tmp, ch); | 675 | rb->utf8decode(utf8_tmp, ch); |
670 | 676 | ||
@@ -678,41 +684,78 @@ static unsigned char* get_ucs(const unsigned char* str, unsigned short* ch) | |||
678 | return (unsigned char*)str+1; | 684 | return (unsigned char*)str+1; |
679 | } | 685 | } |
680 | 686 | ||
681 | /* decode UCS string into UTF-8 string */ | 687 | /* decode iso string into UTF-8 string */ |
682 | static unsigned char *decode2utf8(const unsigned char *src, unsigned char *dst, | 688 | static unsigned char *decode2utf8(const unsigned char *src, unsigned char *dst, |
683 | int skip_width, int disp_width) | 689 | int skip_width, int disp_width) |
684 | { | 690 | { |
691 | unsigned short ucs[max_columns * DIACRITIC_FACTOR + 1]; | ||
685 | unsigned short ch; | 692 | unsigned short ch; |
686 | const unsigned char *oldstr; | 693 | const unsigned char *oldstr; |
687 | const unsigned char *str = src; | 694 | const unsigned char *str = src; |
688 | unsigned char *utf8 = dst; | 695 | unsigned char *utf8 = dst; |
689 | int width = 0; | 696 | int chars = 0; |
697 | int idx = 0; | ||
698 | int width = max_width; | ||
690 | 699 | ||
691 | /* skip the skip_width */ | 700 | if (prefs.alignment == LEFT) |
692 | while (*str != '\0') | ||
693 | { | 701 | { |
694 | oldstr = str; | 702 | /* skip the skip_width */ |
695 | str = get_ucs(oldstr, &ch); | 703 | if (skip_width > 0) |
696 | width += glyph_width(ch); | ||
697 | if (width > skip_width) | ||
698 | { | 704 | { |
699 | str = oldstr; | 705 | while (skip_width > 0 && *str != '\0') |
700 | break; | 706 | { |
707 | oldstr = str; | ||
708 | str = get_ucs(oldstr, &ch); | ||
709 | skip_width -= glyph_width(ch); | ||
710 | } | ||
711 | if (skip_width < 0) | ||
712 | str = oldstr; | ||
701 | } | 713 | } |
702 | } | ||
703 | 714 | ||
704 | /* decode until string end or disp_width reached */ | 715 | /* decode until string end or disp_width reached */ |
705 | width = 0; | 716 | while(*str != '\0') |
706 | while(*str != '\0') | 717 | { |
718 | str = get_ucs(str, &ch); | ||
719 | disp_width -= glyph_width(ch); | ||
720 | if (disp_width < 0) | ||
721 | break; | ||
722 | utf8 = rb->utf8encode(ch, utf8); | ||
723 | } | ||
724 | } | ||
725 | else | ||
707 | { | 726 | { |
708 | str = get_ucs(str, &ch); | 727 | while (width > 0 && *str != '\0') |
709 | width += glyph_width(ch); | 728 | { |
710 | if (width > disp_width) | 729 | str = get_ucs(str, &ch); |
711 | break; | 730 | ucs[chars++] = ch; |
731 | } | ||
732 | ucs[chars] = 0; | ||
733 | |||
734 | skip_width = max_width - skip_width - disp_width; | ||
735 | if (skip_width > 0) | ||
736 | { | ||
737 | while (skip_width > 0 && chars-- > 0) | ||
738 | skip_width -= glyph_width(ucs[chars]); | ||
739 | |||
740 | if (skip_width < 0) | ||
741 | chars++; | ||
742 | } | ||
743 | else | ||
744 | { | ||
745 | idx = chars; | ||
746 | while (disp_width > 0 && idx-- > 0) | ||
747 | disp_width -= glyph_width(ucs[idx]); | ||
748 | |||
749 | if (disp_width < 0 || idx < 0) | ||
750 | idx++; | ||
751 | } | ||
712 | 752 | ||
713 | utf8 = rb->utf8encode(ch, utf8); | 753 | for ( ; idx < chars; idx++) |
754 | utf8 = rb->utf8encode(ucs[idx], utf8); | ||
714 | } | 755 | } |
715 | 756 | ||
757 | *utf8 = '\0'; | ||
758 | |||
716 | /* return a pointer after the dst string ends */ | 759 | /* return a pointer after the dst string ends */ |
717 | return utf8; | 760 | return utf8; |
718 | } | 761 | } |
@@ -776,6 +819,9 @@ static unsigned char* find_first_feed(const unsigned char* p, int size) | |||
776 | int s = 0; | 819 | int s = 0; |
777 | unsigned short ch; | 820 | unsigned short ch; |
778 | const unsigned char *oldp = p; | 821 | const unsigned char *oldp = p; |
822 | const unsigned char *lbrkp = NULL; | ||
823 | int j; | ||
824 | int width = 0; | ||
779 | 825 | ||
780 | while(s <= size) | 826 | while(s <= size) |
781 | { | 827 | { |
@@ -783,6 +829,23 @@ static unsigned char* find_first_feed(const unsigned char* p, int size) | |||
783 | return (unsigned char*)p; | 829 | return (unsigned char*)p; |
784 | oldp = p; | 830 | oldp = p; |
785 | p = get_ucs(p, &ch); | 831 | p = get_ucs(p, &ch); |
832 | |||
833 | if (prefs.word_mode == WRAP) | ||
834 | { | ||
835 | for (j = 0; j < ((int) sizeof(line_break)); j++) | ||
836 | { | ||
837 | if (ch == line_break[j]) | ||
838 | { | ||
839 | lbrkp = p; | ||
840 | break; | ||
841 | } | ||
842 | } | ||
843 | } | ||
844 | |||
845 | width += glyph_width(ch); | ||
846 | if (width > max_width) | ||
847 | return (lbrkp == NULL)? (unsigned char*)oldp : (unsigned char*)lbrkp; | ||
848 | |||
786 | s += (p - oldp); | 849 | s += (p - oldp); |
787 | } | 850 | } |
788 | 851 | ||
@@ -1266,17 +1329,10 @@ static void viewer_show_footer(void) | |||
1266 | } | 1329 | } |
1267 | #endif | 1330 | #endif |
1268 | 1331 | ||
1269 | /* We draw a diacritic char over a non-diacritic one. Therefore, such chars are | ||
1270 | * not considered to occupy space, therefore buffers might have more than | ||
1271 | * max_columns characters. The DIACRITIC_FACTOR is the max ratio between all | ||
1272 | * characters and non-diacritic characters in the buffer | ||
1273 | */ | ||
1274 | #define DIACRITIC_FACTOR 2 | ||
1275 | |||
1276 | static void viewer_draw(int col) | 1332 | static void viewer_draw(int col) |
1277 | { | 1333 | { |
1278 | int i, j, k, line_len, line_width, spaces, left_col=0; | 1334 | int i, j, k, line_len, line_width, spaces, left_col=0; |
1279 | int width, extra_spaces, indent_spaces, spaces_per_word, spaces_width; | 1335 | int width, extra_spaces, indent_spaces, spaces_per_word, spaces_width, disp_width = 0; |
1280 | bool multiple_spacing, line_is_short; | 1336 | bool multiple_spacing, line_is_short; |
1281 | unsigned short ch; | 1337 | unsigned short ch; |
1282 | unsigned char *str, *oldstr; | 1338 | unsigned char *str, *oldstr; |
@@ -1284,9 +1340,8 @@ static void viewer_draw(int col) | |||
1284 | unsigned char *line_end; | 1340 | unsigned char *line_end; |
1285 | unsigned char c; | 1341 | unsigned char c; |
1286 | int max_chars = max_columns * DIACRITIC_FACTOR; | 1342 | int max_chars = max_columns * DIACRITIC_FACTOR; |
1287 | unsigned char scratch_buffer[max_chars + 1]; | 1343 | unsigned char scratch_buffer[max_chars * 4 + 1]; |
1288 | unsigned char utf8_buffer[max_chars * 4 + 1]; | 1344 | unsigned char utf8_buffer[max_chars * 4 + 1]; |
1289 | unsigned char *endptr; | ||
1290 | 1345 | ||
1291 | /* If col==-1 do all calculations but don't display */ | 1346 | /* If col==-1 do all calculations but don't display */ |
1292 | if (col != -1) { | 1347 | if (col != -1) { |
@@ -1392,11 +1447,7 @@ static void viewer_draw(int col) | |||
1392 | break; | 1447 | break; |
1393 | } | 1448 | } |
1394 | } | 1449 | } |
1395 | if (col != -1) { | 1450 | scratch_buffer[k] = 0; |
1396 | scratch_buffer[k] = 0; | ||
1397 | endptr = decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns); | ||
1398 | *endptr = 0; | ||
1399 | } | ||
1400 | } | 1451 | } |
1401 | else if (prefs.line_mode == REFLOW) { | 1452 | else if (prefs.line_mode == REFLOW) { |
1402 | if (line_begin[0] == 0) { | 1453 | if (line_begin[0] == 0) { |
@@ -1414,12 +1465,17 @@ static void viewer_draw(int col) | |||
1414 | for (str = line_begin; str < line_end; ) { | 1465 | for (str = line_begin; str < line_end; ) { |
1415 | str = get_ucs(str, &ch); | 1466 | str = get_ucs(str, &ch); |
1416 | switch (ch) { | 1467 | switch (ch) { |
1417 | case ' ': | ||
1418 | case 0: | 1468 | case 0: |
1419 | if ((str == line_begin) && (prefs.word_mode==WRAP)) | 1469 | case ' ': |
1420 | /* special case: indent the paragraph, | 1470 | if (str == line_begin) |
1421 | * don't count spaces */ | 1471 | { |
1422 | indent_spaces = par_indent_spaces; | 1472 | if (prefs.word_mode == WRAP && prefs.alignment == LEFT) |
1473 | { | ||
1474 | /* special case: indent the paragraph, | ||
1475 | * don't count spaces */ | ||
1476 | indent_spaces = par_indent_spaces; | ||
1477 | } | ||
1478 | } | ||
1423 | else if (!multiple_spacing) | 1479 | else if (!multiple_spacing) |
1424 | spaces++; | 1480 | spaces++; |
1425 | multiple_spacing = true; | 1481 | multiple_spacing = true; |
@@ -1451,7 +1507,6 @@ static void viewer_draw(int col) | |||
1451 | spaces_per_word = 1; | 1507 | spaces_per_word = 1; |
1452 | extra_spaces = 0; | 1508 | extra_spaces = 0; |
1453 | } | 1509 | } |
1454 | |||
1455 | multiple_spacing = false; | 1510 | multiple_spacing = false; |
1456 | for (j=k=spaces=0; j < line_len; j++) { | 1511 | for (j=k=spaces=0; j < line_len; j++) { |
1457 | if (k == max_chars) | 1512 | if (k == max_chars) |
@@ -1459,12 +1514,18 @@ static void viewer_draw(int col) | |||
1459 | 1514 | ||
1460 | c = line_begin[j]; | 1515 | c = line_begin[j]; |
1461 | switch (c) { | 1516 | switch (c) { |
1462 | case ' ': | ||
1463 | case 0: | 1517 | case 0: |
1464 | if (j==0 && prefs.word_mode==WRAP) { /* indent paragraph */ | 1518 | if (j == line_len - 1) |
1465 | for (j=0; j<par_indent_spaces; j++) | 1519 | break; |
1466 | scratch_buffer[k++] = ' '; | 1520 | case ' ': |
1467 | j=0; | 1521 | if (j==0) { |
1522 | /* indent paragraph */ | ||
1523 | if (prefs.word_mode == WRAP && prefs.alignment == LEFT) | ||
1524 | { | ||
1525 | for (j=0; j<par_indent_spaces; j++) | ||
1526 | scratch_buffer[k++] = ' '; | ||
1527 | j=0; | ||
1528 | } | ||
1468 | } | 1529 | } |
1469 | else if (!multiple_spacing) { | 1530 | else if (!multiple_spacing) { |
1470 | for (width = spaces<extra_spaces ? -1:0; width < spaces_per_word; width++) | 1531 | for (width = spaces<extra_spaces ? -1:0; width < spaces_per_word; width++) |
@@ -1479,47 +1540,34 @@ static void viewer_draw(int col) | |||
1479 | break; | 1540 | break; |
1480 | } | 1541 | } |
1481 | } | 1542 | } |
1482 | if (col != -1) { | 1543 | while (scratch_buffer[k-1] == ' ') |
1483 | scratch_buffer[k] = 0; | 1544 | k--; |
1484 | endptr = decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns); | 1545 | scratch_buffer[k] = 0; |
1485 | *endptr = 0; | ||
1486 | } | ||
1487 | } | 1546 | } |
1488 | else { /* prefs.line_mode != JOIN && prefs.line_mode != REFLOW */ | 1547 | else { /* prefs.line_mode != JOIN && prefs.line_mode != REFLOW */ |
1489 | if ((col != -1) && (line_width > col)) { | 1548 | if (col != -1) |
1490 | str = oldstr = line_begin; | 1549 | { |
1491 | k = col; | 1550 | rb->memcpy(scratch_buffer, line_begin, line_len); |
1492 | width = 0; | 1551 | scratch_buffer[line_len] = '\0'; |
1493 | while( (width<draw_columns) && (oldstr<line_end) ) | ||
1494 | { | ||
1495 | oldstr = get_ucs(oldstr, &ch); | ||
1496 | if (k > 0) { | ||
1497 | k -= glyph_width(ch); | ||
1498 | line_begin = oldstr; | ||
1499 | } else { | ||
1500 | width += glyph_width(ch); | ||
1501 | } | ||
1502 | } | ||
1503 | |||
1504 | if(prefs.view_mode==WIDE) | ||
1505 | endptr = rb->iso_decode(line_begin, utf8_buffer, | ||
1506 | prefs.encoding, oldstr-line_begin); | ||
1507 | else | ||
1508 | endptr = rb->iso_decode(line_begin, utf8_buffer, | ||
1509 | prefs.encoding, line_end-line_begin); | ||
1510 | *endptr = 0; | ||
1511 | } | 1552 | } |
1512 | } | 1553 | } |
1513 | 1554 | ||
1555 | /* create displayed line */ | ||
1556 | if (col != -1) | ||
1557 | { | ||
1558 | decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns); | ||
1559 | rb->lcd_getstringsize(utf8_buffer, &disp_width, NULL); | ||
1560 | } | ||
1561 | |||
1514 | /* display on screen the displayed part of the line */ | 1562 | /* display on screen the displayed part of the line */ |
1515 | if (col != -1 && line_width > col) | 1563 | if (col != -1) |
1516 | { | 1564 | { |
1517 | int dpage = (cline+i <= display_lines)?cpage:cpage+1; | 1565 | int dpage = (cline+i <= display_lines)?cpage:cpage+1; |
1518 | int dline = cline+i - ((cline+i <= display_lines)?0:display_lines); | 1566 | int dline = cline+i - ((cline+i <= display_lines)?0:display_lines); |
1519 | bool bflag = (viewer_find_bookmark(dpage, dline) >= 0); | 1567 | bool bflag = (viewer_find_bookmark(dpage, dline) >= 0); |
1520 | #ifdef HAVE_LCD_BITMAP | 1568 | #ifdef HAVE_LCD_BITMAP |
1521 | int dy = i * pf->height + header_height; | 1569 | int dy = i * pf->height + header_height; |
1522 | int dx = (prefs.alignment == LEFT) ? left_col : LCD_WIDTH - line_width; | 1570 | int dx = (prefs.alignment == LEFT)? left_col : LCD_WIDTH - disp_width; |
1523 | #endif | 1571 | #endif |
1524 | if (bflag) | 1572 | if (bflag) |
1525 | #ifdef HAVE_LCD_BITMAP | 1573 | #ifdef HAVE_LCD_BITMAP |