summaryrefslogtreecommitdiff
path: root/apps/plugins/textviewer/tv_text_processor.c
diff options
context:
space:
mode:
authorYoshihisa Uchida <uchida@rockbox.org>2010-04-14 11:19:30 +0000
committerYoshihisa Uchida <uchida@rockbox.org>2010-04-14 11:19:30 +0000
commit4157a31924be37b440c92df8a141ada7e7bfb704 (patch)
treed26a07f45b66aa8fc35ff8bec22aa15823fc037e /apps/plugins/textviewer/tv_text_processor.c
parent2ca2684ede50f145985ae147ca52aef27f7580b2 (diff)
downloadrockbox-4157a31924be37b440c92df8a141ada7e7bfb704.tar.gz
rockbox-4157a31924be37b440c92df8a141ada7e7bfb704.zip
rvert r25644
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@25645 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'apps/plugins/textviewer/tv_text_processor.c')
-rw-r--r--apps/plugins/textviewer/tv_text_processor.c505
1 files changed, 0 insertions, 505 deletions
diff --git a/apps/plugins/textviewer/tv_text_processor.c b/apps/plugins/textviewer/tv_text_processor.c
deleted file mode 100644
index 3ad80db585..0000000000
--- a/apps/plugins/textviewer/tv_text_processor.c
+++ /dev/null
@@ -1,505 +0,0 @@
1/***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
9 *
10 * Copyright (C) 2002 Gilles Roux, 2003 Garrett Derner
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
16 *
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
19 *
20 ****************************************************************************/
21#include "plugin.h"
22#include "tv_drawtext.h"
23
24#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */
25#define NARROW_MAX_COLUMNS 64 /* Max displayable string len [narrow] (over-estimate) */
26#define WIDE_MAX_COLUMNS 128 /* Max displayable string len [wide] (over-estimate) */
27#define MAX_WIDTH 910 /* Max line length in WIDE mode */
28#define READ_PREV_ZONE (block_size*9/10) /* Arbitrary number less than SMALL_BLOCK_SIZE */
29#define SMALL_BLOCK_SIZE block_size /* Smallest file chunk we will read */
30#define LARGE_BLOCK_SIZE (block_size << 1) /* Preferable size of file chunk to read */
31#define TOP_SECTOR buffer
32#define MID_SECTOR (buffer + SMALL_BLOCK_SIZE)
33#define BOTTOM_SECTOR (buffer + (SMALL_BLOCK_SIZE << 1))
34#undef SCROLLBAR_WIDTH
35#define SCROLLBAR_WIDTH rb->global_settings->scrollbar_width
36#define MAX_PAGE 9999
37
38/* Is a scrollbar called for on the current screen? */
39#define NEED_SCROLLBAR() \
40 ((!(ONE_SCREEN_FITS_ALL())) && (prefs.scrollbar_mode==SB_ON))
41
42static void increment_current_line(void)
43{
44 if (cline < display_lines)
45 cline++;
46 else if (cpage < MAX_PAGE)
47 {
48 cpage++;
49 cline = 1;
50 }
51}
52
53static void decrement_current_line(void)
54{
55 if (cline > 1)
56 cline--;
57 else if (cpage > 1)
58 {
59 cpage--;
60 cline = display_lines;
61 }
62}
63
64static void viewer_scroll_up(void)
65{
66 unsigned char *p;
67
68 p = find_prev_line(screen_top_ptr);
69 if (p == NULL && !BUFFER_BOF()) {
70 read_and_synch(-1);
71 p = find_prev_line(screen_top_ptr);
72 }
73 if (p != NULL)
74 screen_top_ptr = p;
75
76 decrement_current_line();
77}
78
79static void viewer_scroll_down(bool autoscroll)
80{
81 if (cpage == lpage)
82 return;
83
84 if (next_line_ptr != NULL)
85 screen_top_ptr = next_line_ptr;
86
87 if (prefs.scroll_mode == LINE || autoscroll)
88 increment_current_line();
89}
90
91static void viewer_scroll_to_top_line(void)
92{
93 int line;
94
95 for (line = cline; line > 1; line--)
96 viewer_scroll_up();
97}
98
99#ifdef HAVE_LCD_BITMAP
100static void viewer_scrollbar(void) {
101 int items, min_shown, max_shown, sb_begin_y, sb_height;
102
103 items = (int) file_size; /* (SH1 int is same as long) */
104 min_shown = (int) file_pos + (screen_top_ptr - buffer);
105
106 if (next_screen_ptr == NULL)
107 max_shown = items;
108 else
109 max_shown = min_shown + (next_screen_ptr - screen_top_ptr);
110
111 sb_begin_y = header_height;
112 sb_height = LCD_HEIGHT - header_height - footer_height;
113
114 rb->gui_scrollbar_draw(rb->screens[SCREEN_MAIN],0, sb_begin_y,
115 SCROLLBAR_WIDTH-1, sb_height,
116 items, min_shown, max_shown, VERTICAL);
117}
118
119static void viewer_show_header(void)
120{
121 if (prefs.header_mode == HD_SBAR || prefs.header_mode == HD_BOTH)
122 rb->gui_syncstatusbar_draw(rb->statusbars, true);
123
124 if (prefs.header_mode == HD_PATH || prefs.header_mode == HD_BOTH)
125 rb->lcd_putsxy(0, header_height - pf->height, file_name);
126}
127
128static void viewer_show_footer(void)
129{
130 if (prefs.footer_mode == FT_SBAR || prefs.footer_mode == FT_BOTH)
131 rb->gui_syncstatusbar_draw(rb->statusbars, true);
132
133 if (prefs.footer_mode == FT_PAGE || prefs.footer_mode == FT_BOTH)
134 {
135 unsigned char buf[12];
136
137 if (cline == 1)
138 rb->snprintf(buf, sizeof(buf), "%d", cpage);
139 else
140 rb->snprintf(buf, sizeof(buf), "%d - %d", cpage, cpage+1);
141
142 rb->lcd_putsxy(0, LCD_HEIGHT - footer_height, buf);
143 }
144}
145#endif
146
147void viewer_draw(int col)
148{
149 int i, j, k, line_len, line_width, spaces, left_col=0;
150 int width, extra_spaces, indent_spaces, spaces_per_word;
151 bool multiple_spacing, line_is_short;
152 unsigned short ch;
153 unsigned char *str, *oldstr;
154 unsigned char *line_begin;
155 unsigned char *line_end;
156 unsigned char c;
157 unsigned char scratch_buffer[max_columns + 1];
158 unsigned char utf8_buffer[max_columns*4 + 1];
159 unsigned char *endptr;
160
161 /* If col==-1 do all calculations but don't display */
162 if (col != -1) {
163#ifdef HAVE_LCD_BITMAP
164 left_col = prefs.need_scrollbar? SCROLLBAR_WIDTH:0;
165#else
166 left_col = 0;
167#endif
168 rb->lcd_clear_display();
169 }
170 max_line_len = 0;
171 line_begin = line_end = screen_top_ptr;
172
173 for (i = 0; i < display_lines; i++) {
174 if (BUFFER_OOB(line_end))
175 {
176 if (lpage == cpage)
177 break; /* Happens after display last line at BUFFER_EOF() */
178
179 if (lpage == 0 && cline == 1)
180 {
181 lpage = cpage;
182 last_screen_top_ptr = screen_top_ptr;
183 last_file_pos = file_pos;
184 }
185 }
186
187 get_next_line_position(&line_begin, &line_end, &line_is_short);
188 if (line_end == NULL)
189 {
190 if (BUFFER_OOB(line_begin))
191 break;
192 line_end = buffer_end + 1;
193 }
194
195 line_len = line_end - line_begin;
196
197 /* calculate line_len */
198 str = oldstr = line_begin;
199 j = -1;
200 while (str < line_end) {
201 oldstr = str;
202 str = crop_at_width(str);
203 j++;
204 }
205 line_width = j*draw_columns;
206 while (oldstr < line_end) {
207 oldstr = get_ucs(oldstr, &ch);
208 line_width += glyph_width(ch);
209 }
210
211 if (prefs.line_mode == JOIN) {
212 if (line_begin[0] == 0) {
213 line_begin++;
214 if (prefs.word_mode == CHOP)
215 line_end++;
216 else
217 line_len--;
218 }
219 for (j=k=spaces=0; j < line_len; j++) {
220 if (k == max_columns)
221 break;
222
223 c = line_begin[j];
224 switch (c) {
225 case ' ':
226 spaces++;
227 break;
228 case 0:
229 spaces = 0;
230 scratch_buffer[k++] = ' ';
231 break;
232 default:
233 while (spaces) {
234 spaces--;
235 scratch_buffer[k++] = ' ';
236 if (k == max_columns - 1)
237 break;
238 }
239 scratch_buffer[k++] = c;
240 break;
241 }
242 }
243 if (col != -1) {
244 scratch_buffer[k] = 0;
245 endptr = decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns);
246 *endptr = 0;
247 }
248 }
249 else if (prefs.line_mode == REFLOW) {
250 if (line_begin[0] == 0) {
251 line_begin++;
252 if (prefs.word_mode == CHOP)
253 line_end++;
254 else
255 line_len--;
256 }
257
258 indent_spaces = 0;
259 if (!line_is_short) {
260 multiple_spacing = false;
261 width=spaces=0;
262 for (str = line_begin; str < line_end; ) {
263 str = get_ucs(str, &ch);
264 switch (ch) {
265 case ' ':
266 case 0:
267 if ((str == line_begin) && (prefs.word_mode==WRAP))
268 /* special case: indent the paragraph,
269 * don't count spaces */
270 indent_spaces = par_indent_spaces;
271 else if (!multiple_spacing)
272 spaces++;
273 multiple_spacing = true;
274 break;
275 default:
276 multiple_spacing = false;
277 width += glyph_width(ch);
278 break;
279 }
280 }
281 if (multiple_spacing) spaces--;
282
283 if (spaces) {
284 /* total number of spaces to insert between words */
285 extra_spaces = (max_width-width)/glyph_width(' ')
286 - indent_spaces;
287 /* number of spaces between each word*/
288 spaces_per_word = extra_spaces / spaces;
289 /* number of words with n+1 spaces (to fill up) */
290 extra_spaces = extra_spaces % spaces;
291 if (spaces_per_word > 2) { /* too much spacing is awful */
292 spaces_per_word = 3;
293 extra_spaces = 0;
294 }
295 } else { /* this doesn't matter much... no spaces anyway */
296 spaces_per_word = extra_spaces = 0;
297 }
298 } else { /* end of a paragraph: don't fill line */
299 spaces_per_word = 1;
300 extra_spaces = 0;
301 }
302
303 multiple_spacing = false;
304 for (j=k=spaces=0; j < line_len; j++) {
305 if (k == max_columns)
306 break;
307
308 c = line_begin[j];
309 switch (c) {
310 case ' ':
311 case 0:
312 if (j==0 && prefs.word_mode==WRAP) { /* indent paragraph */
313 for (j=0; j<par_indent_spaces; j++)
314 scratch_buffer[k++] = ' ';
315 j=0;
316 }
317 else if (!multiple_spacing) {
318 for (width = spaces<extra_spaces ? -1:0; width < spaces_per_word; width++)
319 scratch_buffer[k++] = ' ';
320 spaces++;
321 }
322 multiple_spacing = true;
323 break;
324 default:
325 scratch_buffer[k++] = c;
326 multiple_spacing = false;
327 break;
328 }
329 }
330 if (col != -1) {
331 scratch_buffer[k] = 0;
332 endptr = decode2utf8(scratch_buffer, utf8_buffer, col, draw_columns);
333 *endptr = 0;
334 }
335 }
336 else { /* prefs.line_mode != JOIN && prefs.line_mode != REFLOW */
337 if (col != -1)
338 if (line_width > col) {
339 str = oldstr = line_begin;
340 k = col;
341 width = 0;
342 while( (width<draw_columns) && (oldstr<line_end) )
343 {
344 oldstr = get_ucs(oldstr, &ch);
345 if (k > 0) {
346 k -= glyph_width(ch);
347 line_begin = oldstr;
348 } else {
349 width += glyph_width(ch);
350 }
351 }
352
353 if(prefs.view_mode==WIDE)
354 endptr = rb->iso_decode(line_begin, utf8_buffer,
355 prefs.encoding, oldstr-line_begin);
356 else
357 endptr = rb->iso_decode(line_begin, utf8_buffer,
358 prefs.encoding, line_end-line_begin);
359 *endptr = 0;
360 }
361 }
362 if (col != -1 && line_width > col)
363 {
364 int dpage = (cline+i <= display_lines)?cpage:cpage+1;
365 int dline = cline+i - ((cline+i <= display_lines)?0:display_lines);
366 bool bflag = (viewer_find_bookmark(dpage, dline) >= 0);
367#ifdef HAVE_LCD_BITMAP
368 int dy = i * pf->height + header_height;
369#endif
370 if (bflag)
371#ifdef HAVE_LCD_BITMAP
372 {
373 rb->lcd_set_drawmode(DRMODE_BG|DRMODE_FG);
374 rb->lcd_fillrect(left_col, dy, LCD_WIDTH, pf->height);
375 rb->lcd_set_drawmode(DRMODE_SOLID|DRMODE_INVERSEVID);
376 }
377 rb->lcd_putsxy(left_col, dy, utf8_buffer);
378 rb->lcd_set_drawmode(DRMODE_SOLID);
379#else
380 {
381 rb->lcd_puts(left_col, i, BOOKMARK_ICON);
382 }
383 rb->lcd_puts(left_col+1, i, utf8_buffer);
384#endif
385 }
386 if (line_width > max_line_len)
387 max_line_len = line_width;
388
389 if (i == 0)
390 next_line_ptr = line_end;
391 }
392 next_screen_ptr = line_end;
393 if (BUFFER_OOB(next_screen_ptr))
394 next_screen_ptr = NULL;
395
396#ifdef HAVE_LCD_BITMAP
397 next_screen_to_draw_ptr = prefs.page_mode==OVERLAP? line_begin: next_screen_ptr;
398
399 if (prefs.need_scrollbar)
400 viewer_scrollbar();
401#else
402 next_screen_to_draw_ptr = next_screen_ptr;
403#endif
404
405#ifdef HAVE_LCD_BITMAP
406 /* show header */
407 viewer_show_header();
408
409 /* show footer */
410 viewer_show_footer();
411#endif
412
413 if (col != -1)
414 rb->lcd_update();
415}
416
417#ifdef HAVE_LCD_BITMAP
418static void init_need_scrollbar(void) {
419 /* Call viewer_draw in quiet mode to initialize next_screen_ptr,
420 and thus ONE_SCREEN_FITS_ALL(), and thus NEED_SCROLLBAR() */
421 viewer_draw(-1);
422 prefs.need_scrollbar = NEED_SCROLLBAR();
423 draw_columns = prefs.need_scrollbar? display_columns-SCROLLBAR_WIDTH : display_columns;
424 par_indent_spaces = draw_columns/(5*glyph_width(' '));
425 calc_max_width();
426}
427
428static void init_header_and_footer(void)
429{
430 header_height = 0;
431 footer_height = 0;
432 if (rb->global_settings->statusbar == STATUSBAR_TOP)
433 {
434 if (prefs.header_mode == HD_SBAR || prefs.header_mode == HD_BOTH)
435 header_height = STATUSBAR_HEIGHT;
436
437 if (prefs.footer_mode == FT_SBAR)
438 prefs.footer_mode = FT_NONE;
439 else if (prefs.footer_mode == FT_BOTH)
440 prefs.footer_mode = FT_PAGE;
441 }
442 else if (rb->global_settings->statusbar == STATUSBAR_BOTTOM)
443 {
444 if (prefs.footer_mode == FT_SBAR || prefs.footer_mode == FT_BOTH)
445 footer_height = STATUSBAR_HEIGHT;
446
447 if (prefs.header_mode == HD_SBAR)
448 prefs.header_mode = HD_NONE;
449 else if (prefs.header_mode == HD_BOTH)
450 prefs.header_mode = HD_PATH;
451 }
452 else /* STATUSBAR_OFF || STATUSBAR_CUSTOM */
453 {
454 if (prefs.header_mode == HD_SBAR)
455 prefs.header_mode = HD_NONE;
456 else if (prefs.header_mode == HD_BOTH)
457 prefs.header_mode = HD_PATH;
458
459 if (prefs.footer_mode == FT_SBAR)
460 prefs.footer_mode = FT_NONE;
461 else if (prefs.footer_mode == FT_BOTH)
462 prefs.footer_mode = FT_PAGE;
463 }
464
465 if (prefs.header_mode == HD_NONE || prefs.header_mode == HD_PATH ||
466 prefs.footer_mode == FT_NONE || prefs.footer_mode == FT_PAGE)
467 rb->gui_syncstatusbar_draw(rb->statusbars, false);
468
469 if (prefs.header_mode == HD_PATH || prefs.header_mode == HD_BOTH)
470 header_height += pf->height;
471 if (prefs.footer_mode == FT_PAGE || prefs.footer_mode == FT_BOTH)
472 footer_height += pf->height;
473
474 display_lines = (LCD_HEIGHT - header_height - footer_height) / pf->height;
475
476 lpage = 0;
477 last_file_pos = 0;
478 last_screen_top_ptr = NULL;
479}
480
481static void change_font(unsigned char *font)
482{
483 unsigned char buf[MAX_PATH];
484
485 if (font == NULL || *font == '\0')
486 return;
487
488 rb->snprintf(buf, MAX_PATH, "%s/%s.fnt", FONT_DIR, font);
489 if (rb->font_load(NULL, buf) < 0)
490 rb->splash(HZ/2, "font load failed.");
491}
492#endif
493
494/* When a file is UTF-8 file with BOM, if prefs.encoding is UTF-8,
495 * then file size decreases only BOM_SIZE.
496 */
497static void get_filesize(void)
498{
499 file_size = rb->filesize(fd);
500 if (file_size == -1)
501 return;
502
503 if (prefs.encoding == UTF_8 && is_bom)
504 file_size -= BOM_SIZE;
505}