summaryrefslogtreecommitdiff
path: root/apps/plugins/textviewer/tv_readtext.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/textviewer/tv_readtext.c')
-rw-r--r--apps/plugins/textviewer/tv_readtext.c483
1 files changed, 0 insertions, 483 deletions
diff --git a/apps/plugins/textviewer/tv_readtext.c b/apps/plugins/textviewer/tv_readtext.c
deleted file mode 100644
index 988ee63..0000000
--- a/apps/plugins/textviewer/tv_readtext.c
+++ /dev/null
@@ -1,483 +0,0 @@
-/***************************************************************************
- * __________ __ ___.
- * Open \______ \ ____ ____ | | _\_ |__ _______ ___
- * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
- * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
- * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
- * \/ \/ \/ \/ \/
- * $Id$
- *
- * Copyright (C) 2002 Gilles Roux
- * 2003 Garrett Derner
- * 2010 Yoshihisa Uchida
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU General Public License
- * as published by the Free Software Foundation; either version 2
- * of the License, or (at your option) any later version.
- *
- * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
- * KIND, either express or implied.
- *
- ****************************************************************************/
-#include "plugin.h"
-#include "tv_readtext.h"
-
-#define WRAP_TRIM 44 /* Max number of spaces to trim (arbitrary) */
-#define NARROW_MAX_COLUMNS 64 /* Max displayable string len [narrow] (over-estimate) */
-#define WIDE_MAX_COLUMNS 128 /* Max displayable string len [wide] (over-estimate) */
-#define MAX_WIDTH 910 /* Max line length in WIDE mode */
-#define READ_PREV_ZONE (block_size*9/10) /* Arbitrary number less than SMALL_BLOCK_SIZE */
-#define SMALL_BLOCK_SIZE block_size /* Smallest file chunk we will read */
-#define LARGE_BLOCK_SIZE (block_size << 1) /* Preferable size of file chunk to read */
-#define TOP_SECTOR buffer
-#define MID_SECTOR (buffer + SMALL_BLOCK_SIZE)
-#define BOTTOM_SECTOR (buffer + (SMALL_BLOCK_SIZE << 1))
-#undef SCROLLBAR_WIDTH
-#define SCROLLBAR_WIDTH rb->global_settings->scrollbar_width
-#define MAX_PAGE 9999
-
-/* Out-Of-Bounds test for any pointer to data in the buffer */
-#define BUFFER_OOB(p) ((p) < buffer || (p) >= buffer_end)
-
-/* Does the buffer contain the beginning of the file? */
-#define BUFFER_BOF() (file_pos==0)
-
-/* Does the buffer contain the end of the file? */
-#define BUFFER_EOF() (file_size-file_pos <= buffer_size)
-
-/* Formula for the endpoint address outside of buffer data */
-#define BUFFER_END() \
- ((BUFFER_EOF()) ? (file_size-file_pos+buffer) : (buffer+buffer_size))
-
-/* Is the entire file being shown in one screen? */
-#define ONE_SCREEN_FITS_ALL() \
- (next_screen_ptr==NULL && screen_top_ptr==buffer && BUFFER_BOF())
-
-#define ADVANCE_COUNTERS(c) { width += glyph_width(c); k++; }
-#define LINE_IS_FULL ((k>=max_columns-1) ||( width >= max_width))
-#define LINE_IS_NOT_FULL ((k<max_columns-1) &&( width < max_width))
-
-
-static unsigned char file_name[MAX_PARH+1];
-static int fd = -1;
-
-static unsigned char *buffer;
-static long buffer_size;
-static long block_size = 0x1000;
-
-void viewer_init_buffer(void)
-{
- /* get the plugin buffer */
- buffer = rb->plugin_get_buffer((size_t *)&buffer_size);
- if (buffer_size == 0)
- {
- rb->splash(HZ, "buffer does not allocate !!");
- return PLUGIN_ERROR;
- }
- block_size = buffer_size / 3;
- buffer_size = 3 * block_size;
-}
-
-static unsigned char* crop_at_width(const unsigned char* p)
-{
- int k,width;
- unsigned short ch;
- const unsigned char *oldp = p;
-
- k=width=0;
-
- while (LINE_IS_NOT_FULL) {
- oldp = p;
- if (BUFFER_OOB(p))
- break;
- p = get_ucs(p, &ch);
- ADVANCE_COUNTERS(ch);
- }
-
- return (unsigned char*)oldp;
-}
-
-static unsigned char* find_first_feed(const unsigned char* p, int size)
-{
- int i;
-
- for (i=0; i < size; i++)
- if (p[i] == 0)
- return (unsigned char*) p+i;
-
- return NULL;
-}
-
-static unsigned char* find_last_feed(const unsigned char* p, int size)
-{
- int i;
-
- for (i=size-1; i>=0; i--)
- if (p[i] == 0)
- return (unsigned char*) p+i;
-
- return NULL;
-}
-
-static unsigned char* find_last_space(const unsigned char* p, int size)
-{
- int i, j, k;
-
- k = (prefs.line_mode==JOIN) || (prefs.line_mode==REFLOW) ? 0:1;
-
- if (!BUFFER_OOB(&p[size]))
- for (j=k; j < ((int) sizeof(line_break)) - 1; j++)
- if (p[size] == line_break[j])
- return (unsigned char*) p+size;
-
- for (i=size-1; i>=0; i--)
- for (j=k; j < (int) sizeof(line_break); j++)
- {
- if (!((p[i] == '-') && (prefs.word_mode == WRAP)))
- if (p[i] == line_break[j])
- return (unsigned char*) p+i;
- }
-
- return NULL;
-}
-
-static unsigned char* find_next_line(const unsigned char* cur_line, bool *is_short)
-{
- const unsigned char *next_line = NULL;
- int size, i, j, k, width, search_len, spaces, newlines;
- bool first_chars;
- unsigned char c;
-
- if (is_short != NULL)
- *is_short = true;
-
- if BUFFER_OOB(cur_line)
- return NULL;
-
- if (prefs.view_mode == WIDE) {
- search_len = MAX_WIDTH;
- }
- else { /* prefs.view_mode == NARROW */
- search_len = crop_at_width(cur_line) - cur_line;
- }
-
- size = BUFFER_OOB(cur_line+search_len) ? buffer_end-cur_line : search_len;
-
- if ((prefs.line_mode == JOIN) || (prefs.line_mode == REFLOW)) {
- /* Need to scan ahead and possibly increase search_len and size,
- or possibly set next_line at second hard return in a row. */
- next_line = NULL;
- first_chars=true;
- for (j=k=width=spaces=newlines=0; ; j++) {
- if (BUFFER_OOB(cur_line+j))
- return NULL;
- if (LINE_IS_FULL) {
- size = search_len = j;
- break;
- }
-
- c = cur_line[j];
- switch (c) {
- case ' ':
- if (prefs.line_mode == REFLOW) {
- if (newlines > 0) {
- size = j;
- next_line = cur_line + size;
- return (unsigned char*) next_line;
- }
- if (j==0) /* i=1 is intentional */
- for (i=0; i<par_indent_spaces; i++)
- ADVANCE_COUNTERS(' ');
- }
- if (!first_chars) spaces++;
- break;
-
- case 0:
- if (newlines > 0) {
- size = j;
- next_line = cur_line + size - spaces;
- if (next_line != cur_line)
- return (unsigned char*) next_line;
- break;
- }
-
- newlines++;
- size += spaces -1;
- if (BUFFER_OOB(cur_line+size) || size > 2*search_len)
- return NULL;
- search_len = size;
- spaces = first_chars? 0:1;
- break;
-
- default:
- if (prefs.line_mode==JOIN || newlines>0) {
- while (spaces) {
- spaces--;
- ADVANCE_COUNTERS(' ');
- if (LINE_IS_FULL) {
- size = search_len = j;
- break;
- }
- }
- newlines=0;
- } else if (spaces) {
- /* REFLOW, multiple spaces between words: count only
- * one. If more are needed, they will be added
- * while drawing. */
- search_len = size;
- spaces=0;
- ADVANCE_COUNTERS(' ');
- if (LINE_IS_FULL) {
- size = search_len = j;
- break;
- }
- }
- first_chars = false;
- ADVANCE_COUNTERS(c);
- break;
- }
- }
- }
- else {
- /* find first hard return */
- next_line = find_first_feed(cur_line, size);
- }
-
- if (next_line == NULL)
- if (size == search_len) {
- if (prefs.word_mode == WRAP) /* Find last space */
- next_line = find_last_space(cur_line, size);
-
- if (next_line == NULL)
- next_line = crop_at_width(cur_line);
- else
- if (prefs.word_mode == WRAP)
- for (i=0;
- i<WRAP_TRIM && isspace(next_line[0]) && !BUFFER_OOB(next_line);
- i++)
- next_line++;
- }
-
- if (prefs.line_mode == EXPAND)
- if (!BUFFER_OOB(next_line)) /* Not Null & not out of bounds */
- if (next_line[0] == 0)
- if (next_line != cur_line)
- return (unsigned char*) next_line;
-
- /* If next_line is pointing to a zero, increment it; i.e.,
- leave the terminator at the end of cur_line. If pointing
- to a hyphen, increment only if there is room to display
- the hyphen on current line (won't apply in WIDE mode,
- since it's guarenteed there won't be room). */
- if (!BUFFER_OOB(next_line)) /* Not Null & not out of bounds */
- if (next_line[0] == 0)/* ||
- (next_line[0] == '-' && next_line-cur_line < draw_columns)) */
- next_line++;
-
- if (BUFFER_OOB(next_line))
- {
- if (BUFFER_EOF() && next_line != cur_line)
- return (unsigned char*) next_line;
- return NULL;
- }
-
- if (is_short)
- *is_short = false;
-
- return (unsigned char*) next_line;
-}
-
-static unsigned char* find_prev_line(const unsigned char* cur_line)
-{
- const unsigned char *prev_line = NULL;
- const unsigned char *p;
-
- if BUFFER_OOB(cur_line)
- return NULL;
-
- /* To wrap consistently at the same places, we must
- start with a known hard return, then work downwards.
- We can either search backwards for a hard return,
- or simply start wrapping downwards from top of buffer.
- If current line is not near top of buffer, this is
- a file with long lines (paragraphs). We would need to
- read earlier sectors before we could decide how to
- properly wrap the lines above the current line, but
- it probably is not worth the disk access. Instead,
- start with top of buffer and wrap down from there.
- This may result in some lines wrapping at different
- points from where they wrap when scrolling down.
- If buffer is at top of file, start at top of buffer. */
-
- if ((prefs.line_mode == JOIN) || (prefs.line_mode == REFLOW))
- prev_line = p = NULL;
- else
- prev_line = p = find_last_feed(buffer, cur_line-buffer-1);
- /* Null means no line feeds in buffer above current line. */
-
- if (prev_line == NULL)
- if (BUFFER_BOF() || cur_line - buffer > READ_PREV_ZONE)
- prev_line = p = buffer;
- /* (else return NULL and read previous block) */
-
- /* Wrap downwards until too far, then use the one before. */
- while (p != NULL && p < cur_line) {
- prev_line = p;
- p = find_next_line(prev_line, NULL);
- }
-
- if (BUFFER_OOB(prev_line))
- return NULL;
-
- return (unsigned char*) prev_line;
-}
-
-static void check_bom(void)
-{
- unsigned char bom[BOM_SIZE];
- off_t orig = rb->lseek(fd, 0, SEEK_CUR);
-
- is_bom = false;
-
- rb->lseek(fd, 0, SEEK_SET);
-
- if (rb->read(fd, bom, BOM_SIZE) == BOM_SIZE)
- is_bom = !memcmp(bom, BOM, BOM_SIZE);
-
- rb->lseek(fd, orig, SEEK_SET);
-}
-
-static void fill_buffer(long pos, unsigned char* buf, unsigned size)
-{
- /* Read from file and preprocess the data */
- /* To minimize disk access, always read on sector boundaries */
- unsigned numread, i;
- bool found_CR = false;
- off_t offset = rb->lseek(fd, pos, SEEK_SET);
-
- if (offset == 0 && prefs.encoding == UTF_8 && is_bom)
- rb->lseek(fd, BOM_SIZE, SEEK_SET);
-
- numread = rb->read(fd, buf, size);
- buf[numread] = 0;
- rb->button_clear_queue(); /* clear button queue */
-
- for(i = 0; i < numread; i++) {
- switch(buf[i]) {
- case '\r':
- if (mac_text) {
- buf[i] = 0;
- }
- else {
- buf[i] = ' ';
- found_CR = true;
- }
- break;
-
- case '\n':
- buf[i] = 0;
- found_CR = false;
- break;
-
- case 0: /* No break between case 0 and default, intentionally */
- buf[i] = ' ';
- default:
- if (found_CR) {
- buf[i - 1] = 0;
- found_CR = false;
- mac_text = true;
- }
- break;
- }
- }
-}
-
-static int read_and_synch(int direction)
-{
-/* Read next (or prev) block, and reposition global pointers. */
-/* direction: 1 for down (i.e., further into file), -1 for up */
- int move_size, move_vector, offset;
- unsigned char *fill_buf;
-
- if (direction == -1) /* up */ {
- move_size = SMALL_BLOCK_SIZE;
- offset = 0;
- fill_buf = TOP_SECTOR;
- rb->memcpy(BOTTOM_SECTOR, MID_SECTOR, SMALL_BLOCK_SIZE);
- rb->memcpy(MID_SECTOR, TOP_SECTOR, SMALL_BLOCK_SIZE);
- }
- else /* down */ {
- if (prefs.view_mode == WIDE) {
- /* WIDE mode needs more buffer so we have to read smaller blocks */
- move_size = SMALL_BLOCK_SIZE;
- offset = LARGE_BLOCK_SIZE;
- fill_buf = BOTTOM_SECTOR;
- rb->memcpy(TOP_SECTOR, MID_SECTOR, SMALL_BLOCK_SIZE);
- rb->memcpy(MID_SECTOR, BOTTOM_SECTOR, SMALL_BLOCK_SIZE);
- }
- else {
- move_size = LARGE_BLOCK_SIZE;
- offset = SMALL_BLOCK_SIZE;
- fill_buf = MID_SECTOR;
- rb->memcpy(TOP_SECTOR, BOTTOM_SECTOR, SMALL_BLOCK_SIZE);
- }
- }
- move_vector = direction * move_size;
- screen_top_ptr -= move_vector;
- file_pos += move_vector;
- buffer_end = BUFFER_END(); /* Update whenever file_pos changes */
- fill_buffer(file_pos + offset, fill_buf, move_size);
- return move_vector;
-}
-
-static void get_next_line_position(unsigned char **line_begin,
- unsigned char **line_end,
- bool *is_short)
-{
- int resynch_move;
-
- *line_begin = *line_end;
- *line_end = find_next_line(*line_begin, is_short);
-
- if (*line_end == NULL && !BUFFER_EOF())
- {
- resynch_move = read_and_synch(1); /* Read block & move ptrs */
- *line_begin -= resynch_move;
- if (next_line_ptr > buffer)
- next_line_ptr -= resynch_move;
-
- *line_end = find_next_line(*line_begin, is_short);
- }
-}
-
-/* open, close, get file size functions */
-
-bool viewer_open(const unsigned char *fname)
-{
- if (fname == 0)
- return false;
-
- rb->strlcpy(file_name, fname, MAX_PATH+1);
- fd = rb->open(fname, O_RDONLY);
- return (fd >= 0);
-}
-
-void viewer_close(void)
-{
- if (fd >= 0)
- rb->close(fd);
-}
-
-/* When a file is UTF-8 file with BOM, if prefs.encoding is UTF-8,
- * then file size decreases only BOM_SIZE.
- */
-static void get_filesize(void)
-{
- file_size = rb->filesize(fd);
- if (file_size == -1)
- return;
-
- if (prefs.encoding == UTF_8 && is_bom)
- file_size -= BOM_SIZE;
-}