📄 editdraw.c
字号:
/* editor text drawing. Copyright (C) 1996-2000 the Free Software Foundation Authors: 1996, 1997 Paul Sheer This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program 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, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.*/#include <config.h>#include "edit.h"#define MAX_LINE_LEN 1024#if ! defined (MIDNIGHT) && ! defined (GTK)#include "app_glob.c"#include "coollocal.h"#include "mad.h"#endifextern int column_highlighting;extern struct look *look;#if defined (MIDNIGHT) || defined (GTK)void status_string (WEdit * edit, char *s, int w, int fill, int font_width){#ifdef MIDNIGHT int i;#endif char t[160]; /* 160 just to be sure *//* The field lengths just prevents the status line from shortening to much */ sprintf (t, "[%c%c%c%c] %2ld:%3ld+%2ld=%3ld/%3ld - *%-4ld/%4ldb=%3d", edit->mark1 != edit->mark2 ? ( column_highlighting ? 'C' : 'B') : '-', edit->modified ? 'M' : '-', edit->macro_i < 0 ? '-' : 'R', edit->overwrite == 0 ? '-' : 'O', edit->curs_col / font_width, edit->start_line + 1, edit->curs_row, edit->curs_line + 1, edit->total_lines + 1, edit->curs1, edit->last_byte, edit->curs1 < edit->last_byte ? edit_get_byte (edit, edit->curs1) : -1);#ifdef MIDNIGHT sprintf (s, "%.*s", w + 1, t); i = strlen (s); s[i] = ' '; i = w; do { if (strchr ("+-*=/:b", s[i])) /* chop off the last word/number */ break; s[i] = fill; } while (i--); s[i] = fill; s[w] = 0;#else strcpy (s, t);#endif}#endif#ifdef MIDNIGHT/* how to get as much onto the status line as is numerically possible :) */void edit_status (WEdit * edit){ int w, i, t; char *s; w = edit->widget.cols - (edit->have_frame * 2); s = malloc (w + 15); if (w < 4) w = 4; memset (s, ' ', w); attrset (SELECTED_COLOR); if (w > 4) { widget_move (edit, edit->have_frame, edit->have_frame); i = w > 24 ? 18 : w - 6; i = i < 13 ? 13 : i; sprintf (s, "%s", (char *) name_trunc (edit->filename ? edit->filename : "", i)); i += strlen (s); s[strlen (s)] = ' '; t = w - 20; if (t < 0) t = 0; status_string (edit, s + 20, t, ' ', 1); } else { s[w] = 0; } printw ("%.*s", w, s); attrset (NORMAL_COLOR); free (s);}#elsevoid render_status (CWidget * wdt, int expose);#ifdef GTKvoid edit_status (WEdit *edit){ GtkEntry *entry; int w, i, t; char s[160]; w = edit->num_widget_columns - 1; if (w > 150) w = 150; if (w < 0) w = 0; memset (s, 0, w); if (w > 1) { i = w > 24 ? 18 : w - 6; i = i < 13 ? 13 : i; sprintf (s, "%s", (char *) name_trunc (edit->filename ? edit->filename : "", i)); i = strlen (s); s[i] = ' '; s[i + 1] = ' '; t = w - i - 2; if (t < 0) t = 0; status_string (edit, s + i + 2, t, 0, FONT_MEAN_WIDTH); } s[w] = 0; entry = GTK_ENTRY (edit->widget->status); if (strcmp (s, gtk_entry_get_text (entry))) gtk_entry_set_text (entry, s);}#elsevoid edit_status (WEdit * edit){ static int name_trunc_len = 16; int name_trunc_len_inc = 0; long start_mark, end_mark; CWidget *wdt; mode_t m; char *p; char id[33]; char s[4096]; char b[64]; if (eval_marks (edit, &start_mark, &end_mark)) end_mark = start_mark = 0; if ((COptionsOf (edit->widget) & EDITOR_NO_TEXT)) return; CPushFont ("editor", 0); m = edit->stat.st_mode; p = edit->filename ? edit->filename : ""; if (edit->curs1 < edit->last_byte) { wchar_t c; c = edit_get_wide_byte (edit, edit->curs1) & 0x7FFFFFFFUL; sprintf (b, "%3lu/\011%lX\033", (unsigned long) c, (unsigned long) c); } else { sprintf (b, "\022EOF\033"); } CPushFont ("widget", 0); for (;;) { int status_text_width; sprintf (s, "%s -rwxrwxrwx MMMM %02ld %-4ld+%2ld=%4ld/%3ld *%-5ld/%5ldb=%s%c %ld", *p ? (char *) name_trunc (p, name_trunc_len) : _("<unnamed>"), edit->curs_col / FONT_MEAN_WIDTH, edit->start_line + 1, edit->curs_row, edit->curs_line + 1, edit->total_lines + 1, edit->curs1, edit->last_byte, b, end_mark - start_mark && !column_highlighting ? ' ' : '\0', end_mark - start_mark); status_text_width = CImageTextWidth (s, strlen (s)); if (name_trunc_len_inc >= 0) if (status_text_width < CWidthOf (edit->widget) - 13) { if (name_trunc_len < strlen (p)) { name_trunc_len++; name_trunc_len_inc = 1; continue; } } if (name_trunc_len_inc <= 0) if (status_text_width > CWidthOf (edit->widget) - 13) { if (name_trunc_len > 16) { name_trunc_len--; name_trunc_len_inc = -1; continue; } } if (name_trunc_len_inc > 0) name_trunc_len--; break; } CPopFont (); sprintf (s, "\034%c%s\033\035 \034-%c%c%c%c%c%c%c%c%c\035 \034%s%s%s%c\035 \034\014%02ld\033\035 \034%-4ld+%2ld=\014%4ld\033/%3ld\035 \034*%-5ld/%5ldb=%s\035%c \034\001%ld\033\035", *p ? '\033' : '\003', *p ? (char *) name_trunc (p, name_trunc_len) : _("<unnamed>"), m & S_IRUSR ? 'r' : '-', m & S_IWUSR ? 'w' : '-', m & S_IXUSR ? 'x' : '-', m & S_IRGRP ? 'r' : '-', m & S_IWGRP ? 'w' : '-', m & S_IXGRP ? 'x' : '-', m & S_IROTH ? 'r' : '-', m & S_IWOTH ? 'w' : '-', m & S_IXOTH ? 'x' : '-', end_mark - start_mark || (edit->mark2 == -1 && !edit->highlight) ? (column_highlighting ? "\032C\033" : "\001B\033") : "-", edit->modified ? "\012M\033" : "-", edit->macro_i < 0 ? "-" : "\023R\033", edit->overwrite == 0 ? '-' : 'O', edit->curs_col / FONT_MEAN_WIDTH, edit->start_line + 1, edit->curs_row, edit->curs_line + 1, edit->total_lines + 1, edit->curs1, edit->last_byte, b, end_mark - start_mark && !column_highlighting ? ' ' : '\0', end_mark - start_mark); strcpy (id, CIdentOf (edit->widget)); strcat (id, ".text"); wdt = CIdent (id); free (wdt->text); wdt->text = (char *) strdup (s); CSetWidgetSize (id, CWidthOf (edit->widget), CHeightOf (wdt)); render_status (wdt, 0); CPopFont ();}#endif#endif/* boolean */int cursor_in_screen (WEdit * edit, long row){ if (row < 0 || row >= edit->num_widget_lines) return 0; else return 1;}/* returns rows from the first displayed line to the cursor */int cursor_from_display_top (WEdit * edit){ if (edit->curs1 < edit->start_display) return -edit_move_forward (edit, edit->curs1, 0, edit->start_display); else return edit_move_forward (edit, edit->start_display, 0, edit->curs1);}/* returns how far the cursor is out of the screen */int cursor_out_of_screen (WEdit * edit){ int row = cursor_from_display_top (edit); if (row >= edit->num_widget_lines) return row - edit->num_widget_lines + 1; if (row < 0) return row; return 0;}#ifndef MIDNIGHTint edit_width_of_long_printable (int c);#endif/* this scrolls the text so that cursor is on the screen */void edit_scroll_screen_over_cursor (WEdit * edit){ int p; int outby; int b_extreme, t_extreme, l_extreme, r_extreme; r_extreme = EDIT_RIGHT_EXTREME; l_extreme = EDIT_LEFT_EXTREME; b_extreme = EDIT_BOTTOM_EXTREME; t_extreme = EDIT_TOP_EXTREME; if (edit->found_len) { b_extreme = max (edit->num_widget_lines / 4, b_extreme); t_extreme = max (edit->num_widget_lines / 4, t_extreme); } if (b_extreme + t_extreme + 1 > edit->num_widget_lines) { int n; n = b_extreme + t_extreme; b_extreme = (b_extreme * (edit->num_widget_lines - 1)) / n; t_extreme = (t_extreme * (edit->num_widget_lines - 1)) / n; } if (l_extreme + r_extreme + 1 > edit->num_widget_columns) { int n; n = l_extreme + t_extreme; l_extreme = (l_extreme * (edit->num_widget_columns - 1)) / n; r_extreme = (r_extreme * (edit->num_widget_columns - 1)) / n; } p = edit_get_col (edit); edit_update_curs_row (edit);#ifdef MIDNIGHT outby = p + edit->start_col - edit->num_widget_columns + 1 + (r_extreme + edit->found_len);#else outby = p + edit->start_col - CWidthOf (edit->widget) + 7 + (r_extreme + edit->found_len) * FONT_MEAN_WIDTH + edit_width_of_long_printable (edit_get_byte (edit, edit->curs1));#endif if (outby > 0) edit_scroll_right (edit, outby);#ifdef MIDNIGHT outby = l_extreme - p - edit->start_col;#else outby = l_extreme * FONT_MEAN_WIDTH - p - edit->start_col;#endif if (outby > 0) edit_scroll_left (edit, outby); p = edit->curs_row; outby = p - edit->num_widget_lines + 1 + b_extreme; if (outby > 0) edit_scroll_downward (edit, outby); outby = t_extreme - p; if (outby > 0) edit_scroll_upward (edit, outby); edit_update_curs_row (edit);}#ifndef MIDNIGHT#define CACHE_WIDTH 256#define CACHE_HEIGHT 128int EditExposeRedraw = 0;int EditClear = 0;/* background colors: marked is refers to mouse highlighting, highlighted refers to a found string. */unsigned long edit_abnormal_color, edit_marked_abnormal_color;unsigned long edit_highlighted_color, edit_marked_color;unsigned long edit_normal_background_color;/* foreground colors */unsigned long edit_normal_foreground_color, edit_bold_color;unsigned long edit_italic_color;/* cursor color */unsigned long edit_cursor_color;void edit_set_foreground_colors (unsigned long normal, unsigned long bold, unsigned long italic){ edit_normal_foreground_color = normal; edit_bold_color = bold; edit_italic_color = italic;}void edit_set_background_colors (unsigned long normal, unsigned long abnormal, unsigned long marked, unsigned long marked_abnormal, unsigned long highlighted){ edit_abnormal_color = abnormal; edit_marked_abnormal_color = marked_abnormal; edit_marked_color = marked; edit_highlighted_color = highlighted; edit_normal_background_color = normal;}void edit_set_cursor_color (unsigned long c){ edit_cursor_color = c;}#elsestatic void set_color (int font){ attrset (font);}#define edit_move(x,y) widget_move(edit, y, x);static void print_to_widget (WEdit * edit, long row, int start_col, float start_col_real, long end_col, unsigned int line[]){ int x = (float) start_col_real + EDIT_TEXT_HORIZONTAL_OFFSET; int x1 = start_col + EDIT_TEXT_HORIZONTAL_OFFSET; int y = row + EDIT_TEXT_VERTICAL_OFFSET; set_color (EDITOR_NORMAL_COLOR); edit_move (x1, y); hline (' ', end_col + 1 - EDIT_TEXT_HORIZONTAL_OFFSET - x1); edit_move (x + FONT_OFFSET_X, y + FONT_OFFSET_Y); { unsigned int *p = line; int textchar = ' '; long style; while (*p) { style = *p >> 8; textchar = *p & 0xFF;#ifdef HAVE_SYNTAXH if (!(style & (0xFF - MOD_ABNORMAL - MOD_CURSOR))) SLsmg_set_color ((*p & 0x007F0000) >> 16);#endif if (style & MOD_ABNORMAL) textchar = '.'; if (style & MOD_HIGHLIGHTED) { set_color (EDITOR_BOLD_COLOR); } else if (style & MOD_MARKED) { set_color (EDITOR_MARKED_COLOR); } if (style & MOD_UNDERLINED) { set_color (EDITOR_UNDERLINED_COLOR); } if (style & MOD_BOLD) { set_color (EDITOR_BOLD_COLOR); } addch (textchar); p++; } }}/* b pointer to begining of line */static void edit_draw_this_line (WEdit * edit, long b, long row, long start_col, long end_col){ static unsigned int line[MAX_LINE_LEN]; unsigned int *p = line; long m1 = 0, m2 = 0, q, c1, c2; int col, start_col_real; unsigned int c; int fg, bg; int i, book_mark = -1;#if 0 if (!book_mark_query (edit, edit->start_line + row, &book_mark)) book_mark = -1;#endif edit_get_syntax_color (edit, b - 1, &fg, &bg); 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; c1 = min (edit->column1, edit->column2); c2 = max (edit->column1, edit->column2); if (col + 16 > -edit->start_col) { eval_marks (edit, &m1, &m2); if (row <= edit->total_lines - edit->start_line) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -