mirror of
https://github.com/MidnightCommander/mc
synced 2024-12-22 12:32:40 +03:00
Merge branch '3250_mcviewer'
* 3250_mcviewer: Tickets #3250, #3256: rewrite mcview's rendering and scrolling
This commit is contained in:
commit
6b5ba76c6a
1
AUTHORS
1
AUTHORS
@ -64,6 +64,7 @@ Egmont Koblinger <egmont@gmail.com>
|
||||
Support of extended mouse clicks beyond 223 column
|
||||
Support of bracketed paste mode of xterm
|
||||
(http://invisible-island.net/xterm/ctlseqs/ctlseqs.html#Bracketed%20Paste%20Mode)
|
||||
Rewritten viewer
|
||||
|
||||
Erwin van Eijk <wabbit@corner.iaf.nl>
|
||||
|
||||
|
@ -3,6 +3,7 @@ noinst_LTLIBRARIES = libmcviewer.la
|
||||
|
||||
libmcviewer_la_SOURCES = \
|
||||
actions_cmd.c \
|
||||
ascii.c \
|
||||
coord_cache.c \
|
||||
datasource.c \
|
||||
dialogs.c \
|
||||
@ -16,7 +17,6 @@ libmcviewer_la_SOURCES = \
|
||||
mcviewer.h \
|
||||
move.c \
|
||||
nroff.c \
|
||||
plain.c \
|
||||
search.c
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir) $(GLIB_CFLAGS) $(PCRE_CPPFLAGS)
|
||||
|
@ -510,6 +510,8 @@ mcview_execute_cmd (mcview_t * view, unsigned long command)
|
||||
break;
|
||||
case CK_Bookmark:
|
||||
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++;
|
||||
break;
|
||||
#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 (b), LINES - 1, 0, 1, COLS);
|
||||
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
mcview_compute_areas (view);
|
||||
mcview_update_bytes_per_line (view);
|
||||
}
|
||||
|
1038
src/viewer/ascii.c
Normal file
1038
src/viewer/ascii.c
Normal file
File diff suppressed because it is too large
Load Diff
@ -152,7 +152,7 @@ mcview_get_ptr_file (mcview_t * view, off_t byte_index)
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
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;
|
||||
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 utf8buf[UTF8_CHAR_LEN + 1];
|
||||
|
||||
*char_width = 0;
|
||||
*bytes_consumed = 0;
|
||||
*result = FALSE;
|
||||
|
||||
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)
|
||||
{
|
||||
ch = *str;
|
||||
*char_width = 1;
|
||||
*bytes_consumed = 1;
|
||||
}
|
||||
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 */
|
||||
next_ch = g_utf8_next_char (str);
|
||||
if (next_ch)
|
||||
*char_width = next_ch - str;
|
||||
*bytes_consumed = next_ch - str;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
@ -251,10 +251,6 @@ mcview_display (mcview_t * view)
|
||||
{
|
||||
mcview_display_hex (view);
|
||||
}
|
||||
else if (view->text_nroff_mode)
|
||||
{
|
||||
mcview_display_nroff (view);
|
||||
}
|
||||
else
|
||||
{
|
||||
mcview_display_text (view);
|
||||
|
@ -87,6 +87,18 @@ typedef struct
|
||||
coord_cache_entry_t **cache;
|
||||
} 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_struct
|
||||
@ -144,8 +156,12 @@ struct mcview_struct
|
||||
/* Display information */
|
||||
gboolean active; /* Active or not in QuickView mode */
|
||||
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_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
|
||||
* text mode */
|
||||
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 data_area; /* Where the data is displayed */
|
||||
|
||||
ssize_t force_max; /* Force a max offset, or -1 */
|
||||
|
||||
int dirty; /* Number of skipped updates */
|
||||
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,
|
||||
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_t *coord_cache_new (void);
|
||||
void coord_cache_free (coord_cache_t * cache);
|
||||
@ -312,9 +338,7 @@ void mcview_place_cursor (mcview_t *);
|
||||
void mcview_moveto_match (mcview_t *);
|
||||
|
||||
/* nroff.c: */
|
||||
void mcview_display_nroff (mcview_t * view);
|
||||
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 (mcview_t * view);
|
||||
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_prev (mcview_nroff_t *);
|
||||
|
||||
|
||||
/* plain.c: */
|
||||
void mcview_display_text (mcview_t *);
|
||||
|
||||
/* search.c: */
|
||||
mc_search_cbret_t mcview_search_cmd_callback (const void *user_data, gsize char_offset,
|
||||
int *current_char);
|
||||
|
@ -106,9 +106,8 @@ mcview_toggle_magic_mode (mcview_t * view)
|
||||
void
|
||||
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->dpy_wrap_dirty = TRUE;
|
||||
view->dpy_bbar_dirty = TRUE;
|
||||
view->dirty++;
|
||||
}
|
||||
@ -120,6 +119,7 @@ mcview_toggle_nroff_mode (mcview_t * view)
|
||||
{
|
||||
view->text_nroff_mode = !view->text_nroff_mode;
|
||||
mcview_altered_nroff_flag = 1;
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
view->dpy_bbar_dirty = TRUE;
|
||||
view->dirty++;
|
||||
}
|
||||
@ -144,6 +144,8 @@ mcview_toggle_hex_mode (mcview_t * view)
|
||||
widget_want_cursor (WIDGET (view), FALSE);
|
||||
}
|
||||
mcview_altered_hex_mode = 1;
|
||||
view->dpy_paragraph_skip_lines = 0;
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
view->dpy_bbar_dirty = TRUE;
|
||||
view->dirty++;
|
||||
}
|
||||
@ -170,6 +172,10 @@ mcview_init (mcview_t * view)
|
||||
view->coord_cache = NULL;
|
||||
|
||||
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_end = 0;
|
||||
view->hex_cursor = 0;
|
||||
@ -281,6 +287,7 @@ mcview_set_codeset (mcview_t * view)
|
||||
view->converter = conv;
|
||||
}
|
||||
view->utf8 = (gboolean) str_isutf8 (cp_id);
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
}
|
||||
#else
|
||||
(void) view;
|
||||
@ -333,7 +340,7 @@ mcview_bol (mcview_t * view, off_t current, off_t limit)
|
||||
if (c == '\r')
|
||||
current--;
|
||||
}
|
||||
while (current > 0 && current >= limit)
|
||||
while (current > 0 && current > limit)
|
||||
{
|
||||
if (!mcview_get_byte (view, current - 1, &c))
|
||||
break;
|
||||
|
@ -406,6 +406,10 @@ mcview_load (mcview_t * view, const char *command, const char *file, int start_l
|
||||
finish:
|
||||
view->command = g_strdup (command);
|
||||
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_end = 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
|
||||
new_offset = min (new_offset, max_offset);
|
||||
if (!view->hex_mode)
|
||||
{
|
||||
view->dpy_start = mcview_bol (view, new_offset, 0);
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
view->dpy_start = new_offset - new_offset % view->bytes_per_line;
|
||||
|
@ -83,6 +83,8 @@ mcview_scroll_to_cursor (mcview_t * view)
|
||||
if (cursor < topleft)
|
||||
topleft = mcview_offset_rounddown (cursor, bytes);
|
||||
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
|
||||
mcview_move_up (mcview_t * view, off_t lines)
|
||||
{
|
||||
off_t new_offset;
|
||||
|
||||
if (view->hex_mode)
|
||||
{
|
||||
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;
|
||||
if (view->hex_cursor < view->dpy_start)
|
||||
{
|
||||
view->dpy_start = mcview_offset_doz (view->dpy_start, bytes);
|
||||
view->dpy_paragraph_skip_lines = 0;
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -125,46 +129,7 @@ mcview_move_up (mcview_t * view, off_t lines)
|
||||
}
|
||||
else
|
||||
{
|
||||
off_t i;
|
||||
|
||||
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_ascii_move_up (view, lines);
|
||||
}
|
||||
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;
|
||||
if (lines != 1)
|
||||
{
|
||||
view->dpy_start += view->bytes_per_line;
|
||||
view->dpy_paragraph_skip_lines = 0;
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
off_t new_offset = 0;
|
||||
|
||||
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_ascii_move_down (view, lines);
|
||||
}
|
||||
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)
|
||||
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);
|
||||
|
||||
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)
|
||||
view->hexedit_lownibble = !view->hexedit_lownibble;
|
||||
}
|
||||
else
|
||||
else if (!view->text_wrap_mode)
|
||||
{
|
||||
view->dpy_text_column += columns;
|
||||
}
|
||||
@ -297,6 +226,8 @@ void
|
||||
mcview_moveto_top (mcview_t * view)
|
||||
{
|
||||
view->dpy_start = 0;
|
||||
view->dpy_paragraph_skip_lines = 0;
|
||||
mcview_state_machine_init (&view->dpy_state_top, 0);
|
||||
view->hex_cursor = 0;
|
||||
view->dpy_text_column = 0;
|
||||
mcview_movement_fixups (view, TRUE);
|
||||
@ -326,6 +257,8 @@ mcview_moveto_bottom (mcview_t * view)
|
||||
const off_t datalines = view->data_area.height;
|
||||
|
||||
view->dpy_start = filesize;
|
||||
view->dpy_paragraph_skip_lines = 0;
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
mcview_move_up (view, datalines);
|
||||
}
|
||||
}
|
||||
@ -338,12 +271,12 @@ mcview_moveto_bol (mcview_t * view)
|
||||
if (view->hex_mode)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
@ -370,43 +303,7 @@ mcview_moveto_eol (mcview_t * view)
|
||||
}
|
||||
else
|
||||
{
|
||||
off_t eol;
|
||||
|
||||
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_ascii_moveto_eol (view);
|
||||
}
|
||||
mcview_movement_fixups (view, FALSE);
|
||||
}
|
||||
@ -420,10 +317,14 @@ mcview_moveto_offset (mcview_t * view, off_t offset)
|
||||
{
|
||||
view->hex_cursor = offset;
|
||||
view->dpy_start = offset - offset % view->bytes_per_line;
|
||||
view->dpy_paragraph_skip_lines = 0;
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
view->dpy_start = offset;
|
||||
view->dpy_paragraph_skip_lines = 0;
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
}
|
||||
mcview_movement_fixups (view, TRUE);
|
||||
}
|
||||
@ -494,9 +395,15 @@ mcview_moveto_match (mcview_t * view)
|
||||
view->hexedit_lownibble = FALSE;
|
||||
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_paragraph_skip_lines = 0;
|
||||
view->dpy_wrap_dirty = TRUE;
|
||||
}
|
||||
else
|
||||
{
|
||||
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);
|
||||
view->dirty++;
|
||||
|
@ -1,6 +1,6 @@
|
||||
/*
|
||||
Internal file viewer for the Midnight Commander
|
||||
Function for nroff-like view
|
||||
Functions for searching in nroff-like view
|
||||
|
||||
Copyright (C) 1994-2014
|
||||
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 ****************************************************************************/
|
||||
/* --------------------------------------------------------------------------------------------- */
|
||||
|
||||
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
|
||||
mcview__get_nroff_real_len (mcview_t * view, off_t start, off_t length)
|
||||
{
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------------------- */
|
BIN
tests/src/viewer/viewertest.txt
Normal file
BIN
tests/src/viewer/viewertest.txt
Normal file
Binary file not shown.
Loading…
Reference in New Issue
Block a user