📄 propfont.c
字号:
/* propfont.c - editor text drawing for proportional fonts. Copyright (C) 1996-2000 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.*/#define WIDE_CHAR#include <config.h>#include "edit.h"#if defined (HAVE_MAD) && ! defined (MIDNIGHT) && ! defined (GTK)#include "mad.h"#endif#ifdef HAVE_WCHAR_H#include <wchar.h>#endif/* this file definatively relies on int being 32 bits or more */int option_long_whitespace = 0;int cache_width = 0;int cache_height = 0;#define MAX_LINE_LEN 1024/* background colors: marked is refers to mouse highlighting, highlighted refers to a found string. */extern unsigned long edit_abnormal_color, edit_marked_abnormal_color;extern unsigned long edit_highlighted_color, edit_marked_color;extern unsigned long edit_normal_background_color;/* foreground colors */extern unsigned long edit_normal_foreground_color, edit_bold_color;extern unsigned long edit_italic_color;/* cursor color */extern unsigned long edit_cursor_color;extern int EditExposeRedraw;extern int EditClear;int set_style_color (#ifdef GTK Window win,#endif cache_type s, unsigned long *fg, unsigned long *bg){ int fgp, bgp, underlined = 0; fgp = s.c.fg;/* NO_COLOR would give fgp == 255 */ if (fgp < 0xFF) *fg = color_palette (fgp); else *fg = edit_normal_foreground_color; bgp = s.c.bg; if (bgp == 0xFE) underlined = 1; if (bgp < 0xFD) *bg = color_palette (bgp); else *bg = edit_normal_background_color; if (!(s.c.style | s.c.fg | s.c.fg)) /* check this first as an optimization */ return underlined; if (s.c.style & MOD_ABNORMAL) { *bg = edit_abnormal_color; if (s.c.style & MOD_MARKED) *bg = edit_marked_abnormal_color; } else if (s.c.style & MOD_HIGHLIGHTED) { *bg = edit_highlighted_color; } else if (s.c.style & MOD_MARKED) { *bg = edit_marked_color; } if (s.c.style & MOD_BOLD) *fg = edit_bold_color; if (s.c.style & MOD_ITALIC) *fg = edit_italic_color; if (s.c.style & MOD_INVERSE) { unsigned long t; t = *fg; *fg = *bg; *bg = t; if (*bg == COLOR_BLACK) *bg = color_palette (1); } return underlined;}#ifdef GTK#define set_style_color(s,f,b) set_style_color(win,s,f,b)#endifint tab_width = 1;static inline int next_tab_pos (int x){ return x += tab_width - x % tab_width;}/* this now properly uses ctypes */static inline int convert_to_long_printable (wchar_t c, wchar_t * t){ c &= 0x7FFFFFFFUL; if (wc_isgraph (c)) { t[0] = c; t[1] = 0; return FONT_PER_CHAR_256 (c); } if (c == ' ') { if (option_long_whitespace) { t[0] = ' '; t[1] = ' '; t[2] = 0; return FONT_PER_CHAR (' ') + FONT_PER_CHAR (' '); } else { t[0] = ' '; t[1] = 0; return FONT_PER_CHAR (' '); } } if (option_international_characters && FONT_PER_CHAR (c)) { t[0] = c; t[1] = 0; return FONT_PER_CHAR (c); } if (c > 0xFFFF) { t[0] = ("0123456789ABCDEF")[(c >> 28) & 0xF]; t[1] = ("0123456789ABCDEF")[(c >> 24) & 0xF]; t[2] = ("0123456789ABCDEF")[(c >> 20) & 0xF]; t[3] = ("0123456789ABCDEF")[(c >> 16) & 0xF]; t[4] = ("0123456789ABCDEF")[(c >> 12) & 0xF]; t[5] = ("0123456789ABCDEF")[(c >> 8) & 0xF]; t[6] = ("0123456789ABCDEF")[(c >> 4) & 0xF]; t[7] = ("0123456789ABCDEF")[c & 0xF]; t[8] = 'h'; t[9] = 0; return FONT_PER_CHAR (t[0]) + FONT_PER_CHAR (t[1]) + FONT_PER_CHAR (t[2]) + FONT_PER_CHAR (t[3]) + FONT_PER_CHAR (t[4]); } if (c > 0xFF) { t[0] = ("0123456789ABCDEF")[(c >> 12) & 0xF]; t[1] = ("0123456789ABCDEF")[(c >> 8) & 0xF]; t[2] = ("0123456789ABCDEF")[(c >> 4) & 0xF]; t[3] = ("0123456789ABCDEF")[c & 0xF]; t[4] = 'h'; t[5] = 0; return FONT_PER_CHAR (t[0]) + FONT_PER_CHAR (t[1]) + FONT_PER_CHAR (t[2]) + FONT_PER_CHAR (t[3]) + FONT_PER_CHAR (t[4]); } if (c > '~') { t[0] = ("0123456789ABCDEF")[c >> 4]; t[1] = ("0123456789ABCDEF")[c & 0xF]; t[2] = 'h'; t[3] = 0; return FONT_PER_CHAR (t[0]) + FONT_PER_CHAR (t[1]) + FONT_PER_CHAR (t[2]); } t[0] = '^'; t[1] = c + '@'; t[2] = 0; return FONT_PER_CHAR (t[0]) + FONT_PER_CHAR (t[1]);}/* same as above but just gets the length */static inline int width_of_long_printable (wchar_t c){ c &= 0x7FFFFFFFUL; if (wc_isgraph (c)) return FONT_PER_CHAR (c); if (c == ' ') { if (option_long_whitespace) return FONT_PER_CHAR (' ') + FONT_PER_CHAR (' '); else return FONT_PER_CHAR (' '); } if (option_international_characters && FONT_PER_CHAR (c)) return FONT_PER_CHAR (c); if (c > 0xFF) return FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 12) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 8) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 4) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[c & 0xF]) + FONT_PER_CHAR ((unsigned char) 'h'); if (c > 0xFFFF) return FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 28) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 24) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 20) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 16) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 12) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 8) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[(c >> 4) & 0xF]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[c & 0xF]) + FONT_PER_CHAR ((unsigned char) 'h'); if (c > '~') return FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[c >> 4]) + FONT_PER_CHAR ((unsigned char) ("0123456789ABCDEF")[c & 0xF]) + FONT_PER_CHAR ((unsigned char) 'h'); return FONT_PER_CHAR ('^') + FONT_PER_CHAR (c + '@');}int edit_width_of_long_printable (wchar_t c){ return width_of_long_printable (c);}/* returns x pixel pos of char at offset *q with x not more than l */static int calc_text_pos (WEdit * edit, long b, long *q, int l){ int x = 0, xn = 0; wchar_t c; for (;;) { c = edit_get_wide_byte (edit, b); switch (c) { case -1:/* no character since used up by a multi-byte sequence */ break; case '\n': *q = b; if (x > edit->max_column) edit->max_column = x; return x; case '\t': xn = next_tab_pos (x); break; default: xn = x + width_of_long_printable (c); break; } if (xn > l) break; x = xn; b++; } *q = b; if (x > edit->max_column) edit->max_column = x; return x;}/* calcs pixel length of the line beginning at b up to upto */static int calc_text_len (WEdit * edit, long b, long upto){ int x = 0; wchar_t c; for (;;) { if (b == upto) { if (x > edit->max_column) edit->max_column = x; return x; } c = edit_get_wide_byte (edit, b); switch (c) { case -1:/* no character since used up by a multi-byte sequence */ break; case '\n':{ if (x > edit->max_column) edit->max_column = x; return x; } case '\t': x = next_tab_pos (x); break; default: x += width_of_long_printable (c); break; } b++; }}/* If pixels is zero this returns the count of pixels from current to upto. *//* If upto is zero returns index of pixels across from current. */long edit_move_forward3 (WEdit * edit, long current, int pixels, long upto){ CPushFont ("editor", 0); if (upto) { current = calc_text_len (edit, current, upto); } else if (pixels) { long q; calc_text_pos (edit, current, &q, pixels); current = q; } CPopFont (); return current;}extern int column_highlighting;/* gets the characters style (eg marked, highlighted) from its position in the edit buffer */static inline cache_type get_style_fast (WEdit * edit, long q, wchar_t c){ cache_type s; unsigned int fg, bg; s.c.ch = s.style = 0; if (!(wc_isprint (c) || (option_international_characters && FONT_PER_CHAR(c)))) if (c != '\n' && c != '\t') s.c.style = MOD_ABNORMAL; edit_get_syntax_color (edit, q, (int *) &fg, (int *) &bg); s.c.fg = fg; s.c.bg = bg; return s;}/* gets the characters style (eg marked, highlighted) from its position in the edit buffer */static inline cache_type get_style (WEdit * edit, long q, wchar_t c, long m1, long m2, int x){ cache_type s; unsigned int fg, bg; s.c.ch = s.style = 0; if (q == edit->curs1) s.c.style |= MOD_CURSOR; if (q >= m1 && q < m2) { if (column_highlighting) { if ((x >= edit->column1 && x < edit->column2) || (x >= edit->column2 && x < edit->column1)) s.c.style |= MOD_INVERSE; } else { s.c.style |= MOD_MARKED; } } if (q == edit->bracket) s.c.style |= MOD_BOLD; if (q >= edit->found_start && q < edit->found_start + edit->found_len) s.c.style |= MOD_HIGHLIGHTED; if (!(wc_isprint (c) || (option_international_characters && FONT_PER_CHAR(c)))) if (c != '\n' && c != '\t') s.c.style |= MOD_ABNORMAL; edit_get_syntax_color (edit, q, (int *) &fg, (int *) &bg); s.c.fg = fg; s.c.bg = bg; return s;}static void convert_text (WEdit * edit, long q, cache_type * p, int x, int x_max, int row){ wchar_t c; cache_type s; long m1, m2, last; wchar_t *r, text[12]; int book_mark_colors[10], book_mark; eval_marks (edit, &m1, &m2); book_mark = book_mark_query_all (edit, edit->start_line + row, book_mark_colors); last = q + (x_max - x) / 2 + 2; /* for optimization, we say that the last character of this line cannot have an offset greater than this. This can be used to rule out uncommon text styles, like a character with a cursor, or selected text */ if (book_mark) { int the_end = 0, book_mark_cycle = 0; for (;;) { c = edit_get_wide_byte (edit, q); if (!the_end) *p = get_style (edit, q, c, m1, m2, x); if (the_end) p->c.ch = p->style = 0; book_mark_cycle = (book_mark_cycle + 1) % book_mark; p->c.fg = book_mark_colors[book_mark_cycle] << 8; p->c.bg = book_mark_colors[book_mark_cycle]; switch (c) { case -1:/* no character since used up by a multi-byte sequence */ break; case '\n': the_end = 1; c = ' '; q--; goto the_default; case '\t': if (FIXED_FONT) { int t; t = next_tab_pos (x); t = min (t, x_max); s = *p; s.c.ch = ' '; while (x < t) { x += FONT_PER_CHAR(' '); *p++ = s; } } else { (p++)->c.ch = '\t'; x = next_tab_pos (x); } break; default: the_default: x += convert_to_long_printable (c, text); r = text; s = *p; s.c.ch = *r++; *p++ = s; if (!*r) break; s.c.ch = *r++; *p++ = s;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -