Merge branch '3250_mcviewer'

* 3250_mcviewer:
  Tickets #3250, #3256: rewrite mcview's rendering and scrolling
This commit is contained in:
Andrew Borodin 2015-01-08 19:30:50 +03:00
commit 6b5ba76c6a
13 changed files with 1124 additions and 505 deletions

View File

@ -64,6 +64,7 @@ Egmont Koblinger <egmont@gmail.com>
Support of extended mouse clicks beyond 223 column Support of extended mouse clicks beyond 223 column
Support of bracketed paste mode of xterm Support of bracketed paste mode of xterm
(http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Bracketed%20Paste%20Mode) (http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Bracketed%20Paste%20Mode)
Rewritten viewer
Erwin van Eijk <wabbit@corner.iaf.nl> Erwin van Eijk <wabbit@corner.iaf.nl>

View File

@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libmcviewer.la
libmcviewer_la_SOURCES = \ libmcviewer_la_SOURCES = \
actions_cmd.c \ actions_cmd.c \
ascii.c \
coord_cache.c \ coord_cache.c \
datasource.c \ datasource.c \
dialogs.c \ dialogs.c \
@ -16,7 +17,6 @@ libmcviewer_la_SOURCES = \
mcviewer.h \ mcviewer.h \
move.c \ move.c \
nroff.c \ nroff.c \
plain.c \
search.c search.c
AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS) AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS)

View File

@ -510,6 +510,8 @@ mcview_execute_cmd (mcview_t * view, unsigned long command)
break; break;
case CK_Bookmark: case CK_Bookmark:
view->dpy_start = view->marks[view->marker]; view->dpy_start = view->marks[view->marker];
view->dpy_paragraph_skip_lines = 0; /* TODO: remember this value in the marker? */
view->dpy_wrap_dirty = TRUE;
view->dirty++; view->dirty++;
break; break;
#ifdef HAVE_CHARSET #ifdef HAVE_CHARSET
@ -592,6 +594,7 @@ mcview_adjust_size (WDialog * h)
widget_set_size (WIDGET (view), 0, 0, LINES - 1, COLS); widget_set_size (WIDGET (view), 0, 0, LINES - 1, COLS);
widget_set_size (WIDGET (b), LINES - 1, 0, 1, COLS); widget_set_size (WIDGET (b), LINES - 1, 0, 1, COLS);
view->dpy_wrap_dirty = TRUE;
mcview_compute_areas (view); mcview_compute_areas (view);
mcview_update_bytes_per_line (view); mcview_update_bytes_per_line (view);
} }

1038
src/viewer/ascii.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -152,7 +152,7 @@ mcview_get_ptr_file (mcview_t * view, off_t byte_index)
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
int int
mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * result) mcview_get_utf (mcview_t * view, off_t byte_index, int *bytes_consumed, gboolean * result)
{ {
gchar *str = NULL; gchar *str = NULL;
int res = -1; int res = -1;
@ -160,7 +160,7 @@ mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * r
gchar *next_ch = NULL; gchar *next_ch = NULL;
gchar utf8buf[UTF8_CHAR_LEN + 1]; gchar utf8buf[UTF8_CHAR_LEN + 1];
*char_width = 0; *bytes_consumed = 0;
*result = FALSE; *result = FALSE;
switch (view->datasource) switch (view->datasource)
@ -206,7 +206,7 @@ mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * r
if (res < 0) if (res < 0)
{ {
ch = *str; ch = *str;
*char_width = 1; *bytes_consumed = 1;
} }
else else
{ {
@ -214,7 +214,7 @@ mcview_get_utf (mcview_t * view, off_t byte_index, int *char_width, gboolean * r
/* Calculate UTF-8 char width */ /* Calculate UTF-8 char width */
next_ch = g_utf8_next_char (str); next_ch = g_utf8_next_char (str);
if (next_ch) if (next_ch)
*char_width = next_ch - str; *bytes_consumed = next_ch - str;
else else
return 0; return 0;
} }

View File

@ -251,10 +251,6 @@ mcview_display (mcview_t * view)
{ {
mcview_display_hex (view); mcview_display_hex (view);
} }
else if (view->text_nroff_mode)
{
mcview_display_nroff (view);
}
else else
{ {
mcview_display_text (view); mcview_display_text (view);

View File

@ -87,6 +87,18 @@ typedef struct
coord_cache_entry_t **cache; coord_cache_entry_t **cache;
} coord_cache_t; } coord_cache_t;
/* TODO: find a better name. This is not actually a "state machine",
* but a "state machine's state", but that sounds silly.
* Could be parser_state, formatter_state... */
typedef struct
{
off_t offset; /* The file offset at which this is the state. */
off_t unwrapped_column; /* Columns if the paragraph wasn't wrapped, */
/* used for positioning TABs in wrapped lines */
gboolean nroff_underscore_is_underlined; /* whether _\b_ is underlined rather than bold */
gboolean print_lonely_combining; /* whether lonely combining marks are printed on a dotted circle */
} mcview_state_machine_t;
struct mcview_nroff_struct; struct mcview_nroff_struct;
struct mcview_struct struct mcview_struct
@ -144,8 +156,12 @@ struct mcview_struct
/* Display information */ /* Display information */
gboolean active; /* Active or not in QuickView mode */ gboolean active; /* Active or not in QuickView mode */
screen_dimen dpy_frame_size; /* Size of the frame surrounding the real viewer */ screen_dimen dpy_frame_size; /* Size of the frame surrounding the real viewer */
off_t dpy_start; /* Offset of the displayed data */ off_t dpy_start; /* Offset of the displayed data (start of the paragraph in non-hex mode) */
off_t dpy_end; /* Offset after the displayed data */ off_t dpy_end; /* Offset after the displayed data */
off_t dpy_paragraph_skip_lines; /* Extra lines to skip in wrap mode */
mcview_state_machine_t dpy_state_top; /* Parser-formatter state at the topmost visible line in wrap mode */
mcview_state_machine_t dpy_state_bottom; /* Parser-formatter state after the bottomvisible line in wrap mode */
gboolean dpy_wrap_dirty; /* dpy_state_top needs to be recomputed */
off_t dpy_text_column; /* Number of skipped columns in non-wrap off_t dpy_text_column; /* Number of skipped columns in non-wrap
* text mode */ * text mode */
off_t hex_cursor; /* Hexview cursor position in file */ off_t hex_cursor; /* Hexview cursor position in file */
@ -156,6 +172,8 @@ struct mcview_struct
struct area ruler_area; /* Where the ruler is displayed */ struct area ruler_area; /* Where the ruler is displayed */
struct area data_area; /* Where the data is displayed */ struct area data_area; /* Where the data is displayed */
ssize_t force_max; /* Force a max offset, or -1 */
int dirty; /* Number of skipped updates */ int dirty; /* Number of skipped updates */
gboolean dpy_bbar_dirty; /* Does the button bar need to be updated? */ gboolean dpy_bbar_dirty; /* Does the button bar need to be updated? */
@ -223,6 +241,14 @@ cb_ret_t mcview_callback (Widget * w, Widget * sender, widget_msg_t msg, int par
cb_ret_t mcview_dialog_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm, cb_ret_t mcview_dialog_callback (Widget * w, Widget * sender, widget_msg_t msg, int parm,
void *data); void *data);
/* ascii.c: */
void mcview_display_text (mcview_t *);
void mcview_state_machine_init (mcview_state_machine_t *, off_t);
void mcview_ascii_move_down (mcview_t *, off_t);
void mcview_ascii_move_up (mcview_t *, off_t);
void mcview_ascii_moveto_bol (mcview_t *);
void mcview_ascii_moveto_eol (mcview_t *);
/* coord_cache.c: */ /* coord_cache.c: */
coord_cache_t *coord_cache_new (void); coord_cache_t *coord_cache_new (void);
void coord_cache_free (coord_cache_t * cache); void coord_cache_free (coord_cache_t * cache);
@ -312,9 +338,7 @@ void mcview_place_cursor (mcview_t *);
void mcview_moveto_match (mcview_t *); void mcview_moveto_match (mcview_t *);
/* nroff.c: */ /* nroff.c: */
void mcview_display_nroff (mcview_t * view);
int mcview__get_nroff_real_len (mcview_t * view, off_t, off_t p); int mcview__get_nroff_real_len (mcview_t * view, off_t, off_t p);
mcview_nroff_t *mcview_nroff_seq_new_num (mcview_t * view, off_t p); mcview_nroff_t *mcview_nroff_seq_new_num (mcview_t * view, off_t p);
mcview_nroff_t *mcview_nroff_seq_new (mcview_t * view); mcview_nroff_t *mcview_nroff_seq_new (mcview_t * view);
void mcview_nroff_seq_free (mcview_nroff_t **); void mcview_nroff_seq_free (mcview_nroff_t **);
@ -322,10 +346,6 @@ nroff_type_t mcview_nroff_seq_info (mcview_nroff_t *);
int mcview_nroff_seq_next (mcview_nroff_t *); int mcview_nroff_seq_next (mcview_nroff_t *);
int mcview_nroff_seq_prev (mcview_nroff_t *); int mcview_nroff_seq_prev (mcview_nroff_t *);
/* plain.c: */
void mcview_display_text (mcview_t *);
/* search.c: */ /* search.c: */
mc_search_cbret_t mcview_search_cmd_callback (const void *user_data, gsize char_offset, mc_search_cbret_t mcview_search_cmd_callback (const void *user_data, gsize char_offset,
int *current_char); int *current_char);

View File

@ -106,9 +106,8 @@ mcview_toggle_magic_mode (mcview_t * view)
void void
mcview_toggle_wrap_mode (mcview_t * view) mcview_toggle_wrap_mode (mcview_t * view)
{ {
if (view->text_wrap_mode)
view->dpy_start = mcview_bol (view, view->dpy_start, 0);
view->text_wrap_mode = !view->text_wrap_mode; view->text_wrap_mode = !view->text_wrap_mode;
view->dpy_wrap_dirty = TRUE;
view->dpy_bbar_dirty = TRUE; view->dpy_bbar_dirty = TRUE;
view->dirty++; view->dirty++;
} }
@ -120,6 +119,7 @@ mcview_toggle_nroff_mode (mcview_t * view)
{ {
view->text_nroff_mode = !view->text_nroff_mode; view->text_nroff_mode = !view->text_nroff_mode;
mcview_altered_nroff_flag = 1; mcview_altered_nroff_flag = 1;
view->dpy_wrap_dirty = TRUE;
view->dpy_bbar_dirty = TRUE; view->dpy_bbar_dirty = TRUE;
view->dirty++; view->dirty++;
} }
@ -144,6 +144,8 @@ mcview_toggle_hex_mode (mcview_t * view)
widget_want_cursor (WIDGET (view), FALSE); widget_want_cursor (WIDGET (view), FALSE);
} }
mcview_altered_hex_mode = 1; mcview_altered_hex_mode = 1;
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
view->dpy_bbar_dirty = TRUE; view->dpy_bbar_dirty = TRUE;
view->dirty++; view->dirty++;
} }
@ -170,6 +172,10 @@ mcview_init (mcview_t * view)
view->coord_cache = NULL; view->coord_cache = NULL;
view->dpy_start = 0; view->dpy_start = 0;
view->dpy_paragraph_skip_lines = 0;
mcview_state_machine_init (&view->dpy_state_top, 0);
view->dpy_wrap_dirty = FALSE;
view->force_max = -1;
view->dpy_text_column = 0; view->dpy_text_column = 0;
view->dpy_end = 0; view->dpy_end = 0;
view->hex_cursor = 0; view->hex_cursor = 0;
@ -281,6 +287,7 @@ mcview_set_codeset (mcview_t * view)
view->converter = conv; view->converter = conv;
} }
view->utf8 = (gboolean) str_isutf8 (cp_id); view->utf8 = (gboolean) str_isutf8 (cp_id);
view->dpy_wrap_dirty = TRUE;
} }
#else #else
(void) view; (void) view;
@ -333,7 +340,7 @@ mcview_bol (mcview_t * view, off_t current, off_t limit)
if (c == '\r') if (c == '\r')
current--; current--;
} }
while (current > 0 && current >= limit) while (current > 0 && current > limit)
{ {
if (!mcview_get_byte (view, current - 1, &c)) if (!mcview_get_byte (view, current - 1, &c))
break; break;

View File

@ -406,6 +406,10 @@ mcview_load (mcview_t * view, const char *command, const char *file, int start_l
finish: finish:
view->command = g_strdup (command); view->command = g_strdup (command);
view->dpy_start = 0; view->dpy_start = 0;
view->dpy_paragraph_skip_lines = 0;
mcview_state_machine_init (&view->dpy_state_top, 0);
view->dpy_wrap_dirty = FALSE;
view->force_max = -1;
view->search_start = 0; view->search_start = 0;
view->search_end = 0; view->search_end = 0;
view->dpy_text_column = 0; view->dpy_text_column = 0;
@ -425,7 +429,10 @@ mcview_load (mcview_t * view, const char *command, const char *file, int start_l
else else
new_offset = min (new_offset, max_offset); new_offset = min (new_offset, max_offset);
if (!view->hex_mode) if (!view->hex_mode)
{
view->dpy_start = mcview_bol (view, new_offset, 0); view->dpy_start = mcview_bol (view, new_offset, 0);
view->dpy_wrap_dirty = TRUE;
}
else else
{ {
view->dpy_start = new_offset - new_offset % view->bytes_per_line; view->dpy_start = new_offset - new_offset % view->bytes_per_line;

View File

@ -83,6 +83,8 @@ mcview_scroll_to_cursor (mcview_t * view)
if (cursor < topleft) if (cursor < topleft)
topleft = mcview_offset_rounddown (cursor, bytes); topleft = mcview_offset_rounddown (cursor, bytes);
view->dpy_start = topleft; view->dpy_start = topleft;
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
} }
} }
@ -107,8 +109,6 @@ mcview_movement_fixups (mcview_t * view, gboolean reset_search)
void void
mcview_move_up (mcview_t * view, off_t lines) mcview_move_up (mcview_t * view, off_t lines)
{ {
off_t new_offset;
if (view->hex_mode) if (view->hex_mode)
{ {
off_t bytes = lines * view->bytes_per_line; off_t bytes = lines * view->bytes_per_line;
@ -116,7 +116,11 @@ mcview_move_up (mcview_t * view, off_t lines)
{ {
view->hex_cursor -= bytes; view->hex_cursor -= bytes;
if (view->hex_cursor < view->dpy_start) if (view->hex_cursor < view->dpy_start)
{
view->dpy_start = mcview_offset_doz (view->dpy_start, bytes); view->dpy_start = mcview_offset_doz (view->dpy_start, bytes);
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
}
} }
else else
{ {
@ -125,46 +129,7 @@ mcview_move_up (mcview_t * view, off_t lines)
} }
else else
{ {
off_t i; mcview_ascii_move_up (view, lines);
for (i = 0; i < lines; i++)
{
if (view->dpy_start == 0)
break;
if (view->text_wrap_mode)
{
new_offset = mcview_bol (view, view->dpy_start, view->dpy_start - (off_t) 1);
/* check if dpy_start == BOL or not (then new_offset = dpy_start - 1,
* no need to check more) */
if (new_offset == view->dpy_start)
{
size_t last_row_length;
new_offset = mcview_bol (view, new_offset - 1, 0);
last_row_length = (view->dpy_start - new_offset) % view->data_area.width;
if (last_row_length != 0)
{
/* if dpy_start == BOL in wrapped mode, find BOL of previous line
* and move down all but the last rows */
new_offset = view->dpy_start - (off_t) last_row_length;
}
}
else
{
/* if dpy_start != BOL in wrapped mode, just move one row up;
* no need to check if > 0 as there is at least exactly one wrap
* between dpy_start and BOL */
new_offset = view->dpy_start - (off_t) view->data_area.width;
}
view->dpy_start = new_offset;
}
else
{
/* if unwrapped -> current BOL equals dpy_start, just find BOL of previous line */
new_offset = view->dpy_start - 1;
view->dpy_start = mcview_bol (view, new_offset, 0);
}
}
} }
mcview_movement_fixups (view, TRUE); mcview_movement_fixups (view, TRUE);
} }
@ -186,51 +151,16 @@ mcview_move_down (mcview_t * view, off_t lines)
{ {
view->hex_cursor += view->bytes_per_line; view->hex_cursor += view->bytes_per_line;
if (lines != 1) if (lines != 1)
{
view->dpy_start += view->bytes_per_line; view->dpy_start += view->bytes_per_line;
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
}
} }
} }
else else
{ {
off_t new_offset = 0; mcview_ascii_move_down (view, lines);
if (view->dpy_end - view->dpy_start > last_byte - view->dpy_end)
{
while (lines-- > 0)
{
if (view->text_wrap_mode)
view->dpy_end =
mcview_eol (view, view->dpy_end,
view->dpy_end + (off_t) view->data_area.width);
else
view->dpy_end = mcview_eol (view, view->dpy_end, last_byte);
if (view->text_wrap_mode)
new_offset =
mcview_eol (view, view->dpy_start,
view->dpy_start + (off_t) view->data_area.width);
else
new_offset = mcview_eol (view, view->dpy_start, last_byte);
if (new_offset < last_byte)
view->dpy_start = new_offset;
if (view->dpy_end >= last_byte)
break;
}
}
else
{
off_t i;
for (i = 0; i < lines && new_offset < last_byte; i++)
{
if (view->text_wrap_mode)
new_offset =
mcview_eol (view, view->dpy_start,
view->dpy_start + (off_t) view->data_area.width);
else
new_offset = mcview_eol (view, view->dpy_start, last_byte);
if (new_offset < last_byte)
view->dpy_start = new_offset;
}
}
} }
mcview_movement_fixups (view, TRUE); mcview_movement_fixups (view, TRUE);
} }
@ -255,9 +185,8 @@ mcview_move_left (mcview_t * view, off_t columns)
if (old_cursor > 0 || view->hexedit_lownibble) if (old_cursor > 0 || view->hexedit_lownibble)
view->hexedit_lownibble = !view->hexedit_lownibble; view->hexedit_lownibble = !view->hexedit_lownibble;
} }
else else if (!view->text_wrap_mode)
view->dpy_text_column = mcview_offset_doz (view->dpy_text_column, columns); view->dpy_text_column = mcview_offset_doz (view->dpy_text_column, columns);
mcview_movement_fixups (view, FALSE); mcview_movement_fixups (view, FALSE);
} }
@ -284,7 +213,7 @@ mcview_move_right (mcview_t * view, off_t columns)
if (old_cursor < last_byte || !view->hexedit_lownibble) if (old_cursor < last_byte || !view->hexedit_lownibble)
view->hexedit_lownibble = !view->hexedit_lownibble; view->hexedit_lownibble = !view->hexedit_lownibble;
} }
else else if (!view->text_wrap_mode)
{ {
view->dpy_text_column += columns; view->dpy_text_column += columns;
} }
@ -297,6 +226,8 @@ void
mcview_moveto_top (mcview_t * view) mcview_moveto_top (mcview_t * view)
{ {
view->dpy_start = 0; view->dpy_start = 0;
view->dpy_paragraph_skip_lines = 0;
mcview_state_machine_init (&view->dpy_state_top, 0);
view->hex_cursor = 0; view->hex_cursor = 0;
view->dpy_text_column = 0; view->dpy_text_column = 0;
mcview_movement_fixups (view, TRUE); mcview_movement_fixups (view, TRUE);
@ -326,6 +257,8 @@ mcview_moveto_bottom (mcview_t * view)
const off_t datalines = view->data_area.height; const off_t datalines = view->data_area.height;
view->dpy_start = filesize; view->dpy_start = filesize;
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
mcview_move_up (view, datalines); mcview_move_up (view, datalines);
} }
} }
@ -338,12 +271,12 @@ mcview_moveto_bol (mcview_t * view)
if (view->hex_mode) if (view->hex_mode)
{ {
view->hex_cursor -= view->hex_cursor % view->bytes_per_line; view->hex_cursor -= view->hex_cursor % view->bytes_per_line;
view->dpy_text_column = 0;
} }
else if (!view->text_wrap_mode) else
{ {
view->dpy_start = mcview_bol (view, view->dpy_start, 0); mcview_ascii_moveto_bol (view);
} }
view->dpy_text_column = 0;
mcview_movement_fixups (view, TRUE); mcview_movement_fixups (view, TRUE);
} }
@ -370,43 +303,7 @@ mcview_moveto_eol (mcview_t * view)
} }
else else
{ {
off_t eol; mcview_ascii_moveto_eol (view);
bol = mcview_bol (view, view->dpy_start, 0);
eol = mcview_eol (view, view->dpy_start, mcview_get_filesize (view));
#ifdef HAVE_CHARSET
if (view->utf8)
{
char *str = NULL;
switch (view->datasource)
{
case DS_STDIO_PIPE:
case DS_VFS_PIPE:
str = mcview_get_ptr_growing_buffer (view, bol);
break;
case DS_FILE:
str = mcview_get_ptr_file (view, bol);
break;
case DS_STRING:
str = mcview_get_ptr_string (view, bol);
break;
case DS_NONE:
break;
}
if (str != NULL && eol > bol)
view->dpy_text_column = g_utf8_strlen (str, eol - bol);
else
view->dpy_text_column = eol - bol;
}
else
#endif /* HAVE_CHARSET */
if (eol > bol)
view->dpy_text_column = eol - bol;
view->dpy_text_column =
mcview_offset_doz (view->dpy_text_column, (off_t) view->data_area.width);
} }
mcview_movement_fixups (view, FALSE); mcview_movement_fixups (view, FALSE);
} }
@ -420,10 +317,14 @@ mcview_moveto_offset (mcview_t * view, off_t offset)
{ {
view->hex_cursor = offset; view->hex_cursor = offset;
view->dpy_start = offset - offset % view->bytes_per_line; view->dpy_start = offset - offset % view->bytes_per_line;
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
} }
else else
{ {
view->dpy_start = offset; view->dpy_start = offset;
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
} }
mcview_movement_fixups (view, TRUE); mcview_movement_fixups (view, TRUE);
} }
@ -494,9 +395,15 @@ mcview_moveto_match (mcview_t * view)
view->hexedit_lownibble = FALSE; view->hexedit_lownibble = FALSE;
view->dpy_start = view->search_start - view->search_start % view->bytes_per_line; view->dpy_start = view->search_start - view->search_start % view->bytes_per_line;
view->dpy_end = view->search_end - view->search_end % view->bytes_per_line; view->dpy_end = view->search_end - view->search_end % view->bytes_per_line;
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
} }
else else
{
view->dpy_start = mcview_bol (view, view->search_start, 0); view->dpy_start = mcview_bol (view, view->search_start, 0);
view->dpy_paragraph_skip_lines = 0;
view->dpy_wrap_dirty = TRUE;
}
mcview_scroll_to_cursor (view); mcview_scroll_to_cursor (view);
view->dirty++; view->dirty++;

View File

@ -1,6 +1,6 @@
/* /*
Internal file viewer for the Midnight Commander Internal file viewer for the Midnight Commander
Function for nroff-like view Functions for searching in nroff-like view
Copyright (C) 1994-2014 Copyright (C) 1994-2014
Free Software Foundation, Inc. Free Software Foundation, Inc.
@ -91,162 +91,6 @@ mcview_nroff_get_char (mcview_nroff_t * nroff, int *ret_val, off_t nroff_index)
/*** public functions ****************************************************************************/ /*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */ /* --------------------------------------------------------------------------------------------- */
void
mcview_display_nroff (mcview_t * view)
{
const screen_dimen left = view->data_area.left;
const screen_dimen top = view->data_area.top;
const screen_dimen width = view->data_area.width;
const screen_dimen height = view->data_area.height;
screen_dimen row, col;
off_t from;
int cw = 1;
int c;
int c_prev = 0;
int c_next = 0;
mcview_display_clean (view);
mcview_display_ruler (view);
/* Find the first displayable changed byte */
from = view->dpy_start;
tty_setcolor (VIEW_NORMAL_COLOR);
for (row = 0, col = 0; row < height;)
{
#ifdef HAVE_CHARSET
if (view->utf8)
{
gboolean read_res = TRUE;
c = mcview_get_utf (view, from, &cw, &read_res);
if (!read_res)
break;
}
else
#endif
{
if (!mcview_get_byte (view, from, &c))
break;
}
from++;
if (cw > 1)
from += cw - 1;
if (c == '\b')
{
if (from > 1)
{
#ifdef HAVE_CHARSET
if (view->utf8)
{
gboolean read_res;
c_next = mcview_get_utf (view, from, &cw, &read_res);
}
else
#endif
mcview_get_byte (view, from, &c_next);
}
if (g_unichar_isprint (c_prev) && g_unichar_isprint (c_next)
&& (c_prev == c_next || c_prev == '_' || (c_prev == '+' && c_next == 'o')))
{
if (col == 0)
{
if (row == 0)
{
/* We're inside an nroff character sequence at the
* beginning of the screen -- just skip the
* backspace and continue with the next character. */
continue;
}
row--;
col = width;
}
col--;
if (c_prev == '_'
&& (c_next != '_' || mcview_count_backspaces (view, from + 1) == 1))
tty_setcolor (VIEW_UNDERLINED_COLOR);
else
tty_setcolor (VIEW_BOLD_COLOR);
continue;
}
}
if ((c == '\n') || (col >= width && view->text_wrap_mode))
{
col = 0;
row++;
if (c == '\n' || row >= height)
continue;
}
if (c == '\r')
{
mcview_get_byte_indexed (view, from, 1, &c);
if (c == '\r' || c == '\n')
continue;
col = 0;
row++;
continue;
}
if (c == '\t')
{
off_t line, column;
mcview_offset_to_coord (view, &line, &column, from);
col += (option_tab_spacing - col % option_tab_spacing);
if (view->text_wrap_mode && col >= width && width != 0)
{
row += col / width;
col %= width;
}
continue;
}
if (view->search_start <= from && from < view->search_end)
{
tty_setcolor (SELECTED_COLOR);
}
c_prev = c;
if ((off_t) col >= view->dpy_text_column
&& (off_t) col - view->dpy_text_column < (off_t) width)
{
widget_move (view, top + row, left + ((off_t) col - view->dpy_text_column));
#ifdef HAVE_CHARSET
if (mc_global.utf8_display)
{
if (!view->utf8)
{
c = convert_from_8bit_to_utf_c ((unsigned char) c, view->converter);
}
if (!g_unichar_isprint (c))
c = '.';
}
else if (view->utf8)
c = convert_from_utf_to_current_c (c, view->converter);
else
c = convert_to_display_c (c);
#endif
tty_print_anychar (c);
}
col++;
#ifdef HAVE_CHARSET
if (view->utf8)
{
if (g_unichar_iswide (c))
col++;
else if (g_unichar_iszerowidth (c))
col--;
}
#endif
tty_setcolor (VIEW_NORMAL_COLOR);
}
view->dpy_end = from;
}
/* --------------------------------------------------------------------------------------------- */
int int
mcview__get_nroff_real_len (mcview_t * view, off_t start, off_t length) mcview__get_nroff_real_len (mcview_t * view, off_t start, off_t length)
{ {

View File

@ -1,204 +0,0 @@
/*
Internal file viewer for the Midnight Commander
Function for plain view
Copyright (C) 1994-2014
Free Software Foundation, Inc.
Written by:
Miguel de Icaza, 1994, 1995, 1998
Janne Kukonlehto, 1994, 1995
Jakub Jelinek, 1995
Joseph M. Hinkle, 1996
Norbert Warmuth, 1997
Pavel Machek, 1998
Roland Illig <roland.illig@gmx.de>, 2004, 2005
Slava Zanko <slavazanko@google.com>, 2009
Andrew Borodin <aborodin@vmail.ru>, 2009-2014
Ilia Maslakov <il.smind@gmail.com>, 2009
This file is part of the Midnight Commander.
The Midnight Commander 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 3 of the License,
or (at your option) any later version.
The Midnight Commander is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <config.h>
#include "lib/global.h"
#include "lib/tty/tty.h"
#include "lib/skin.h"
#include "lib/util.h" /* is_printable() */
#ifdef HAVE_CHARSET
#include "lib/charsets.h"
#endif
#include "src/setup.h" /* option_tab_spacing */
#include "internal.h"
/*** global variables ****************************************************************************/
/*** file scope macro definitions ****************************************************************/
/*** file scope type declarations ****************************************************************/
/*** file scope variables ************************************************************************/
/*** file scope functions ************************************************************************/
/* --------------------------------------------------------------------------------------------- */
/* --------------------------------------------------------------------------------------------- */
/*** public functions ****************************************************************************/
/* --------------------------------------------------------------------------------------------- */
void
mcview_display_text (mcview_t * view)
{
const screen_dimen left = view->data_area.left;
const screen_dimen top = view->data_area.top;
const screen_dimen width = view->data_area.width;
const screen_dimen height = view->data_area.height;
screen_dimen row = 0, col = 0;
off_t from;
int cw = 1;
int c, prev_ch = 0;
gboolean last_row = TRUE;
mcview_display_clean (view);
mcview_display_ruler (view);
/* Find the first displayable changed byte */
from = view->dpy_start;
while (row < height)
{
#ifdef HAVE_CHARSET
if (view->utf8)
{
gboolean read_res = TRUE;
c = mcview_get_utf (view, from, &cw, &read_res);
if (!read_res)
break;
}
else
#endif
if (!mcview_get_byte (view, from, &c))
break;
last_row = FALSE;
from++;
if (cw > 1)
from += cw - 1;
if (c != '\n' && prev_ch == '\r')
{
if (++row >= height)
break;
col = 0;
/* tty_print_anychar ('\n'); */
}
prev_ch = c;
if (c == '\r')
continue;
if (c == '\n')
{
col = 0;
row++;
continue;
}
if (col >= width && view->text_wrap_mode)
{
col = 0;
if (++row >= height)
break;
}
if (c == '\t')
{
col += (option_tab_spacing - col % option_tab_spacing);
if (view->text_wrap_mode && col >= width && width != 0)
{
row += col / width;
col %= width;
}
continue;
}
if (view->search_start <= from && from < view->search_end)
tty_setcolor (SELECTED_COLOR);
else
tty_setcolor (VIEW_NORMAL_COLOR);
if (((off_t) col >= view->dpy_text_column)
&& ((off_t) col - view->dpy_text_column < (off_t) width))
{
widget_move (view, top + row, left + ((off_t) col - view->dpy_text_column));
#ifdef HAVE_CHARSET
if (mc_global.utf8_display)
{
if (!view->utf8)
c = convert_from_8bit_to_utf_c ((unsigned char) c, view->converter);
if (!g_unichar_isprint (c))
c = '.';
}
else if (view->utf8)
c = convert_from_utf_to_current_c (c, view->converter);
else
{
c = convert_to_display_c (c);
if (!is_printable (c))
c = '.';
}
#else /* HAVE_CHARSET */
if (!is_printable (c))
c = '.';
#endif /* HAVE_CHARSET */
tty_print_anychar (c);
}
col++;
#ifdef HAVE_CHARSET
if (view->utf8)
{
if (g_unichar_iswide (c))
col++;
else if (g_unichar_iszerowidth (c))
col--;
}
#endif
}
view->dpy_end = from;
if (mcview_show_eof != NULL && mcview_show_eof[0] != '\0')
{
if (last_row && mcview_get_byte (view, from - 1, &c) && c != '\n')
row--;
while (++row < height)
{
widget_move (view, top + row, left);
tty_print_string (mcview_show_eof);
}
}
}
/* --------------------------------------------------------------------------------------------- */

Binary file not shown.