Пример #1
0
static gboolean
mcview_isprint (const WView * view, int c)
{
#ifdef HAVE_CHARSET
    if (!view->utf8)
        c = convert_from_8bit_to_utf_c ((unsigned char) c, view->converter);
    return g_unichar_isprint (c);
#else
    (void) view;
    /* TODO this is very-very buggy by design: ticket 3257 comments 0-1 */
    return is_printable (c);
#endif /* HAVE_CHARSET */
}
Пример #2
0
static int
mcview_char_display (const WView * view, int c, char *s)
{
#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 = '.';
        return g_unichar_to_utf8 (c, s);
    }
    if (view->utf8)
    {
        if (g_unichar_iswide (c))
        {
            s[0] = s[1] = '.';
            return 2;
        }
        if (g_unichar_iszerowidth (c))
            return 0;
        /* TODO the is_printable check below will be broken for this */
        c = convert_from_utf_to_current_c (c, view->converter);
    }
    else
    {
        /* TODO the is_printable check below will be broken for this */
        c = convert_to_display_c (c);
    }
#else
    (void) view;
#endif /* HAVE_CHARSET */
    /* TODO this is very-very buggy by design: ticket 3257 comments 0-1 */
    if (!is_printable (c))
        c = '.';
    *s = c;
    return 1;
}
Пример #3
0
static void
edit_draw_this_line (WEdit * edit, long b, long row, long start_col, long end_col)
{
    struct line_s line[MAX_LINE_LEN];
    struct line_s *p = line;

    long m1 = 0, m2 = 0, q, c1, c2;
    int col, start_col_real;
    unsigned int c;
    int color;
    int abn_style;
    int i;
    int utf8lag = 0;
    unsigned int cur_line = 0;
    int book_mark = 0;
    char line_stat[LINE_STATE_WIDTH + 1] = "\0";

    if (row > edit->widget.lines - 1 - EDIT_TEXT_VERTICAL_OFFSET)
        return;

    if (book_mark_query_color (edit, edit->start_line + row, BOOK_MARK_COLOR))
        book_mark = BOOK_MARK_COLOR;
    else if (book_mark_query_color (edit, edit->start_line + row, BOOK_MARK_FOUND_COLOR))
        book_mark = BOOK_MARK_FOUND_COLOR;

    if (book_mark)
        abn_style = book_mark << 16;
    else
        abn_style = MOD_ABNORMAL;

    end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + option_line_state_width;

    edit_get_syntax_color (edit, b - 1, &color);
    q = edit_move_forward3 (edit, b, start_col - edit->start_col, 0);
    start_col_real = (col = (int) edit_move_forward3 (edit, b, 0, q)) + edit->start_col;
    if (option_line_state)
    {
        cur_line = edit->start_line + row;
        if (cur_line <= (unsigned int) edit->total_lines)
        {
            g_snprintf (line_stat, LINE_STATE_WIDTH + 1, "%7i ", cur_line + 1);
        }
        else
        {
            memset (line_stat, ' ', LINE_STATE_WIDTH);
            line_stat[LINE_STATE_WIDTH] = '\0';
        }
        if (book_mark_query_color (edit, cur_line, BOOK_MARK_COLOR))
        {
            g_snprintf (line_stat, 2, "*");
        }
    }

    if (col + 16 > -edit->start_col)
    {
        eval_marks (edit, &m1, &m2);

        if (row <= edit->total_lines - edit->start_line)
        {
            long tws = 0;
            if (tty_use_colors () && visible_tws)
            {
                tws = edit_eol (edit, b);
                while (tws > b && ((c = edit_get_byte (edit, tws - 1)) == ' ' || c == '\t'))
                    tws--;
            }

            while (col <= end_col - edit->start_col)
            {
                int cw = 1;

                p->ch = 0;
                p->style = 0;
                if (q == edit->curs1)
                    p->style |= MOD_CURSOR;
                if (q >= m1 && q < m2)
                {
                    if (edit->column_highlight)
                    {
                        int x;
                        x = edit_move_forward3 (edit, b, 0, q);
                        c1 = min (edit->column1, edit->column2);
                        c2 = max (edit->column1, edit->column2);
                        if (x >= c1 && x < c2)
                            p->style |= MOD_MARKED;
                    }
                    else
                        p->style |= MOD_MARKED;
                }
                if (q == edit->bracket)
                    p->style |= MOD_BOLD;
                if (q >= edit->found_start && q < edit->found_start + edit->found_len)
                    p->style |= MOD_BOLD;

                if (!edit->utf8)
                {
                    c = edit_get_byte (edit, q);
                }
                else
                {
                    c = edit_get_utf (edit, q, &cw);
                }
                /* we don't use bg for mc - fg contains both */
                if (book_mark)
                {
                    p->style |= book_mark << 16;
                }
                else
                {
                    edit_get_syntax_color (edit, q, &color);
                    p->style |= color << 16;
                }
                switch (c)
                {
                case '\n':
                    col = (end_col + utf8lag) - edit->start_col + 1;    /* quit */
                    break;
                case '\t':
                    i = TAB_SIZE - ((int) col % TAB_SIZE);
                    col += i;
                    if (tty_use_colors () &&
                        ((visible_tabs || (visible_tws && q >= tws)) && enable_show_tabs_tws))
                    {
                        if (p->style & MOD_MARKED)
                            c = p->style;
                        else if (book_mark)
                            c |= book_mark << 16;
                        else
                            c = p->style | MOD_WHITESPACE;
                        if (i > 2)
                        {
                            p->ch = '<';
                            p->style = c;
                            p++;
                            while (--i > 1)
                            {
                                p->ch = '-';
                                p->style = c;
                                p++;
                            }
                            p->ch = '>';
                            p->style = c;
                            p++;
                        }
                        else if (i > 1)
                        {
                            p->ch = '<';
                            p->style = c;
                            p++;
                            p->ch = '>';
                            p->style = c;
                            p++;
                        }
                        else
                        {
                            p->ch = '>';
                            p->style = c;
                            p++;
                        }
                    }
                    else if (tty_use_colors () && visible_tws && q >= tws && enable_show_tabs_tws)
                    {
                        p->ch = '.';
                        p->style |= MOD_WHITESPACE;
                        c = p->style & ~MOD_CURSOR;
                        p++;
                        while (--i)
                        {
                            p->ch = ' ';
                            p->style = c;
                            p++;
                        }
                    }
                    else
                    {
                        p->ch |= ' ';
                        c = p->style & ~MOD_CURSOR;
                        p++;
                        while (--i)
                        {
                            p->ch = ' ';
                            p->style = c;
                            p++;
                        }
                    }
                    break;
                case ' ':
                    if (tty_use_colors () && visible_tws && q >= tws && enable_show_tabs_tws)
                    {
                        p->ch = '.';
                        p->style |= MOD_WHITESPACE;
                        p++;
                        col++;
                        break;
                    }
                    /* fallthrough */
                default:
#ifdef HAVE_CHARSET
                    if (mc_global.utf8_display)
                    {
                        if (!edit->utf8)
                        {
                            c = convert_from_8bit_to_utf_c ((unsigned char) c, edit->converter);
                        }
                    }
                    else if (edit->utf8)
                        c = convert_from_utf_to_current_c (c, edit->converter);
                    else
#endif
                        c = convert_to_display_c (c);

                    /* Caret notation for control characters */
                    if (c < 32)
                    {
                        p->ch = '^';
                        p->style = abn_style;
                        p++;
                        p->ch = c + 0x40;
                        p->style = abn_style;
                        p++;
                        col += 2;
                        break;
                    }
                    if (c == 127)
                    {
                        p->ch = '^';
                        p->style = abn_style;
                        p++;
                        p->ch = '?';
                        p->style = abn_style;
                        p++;
                        col += 2;
                        break;
                    }
                    if (!edit->utf8)
                    {
                        if ((mc_global.utf8_display && g_unichar_isprint (c)) ||
                            (!mc_global.utf8_display && is_printable (c)))
                        {
                            p->ch = c;
                            p++;
                        }
                        else
                        {
                            p->ch = '.';
                            p->style = abn_style;
                            p++;
                        }
                    }
                    else
                    {
                        if (g_unichar_isprint (c))
                        {
                            p->ch = c;
                            p++;
                        }
                        else
                        {
                            p->ch = '.';
                            p->style = abn_style;
                            p++;
                        }
                    }
                    col++;
                    break;
                }               /* case */

                q++;
                if (cw > 1)
                {
                    q += cw - 1;
                }
            }
        }
    }
    else
    {
        start_col_real = start_col = 0;
    }

    p->ch = '\0';

    print_to_widget (edit, row, start_col, start_col_real, end_col, line, line_stat, book_mark);
}
Пример #4
0
void
mcview_display_hex (mcview_t * view)
{
    const screen_dimen top = view->data_area.top;
    const screen_dimen left = view->data_area.left;
    const screen_dimen height = view->data_area.height;
    const screen_dimen width = view->data_area.width;
    const int ngroups = view->bytes_per_line / 4;
    const screen_dimen text_start = 8 + 13 * ngroups + ((width < 80) ? 0 : (ngroups - 1 + 1));
    /* 8 characters are used for the file offset, and every hex group
     * takes 13 characters. On "big" screens, the groups are separated
     * by an extra vertical line, and there is an extra space before the
     * text column.
     */

    screen_dimen row;
    off_t from;
    int c;
    mark_t boldflag = MARK_NORMAL;
    struct hexedit_change_node *curr = view->change_list;
#ifdef HAVE_CHARSET
    int ch = 0;
#endif /* HAVE_CHARSET */

    char hex_buff[10];          /* A temporary buffer for sprintf and mvwaddstr */
    int bytes;                  /* Number of bytes already printed on the line */

    mcview_display_clean (view);

    /* Find the first displayable changed byte */
    from = view->dpy_start;
    while (curr && (curr->offset < from))
    {
        curr = curr->next;
    }

    for (row = 0; mcview_get_byte (view, from, NULL) == TRUE && row < height; row++)
    {
        screen_dimen col = 0;
        size_t i;

        col = 0;

        /* Print the hex offset */
        g_snprintf (hex_buff, sizeof (hex_buff), "%08" PRIXMAX " ", (uintmax_t) from);
        widget_move (view, top + row, left);
        tty_setcolor (VIEW_BOLD_COLOR);
        for (i = 0; col < width && hex_buff[i] != '\0'; i++)
        {
            tty_print_char (hex_buff[i]);
            /*              tty_print_char(hex_buff[i]); */
            col += 1;
        }
        tty_setcolor (VIEW_NORMAL_COLOR);

        for (bytes = 0; bytes < view->bytes_per_line; bytes++, from++)
        {

#ifdef HAVE_CHARSET
            if (view->utf8)
            {
                int cw = 1;
                gboolean read_res = TRUE;

                ch = mcview_get_utf (view, from, &cw, &read_res);
                if (!read_res)
                    break;
                /* char width is greater 0 bytes */
                if (cw != 0)
                {
                    int cnt;
                    char corr_buf[UTF8_CHAR_LEN + 1];
                    struct hexedit_change_node *corr = curr;
                    int res;

                    res = g_unichar_to_utf8 (ch, (char *) corr_buf);

                    for (cnt = 0; cnt < cw; cnt++)
                    {
                        if (curr != NULL && from + cnt == curr->offset)
                        {
                            /* replace only changed bytes in array of multibyte char */
                            corr_buf[cnt] = curr->value;
                            curr = curr->next;
                        }
                    }
                    corr_buf[res] = '\0';
                    /* Determine the state of the current multibyte char */
                    ch = utf8_to_int ((char *) corr_buf, &cw, &read_res);
                    curr = corr;
                }
            }
#endif /* HAVE_CHARSET */
            if (!mcview_get_byte (view, from, &c))
                break;

            /* Save the cursor position for mcview_place_cursor() */
            if (from == view->hex_cursor && !view->hexview_in_text)
            {
                view->cursor_row = row;
                view->cursor_col = col;
            }

            /* Determine the state of the current byte */
            boldflag = mcview_hex_calculate_boldflag (view, from, curr);

            /* Determine the value of the current byte */
            if (curr != NULL && from == curr->offset)
            {
                c = curr->value;
                curr = curr->next;
            }

            /* Select the color for the hex number */
            tty_setcolor (boldflag == MARK_NORMAL ? VIEW_NORMAL_COLOR :
                          boldflag == MARK_SELECTED ? VIEW_BOLD_COLOR :
                          boldflag == MARK_CHANGED ? VIEW_UNDERLINED_COLOR :
                          /* boldflag == MARK_CURSOR */
                          view->hexview_in_text ? VIEW_SELECTED_COLOR : VIEW_UNDERLINED_COLOR);

            /* Print the hex number */
            widget_move (view, top + row, left + col);
            if (col < width)
            {
                tty_print_char (hex_char[c / 16]);
                col += 1;
            }
            if (col < width)
            {
                tty_print_char (hex_char[c % 16]);
                col += 1;
            }

            /* Print the separator */
            tty_setcolor (VIEW_NORMAL_COLOR);
            if (bytes != view->bytes_per_line - 1)
            {
                if (col < width)
                {
                    tty_print_char (' ');
                    col += 1;
                }

                /* After every four bytes, print a group separator */
                if (bytes % 4 == 3)
                {
                    if (view->data_area.width >= 80 && col < width)
                    {
                        tty_print_one_vline (TRUE);
                        col += 1;
                    }
                    if (col < width)
                    {
                        tty_print_char (' ');
                        col += 1;
                    }
                }
            }

            /* Select the color for the character; this differs from the
             * hex color when boldflag == MARK_CURSOR */
            tty_setcolor (boldflag == MARK_NORMAL ? VIEW_NORMAL_COLOR :
                          boldflag == MARK_SELECTED ? VIEW_BOLD_COLOR :
                          boldflag == MARK_CHANGED ? VIEW_UNDERLINED_COLOR :
                          /* boldflag == MARK_CURSOR */
                          view->hexview_in_text ? VIEW_SELECTED_COLOR : MARKED_SELECTED_COLOR);


#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)
                ch = convert_from_utf_to_current_c (ch, view->converter);
            else
#endif
            {
#ifdef HAVE_CHARSET
                c = convert_to_display_c (c);
#endif

                if (!is_printable (c))
                    c = '.';
            }

            /* Print corresponding character on the text side */
            if (text_start + bytes < width)
            {
                widget_move (view, top + row, left + text_start + bytes);
#ifdef HAVE_CHARSET
                if (view->utf8)
                    tty_print_anychar (ch);
                else
#endif
                    tty_print_char (c);
            }

            /* Save the cursor position for mcview_place_cursor() */
            if (from == view->hex_cursor && view->hexview_in_text)
            {
                view->cursor_row = row;
                view->cursor_col = text_start + bytes;
            }
        }
    }

    /* Be polite to the other functions */
    tty_setcolor (VIEW_NORMAL_COLOR);

    mcview_place_cursor (view);
    view->dpy_end = from;
}
Пример #5
0
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;
    struct hexedit_change_node *curr = view->change_list;

    mcview_display_clean (view);
    mcview_display_ruler (view);

    /* Find the first displayable changed byte */
    from = view->dpy_start;
    while (curr && (curr->offset < from))
    {
        curr = curr->next;
    }

    tty_setcolor (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 (NORMAL_COLOR);
    }
    view->dpy_end = from;
}
Пример #6
0
Файл: plain.c Проект: BrEacK/mc
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;
    struct hexedit_change_node *curr = view->change_list;

    mcview_display_clean (view);
    mcview_display_ruler (view);

    /* Find the first displayable changed byte */
    from = view->dpy_start;
    while ((curr != NULL) && (curr->offset < from))
        curr = curr->next;

    while (TRUE)
    {
        tty_setcolor (NORMAL_COLOR);

        if (row >= height)
            break;

#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);

        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
#endif
            {
#ifdef HAVE_CHARSET
                c = convert_to_display_c (c);
#endif
                if (!is_printable (c))
                    c = '.';
            }

            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))
            if (c != '\n')
                row--;
        while (++row < height)
        {
            widget_move (view, top + row, left);
            tty_print_string (mcview_show_eof);
        }
    }
}
Пример #7
0
static void
edit_draw_this_line (WEdit * edit, off_t b, long row, long start_col, long end_col)
{
    Widget *w = WIDGET (edit);

    struct line_s line[MAX_LINE_LEN];
    struct line_s *p = line;

    off_t m1 = 0, m2 = 0, q;
    int col, start_col_real;
    int color;
    int abn_style;
    int book_mark = 0;
    char line_stat[LINE_STATE_WIDTH + 1] = "\0";

    if (row > w->lines - 1 - EDIT_TEXT_VERTICAL_OFFSET - 2 * (edit->fullscreen ? 0 : 1))
        return;

    if (book_mark_query_color (edit, edit->start_line + row, BOOK_MARK_COLOR))
        book_mark = BOOK_MARK_COLOR;
    else if (book_mark_query_color (edit, edit->start_line + row, BOOK_MARK_FOUND_COLOR))
        book_mark = BOOK_MARK_FOUND_COLOR;

    if (book_mark)
        abn_style = book_mark << 16;
    else
        abn_style = MOD_ABNORMAL;

    end_col -= EDIT_TEXT_HORIZONTAL_OFFSET + option_line_state_width;
    if (!edit->fullscreen)
    {
        end_col--;
        if (w->x + w->cols <= WIDGET (w->owner)->cols)
            end_col--;
    }

    color = edit_get_syntax_color (edit, b - 1);
    q = edit_move_forward3 (edit, b, start_col - edit->start_col, 0);
    start_col_real = (col = (int) edit_move_forward3 (edit, b, 0, q)) + edit->start_col;

    if (option_line_state)
    {
        unsigned int cur_line;

        cur_line = edit->start_line + row;
        if (cur_line <= (unsigned int) edit->buffer.lines)
        {
            g_snprintf (line_stat, LINE_STATE_WIDTH + 1, "%7i ", cur_line + 1);
        }
        else
        {
            memset (line_stat, ' ', LINE_STATE_WIDTH);
            line_stat[LINE_STATE_WIDTH] = '\0';
        }
        if (book_mark_query_color (edit, cur_line, BOOK_MARK_COLOR))
        {
            g_snprintf (line_stat, 2, "*");
        }
    }

    if (col + 16 > -edit->start_col)
    {
        eval_marks (edit, &m1, &m2);

        if (row <= edit->buffer.lines - edit->start_line)
        {
            off_t tws = 0;
            if (tty_use_colors () && visible_tws)
            {
                unsigned int c;

                tws = edit_buffer_get_eol (&edit->buffer, b);
                while (tws > b
                       && ((c = edit_buffer_get_byte (&edit->buffer, tws - 1)) == ' ' || c == '\t'))
                    tws--;
            }

            while (col <= end_col - edit->start_col)
            {
                int char_length = 1;
                unsigned int c;
                gboolean wide_width_char = FALSE;
                gboolean control_char = FALSE;

                p->ch = 0;
                p->style = 0;
                if (q == edit->buffer.curs1)
                    p->style |= MOD_CURSOR;
                if (q >= m1 && q < m2)
                {
                    if (edit->column_highlight)
                    {
                        long x;
                        long c1, c2;

                        x = (long) edit_move_forward3 (edit, b, 0, q);
                        c1 = min (edit->column1, edit->column2);
                        c2 = max (edit->column1, edit->column2);
                        if (x >= c1 && x < c2)
                            p->style |= MOD_MARKED;
                    }
                    else
                        p->style |= MOD_MARKED;
                }
                if (q == edit->bracket)
                    p->style |= MOD_BOLD;
                if (q >= edit->found_start && q < (off_t) (edit->found_start + edit->found_len))
                    p->style |= MOD_BOLD;

#ifdef HAVE_CHARSET
                if (edit->utf8)
                    c = edit_buffer_get_utf (&edit->buffer, q, &char_length);
                else
#endif
                    c = edit_buffer_get_byte (&edit->buffer, q);

                /* we don't use bg for mc - fg contains both */
                if (book_mark)
                {
                    p->style |= book_mark << 16;
                }
                else
                {
                    color = edit_get_syntax_color (edit, q);
                    p->style |= color << 16;
                }
                switch (c)
                {
                case '\n':
                    col = end_col - edit->start_col + 1;        /* quit */
                    break;
                case '\t':
                    {
                        int tab_over;
                        int i;

                        i = TAB_SIZE - ((int) col % TAB_SIZE);
                        tab_over = (end_col - edit->start_col) - (col + i - 1);
                        if (tab_over < 0)
                            i += tab_over;
                        col += i;
                        if (tty_use_colors () &&
                            ((visible_tabs || (visible_tws && q >= tws)) && enable_show_tabs_tws))
                        {
                            if (p->style & MOD_MARKED)
                                c = p->style;
                            else if (book_mark)
                                c |= book_mark << 16;
                            else
                                c = p->style | MOD_WHITESPACE;
                            if (i > 2)
                            {
                                p->ch = '<';
                                p->style = c;
                                p++;
                                while (--i > 1)
                                {
                                    p->ch = '-';
                                    p->style = c;
                                    p++;
                                }
                                p->ch = '>';
                                p->style = c;
                                p++;
                            }
                            else if (i > 1)
                            {
                                p->ch = '<';
                                p->style = c;
                                p++;
                                p->ch = '>';
                                p->style = c;
                                p++;
                            }
                            else
                            {
                                p->ch = '>';
                                p->style = c;
                                p++;
                            }
                        }
                        else if (tty_use_colors () && visible_tws && q >= tws
                                 && enable_show_tabs_tws)
                        {
                            p->ch = '.';
                            p->style |= MOD_WHITESPACE;
                            c = p->style & ~MOD_CURSOR;
                            p++;
                            while (--i)
                            {
                                p->ch = ' ';
                                p->style = c;
                                p++;
                            }
                        }
                        else
                        {
                            p->ch |= ' ';
                            c = p->style & ~MOD_CURSOR;
                            p++;
                            while (--i)
                            {
                                p->ch = ' ';
                                p->style = c;
                                p++;
                            }
                        }
                    }
                    break;
                case ' ':
                    if (tty_use_colors () && visible_tws && q >= tws && enable_show_tabs_tws)
                    {
                        p->ch = '.';
                        p->style |= MOD_WHITESPACE;
                        p++;
                        col++;
                        break;
                    }
                    /* fallthrough */
                default:
#ifdef HAVE_CHARSET
                    if (mc_global.utf8_display)
                    {
                        if (!edit->utf8)
                        {
                            c = convert_from_8bit_to_utf_c ((unsigned char) c, edit->converter);
                        }
                        else
                        {
                            if (g_unichar_iswide (c))
                            {
                                wide_width_char = TRUE;
                                col++;
                            }
                        }
                    }
                    else if (edit->utf8)
                        c = convert_from_utf_to_current_c (c, edit->converter);
                    else
                        c = convert_to_display_c (c);
#endif

                    /* Caret notation for control characters */
                    if (c < 32)
                    {
                        p->ch = '^';
                        p->style = abn_style;
                        p++;
                        p->ch = c + 0x40;
                        p->style = abn_style;
                        p++;
                        col += 2;
                        control_char = TRUE;
                        break;
                    }
                    if (c == 127)
                    {
                        p->ch = '^';
                        p->style = abn_style;
                        p++;
                        p->ch = '?';
                        p->style = abn_style;
                        p++;
                        col += 2;
                        control_char = TRUE;
                        break;
                    }
#ifdef HAVE_CHARSET
                    if (edit->utf8)
                    {
                        if (g_unichar_isprint (c))
                            p->ch = c;
                        else
                        {
                            p->ch = '.';
                            p->style = abn_style;
                        }
                        p++;
                    }
                    else
#endif
                    {
                        if ((mc_global.utf8_display && g_unichar_isprint (c)) ||
                            (!mc_global.utf8_display && is_printable (c)))
                        {
                            p->ch = c;
                            p++;
                        }
                        else
                        {
                            p->ch = '.';
                            p->style = abn_style;
                            p++;
                        }
                    }
                    col++;
                    break;
                }               /* case */

                q++;
                if (char_length > 1)
                    q += char_length - 1;

                if (col > (end_col - edit->start_col + 1))
                {
                    if (wide_width_char)
                    {
                        p--;
                        break;
                    }
                    if (control_char)
                    {
                        p -= 2;
                        break;
                    }
                }
            }
        }
    }
    else
    {
        start_col_real = start_col = 0;
    }

    p->ch = 0;

    print_to_widget (edit, row, start_col, start_col_real, end_col, line, line_stat, book_mark);
}
Пример #8
0
void
mcview_display_hex (WView * view)
{
    const screen_dimen top = view->data_area.top;
    const screen_dimen left = view->data_area.left;
    const screen_dimen height = view->data_area.height;
    const screen_dimen width = view->data_area.width;
    const int ngroups = view->bytes_per_line / 4;
    /* 8 characters are used for the file offset, and every hex group
     * takes 13 characters. Starting at width of 80 columns, the groups
     * are separated by an extra vertical line. Starting at width of 81,
     * there is an extra space before the text column. There is always a
     * mostly empty column on the right, to allow overflowing CJKs.
     */
    const screen_dimen text_start = 8 + 13 * ngroups +
        ((width < 80) ? 0 : (width == 80) ? (ngroups - 1) : (ngroups - 1 + 1));

    int row;
    off_t from;
    mark_t boldflag_byte = MARK_NORMAL;
    mark_t boldflag_char = MARK_NORMAL;
    struct hexedit_change_node *curr = view->change_list;
#ifdef HAVE_CHARSET
    int cont_bytes = 0;         /* number of continuation bytes remanining from current UTF-8 */
    gboolean cjk_right = FALSE; /* whether the second byte of a CJK is to be processed */
#endif /* HAVE_CHARSET */
    gboolean utf8_changed = FALSE;      /* whether any of the bytes in the UTF-8 were changed */

    char hex_buff[10];          /* A temporary buffer for sprintf and mvwaddstr */

    mcview_display_clean (view);

    /* Find the first displayable changed byte */
    /* In UTF-8 mode, go back by 1 or maybe 2 lines to handle continuation bytes properly. */
    from = view->dpy_start;
    row = 0;
#ifdef HAVE_CHARSET
    if (view->utf8)
    {
        if (from >= view->bytes_per_line)
        {
            row--;
            from -= view->bytes_per_line;
        }
        if (view->bytes_per_line == 4 && from >= view->bytes_per_line)
        {
            row--;
            from -= view->bytes_per_line;
        }
    }
#endif /* HAVE_CHARSET */
    while (curr && (curr->offset < from))
    {
        curr = curr->next;
    }

    for (; mcview_get_byte (view, from, NULL) && row < (int) height; row++)
    {
        screen_dimen col = 0;
        size_t i;
        int bytes;              /* Number of bytes already printed on the line */

        /* Print the hex offset */
        if (row >= 0)
        {
            g_snprintf (hex_buff, sizeof (hex_buff), "%08" PRIXMAX " ", (uintmax_t) from);
            widget_move (view, top + row, left);
            tty_setcolor (VIEW_BOLD_COLOR);
            for (i = 0; col < width && hex_buff[i] != '\0'; col++, i++)
                tty_print_char (hex_buff[i]);
            tty_setcolor (VIEW_NORMAL_COLOR);
        }

        for (bytes = 0; bytes < view->bytes_per_line; bytes++, from++)
        {
            int c;
#ifdef HAVE_CHARSET
            int ch = 0;

            if (view->utf8)
            {
                struct hexedit_change_node *corr = curr;

                if (cont_bytes != 0)
                {
                    /* UTF-8 continuation bytes, print a space (with proper attributes)... */
                    cont_bytes--;
                    ch = ' ';
                    if (cjk_right)
                    {
                        /* ... except when it'd wipe out the right half of a CJK, then print nothing */
                        cjk_right = FALSE;
                        ch = -1;
                    }
                }
                else
                {
                    int j;
                    gchar utf8buf[UTF8_CHAR_LEN + 1];
                    int res;
                    int first_changed = -1;

                    for (j = 0; j < UTF8_CHAR_LEN; j++)
                    {
                        if (mcview_get_byte (view, from + j, &res))
                            utf8buf[j] = res;
                        else
                        {
                            utf8buf[j] = '\0';
                            break;
                        }
                        if (curr != NULL && from + j == curr->offset)
                        {
                            utf8buf[j] = curr->value;
                            if (first_changed == -1)
                                first_changed = j;
                        }
                        if (curr != NULL && from + j >= curr->offset)
                            curr = curr->next;
                    }
                    utf8buf[UTF8_CHAR_LEN] = '\0';

                    /* Determine the state of the current multibyte char */
                    ch = g_utf8_get_char_validated (utf8buf, -1);
                    if (ch == -1 || ch == -2)
                    {
                        ch = '.';
                    }
                    else
                    {
                        gchar *next_ch;

                        next_ch = g_utf8_next_char (utf8buf);
                        cont_bytes = next_ch - utf8buf - 1;
                        if (g_unichar_iswide (ch))
                            cjk_right = TRUE;
                    }

                    utf8_changed = (first_changed >= 0 && first_changed <= cont_bytes);
                    curr = corr;
                }
            }
#endif /* HAVE_CHARSET */

            /* For negative rows, the only thing we care about is overflowing
             * UTF-8 continuation bytes which were handled above. */
            if (row < 0)
            {
                if (curr != NULL && from == curr->offset)
                    curr = curr->next;
                continue;
            }

            if (!mcview_get_byte (view, from, &c))
                break;

            /* Save the cursor position for mcview_place_cursor() */
            if (from == view->hex_cursor && !view->hexview_in_text)
            {
                view->cursor_row = row;
                view->cursor_col = col;
            }

            /* Determine the state of the current byte */
            boldflag_byte = mcview_hex_calculate_boldflag (view, from, curr, FALSE);
            boldflag_char = mcview_hex_calculate_boldflag (view, from, curr, utf8_changed);

            /* Determine the value of the current byte */
            if (curr != NULL && from == curr->offset)
            {
                c = curr->value;
                curr = curr->next;
            }

            /* Select the color for the hex number */
            tty_setcolor (boldflag_byte == MARK_NORMAL ? VIEW_NORMAL_COLOR :
                          boldflag_byte == MARK_SELECTED ? VIEW_BOLD_COLOR :
                          boldflag_byte == MARK_CHANGED ? VIEW_UNDERLINED_COLOR :
                          /* boldflag_byte == MARK_CURSOR */
                          view->hexview_in_text ? VIEW_SELECTED_COLOR : VIEW_UNDERLINED_COLOR);

            /* Print the hex number */
            widget_move (view, top + row, left + col);
            if (col < width)
            {
                tty_print_char (hex_char[c / 16]);
                col += 1;
            }
            if (col < width)
            {
                tty_print_char (hex_char[c % 16]);
                col += 1;
            }

            /* Print the separator */
            tty_setcolor (VIEW_NORMAL_COLOR);
            if (bytes != view->bytes_per_line - 1)
            {
                if (col < width)
                {
                    tty_print_char (' ');
                    col += 1;
                }

                /* After every four bytes, print a group separator */
                if (bytes % 4 == 3)
                {
                    if (view->data_area.width >= 80 && col < width)
                    {
                        tty_print_one_vline (TRUE);
                        col += 1;
                    }
                    if (col < width)
                    {
                        tty_print_char (' ');
                        col += 1;
                    }
                }
            }

            /* Select the color for the character; this differs from the
             * hex color when boldflag == MARK_CURSOR */
            tty_setcolor (boldflag_char == MARK_NORMAL ? VIEW_NORMAL_COLOR :
                          boldflag_char == MARK_SELECTED ? VIEW_BOLD_COLOR :
                          boldflag_char == MARK_CHANGED ? VIEW_UNDERLINED_COLOR :
                          /* boldflag_char == MARK_CURSOR */
                          view->hexview_in_text ? VIEW_SELECTED_COLOR : MARKED_SELECTED_COLOR);


#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)
                ch = convert_from_utf_to_current_c (ch, view->converter);
            else
#endif
            {
#ifdef HAVE_CHARSET
                c = convert_to_display_c (c);
#endif

                if (!is_printable (c))
                    c = '.';
            }

            /* Print corresponding character on the text side */
            if (text_start + bytes < width)
            {
                widget_move (view, top + row, left + text_start + bytes);
#ifdef HAVE_CHARSET
                if (view->utf8)
                    tty_print_anychar (ch);
                else
#endif
                    tty_print_char (c);
            }

            /* Save the cursor position for mcview_place_cursor() */
            if (from == view->hex_cursor && view->hexview_in_text)
            {
                view->cursor_row = row;
                view->cursor_col = text_start + bytes;
            }
        }
    }

    /* Be polite to the other functions */
    tty_setcolor (VIEW_NORMAL_COLOR);

    mcview_place_cursor (view);
    view->dpy_end = from;
}