📄 propfont.c
字号:
if (line_len > cache_len) for (i = line_len - 1; i >= cache_len && i >= length; i--) { if (line[i].c.ch == ' ' && !(line[i].c.style | line[i].c.fg | line[i].c.bg)) continue; return i + 1; } for (i = cache_len - 1, line = line + i, cache = cache + i; i > length; i--, line--, cache--) if (STYLE_DIFF) return i + 1; return length + 1;}/* erases trailing bit of old line if a new line is printed over a longer old line */static void cover_trail (Window win, int x_start, int x_new, int x_old, int y){ if (x_new < EDIT_TEXT_HORIZONTAL_OFFSET) x_new = EDIT_TEXT_HORIZONTAL_OFFSET; if (x_new < x_old) { /* no need to print */#ifdef GTK gdk_gc_set_foreground (win->gc, &win->color[1]); gdk_draw_rectangle (win->text_area, win->gc, 1, x_new, y + FONT_OVERHEAD, x_old - x_new, FONT_HEIGHT);#else CSetColor (edit_normal_background_color); CRectangle (win, x_new, y + FONT_OVERHEAD, x_old - x_new, FONT_HEIGHT + (FONT_OVERHEAD != 0 && !FIXED_FONT));#endif } else {#ifdef GTK gdk_gc_set_foreground (win->gc, &win->color[1]);#else CSetColor (edit_normal_background_color);#endif }/* true type fonts print stuff out of the bounding box (aaaaaaaaarrrgh!!) */ if (!FIXED_FONT) if (FONT_OVERHEAD && x_new > EDIT_TEXT_HORIZONTAL_OFFSET)#ifdef GTK gdk_draw_line (win->text_area, win->gc, max (x_start, EDIT_TEXT_HORIZONTAL_OFFSET), y + FONT_HEIGHT + FONT_OVERHEAD, x_new - 1, y + FONT_HEIGHT + FONT_OVERHEAD);#else CLine (win, max (x_start, EDIT_TEXT_HORIZONTAL_OFFSET), y + FONT_HEIGHT + FONT_OVERHEAD, x_new - 1, y + FONT_HEIGHT + FONT_OVERHEAD);#endif}#define NOT_VALID (-2000000000)struct cache_line { int x0, x1; cache_type *data;};struct cache_line *cache_lines = 0;void edit_free_cache_lines (void){ int i; if (cache_lines) { for (i = 0; i < cache_height; i++) free (cache_lines[i].data); free (cache_lines); cache_lines = 0; }}static void edit_realloc_cache_lines (int width, int height){ if (width > cache_width || height > cache_height) { int i; edit_free_cache_lines (); cache_width = max (width + 10, cache_width); cache_height = max (height + 10, cache_height); cache_lines = malloc (sizeof (struct cache_line) * cache_height); for (i = 0; i < cache_height; i++) { cache_lines[i].data = malloc (sizeof (cache_type) * (cache_width + 1)); memset (cache_lines[i].data, 0, sizeof (cache_type) * (cache_width + 1)); cache_lines[i].x0 = NOT_VALID; cache_lines[i].x1 = 10000; } }}#define IS_HEBREW(c) (((c) >= 0x0590UL && (c) <= 0x05FFUL))int option_reverse_hebrew = 1;static void reverse_text (cache_type * line){ int i, n; if (option_reverse_hebrew) { while (line->c.ch | line->style) { while (!IS_HEBREW (line->c.ch) && (line->c.ch | line->style)) line++; for (n = 0; (IS_HEBREW (line[n].c.ch) || (line[n].c.ch == ' ')) && (line[n].c.ch | line[n].style); n++); while (n && !IS_HEBREW (line[n - 1].c.ch)) n--; n--; for (i = 0; i < (n + 1) / 2; i++) { cache_type t; t = line[i]; line[i] = line[n - i]; line[i].c.style |= MOD_REVERSE; line[n - i] = t; line[n - i].c.style |= MOD_REVERSE; } line += n + 1; } }}void edit_draw_proportional (void *data, void (*converttext) (void *, long, cache_type *, int, int, int), int calctextpos (void *, long, long *, int), int scroll_right, Window win, int x_max, long b, int row, int y, int x_offset, int tabwidth){ static Window last = 0; cache_type style, line[MAX_LINE_LEN], *p; XChar2b text[128]; wchar_t textwc[128]; int x0, x, ignore_text = 0, ignore_trailer = 2000000000, j, i; long q; tab_width = tabwidth; if (option_long_whitespace) tab_width = tabwidth *= 2; x_max -= 3; edit_realloc_cache_lines (x_max / 3, row + 1);/* if its not the same window, reset the screen rememberer */ if (last != win || !win) { last = win; for (i = 0; i < cache_height; i++) { cache_lines[i].x0 = NOT_VALID; cache_lines[i].x1 = x_max; } if (!win) return; }/* get point to start drawing */ x0 = (*calctextpos) (data, b, &q, -scroll_right + x_offset);/* q contains the offset in the edit buffer *//* translate this line into printable characters with a style (=color) high byte */ (*converttext) (data, q, line, x0, x_max - scroll_right - EDIT_TEXT_HORIZONTAL_OFFSET, row); reverse_text (line);/* adjust for the horizontal scroll and border */ x0 += scroll_right + EDIT_TEXT_HORIZONTAL_OFFSET; x = x0;/* is some of the line identical to that already printed so that we can ignore it? */ if (!EditExposeRedraw) { if (cache_lines[row].x0 == x0 && row < cache_height) { /* i.e. also && cache_lines[row].x0 != NOT_VALID */ ignore_text = get_ignore_length (cache_lines[row].data, line); if (FIXED_FONT) ignore_trailer = get_ignore_trailer (cache_lines[row].data, line, ignore_text); } } p = line; j = 0; while (p->c.ch | p->style) { if (p->c.style & MOD_PIXMAP) {#ifdef STILL_TO_BE_SUPPORTED x += edit_insert_pixmap (win, x, y, p->c.ch); /* the pixmap will be clipped, if it's taller than the current font, else centred top to bottom */#endif j++; p++; continue; } if (p->c.style & MOD_TAB) { draw_space (win, x, y, *p, p->c.ch); x += p->c.ch; j++; p++; } else if (p->c.ch == '\t') { j++; if (j > ignore_text && j < ignore_trailer + 1) x = draw_tab (win, x, y, *p, scroll_right); else x += next_tab (x, scroll_right); p++; } else { style = *p; style.c.ch = 0; i = 0; do { text[i].byte2 = (unsigned char) p->c.ch; text[i].byte1 = (unsigned char) (p->c.ch >> 8); textwc[i++] = (p++)->c.ch; j++; if (j == ignore_text || j == ignore_trailer) break; } while (i < 128 && p->c.ch && style.style == p->style && p->c.ch != '\t'); if (j > ignore_text && j < ignore_trailer + 1) { x = draw_string (win, x, y, style, text, textwc, i); } else {#ifdef GTK x += gdk_text_width (GTK_WIDGET(win)->style->font, text, i);#else x += CImageTextWidthWC (text, textwc, i);#endif } } } x = min (x, x_max); if (!EditExposeRedraw || EditClear) cover_trail (win, x0, x, cache_lines[row].x1, y); memcpy (&(cache_lines[row].data[ignore_text]), &(line[ignore_text]), (min (j, cache_width) - ignore_text) * sizeof (cache_type)); cache_lines[row].data[min (j, cache_width)].c.ch = 0; cache_lines[row].data[min (j, cache_width)].style = 0; cache_lines[row].x0 = x0; cache_lines[row].x1 = x; if (EditExposeRedraw) last = 0; else last = win;}void edit_draw_this_line_proportional (WEdit * edit, long b, int row, int start_column, int end_column){ int fg, bg; if (row < 0 || row >= edit->num_widget_lines) return; if (row + edit->start_line > edit->total_lines) b = edit->last_byte + 1; /* force b out of range of the edit buffer for blanks lines */ if (end_column > CWidthOf (edit->widget)) end_column = CWidthOf (edit->widget); edit_get_syntax_color (edit, b - 1, &fg, &bg); edit_draw_proportional (edit, (void (*) (void *, long, cache_type *, int, int, int)) convert_text, (int (*) (void *, long, long *, int)) calc_text_pos, edit->start_col, CWindowOf (edit->widget), end_column, b, row, row * FONT_PIX_PER_LINE + EDIT_TEXT_VERTICAL_OFFSET, EditExposeRedraw ? start_column : 0, FONT_PER_CHAR(' ') * TAB_SIZE);}/*********************************************************************************//* The remainder is for the text box widget *//*********************************************************************************/static int calc_text_pos_str (unsigned char *text, long b, long *q, int l){ int x = 0, c = 0, xn = 0, d; for (;;) { d = c; c = (unsigned char) text[b]; switch (c) { case '\0': case '\n': *q = b; return x; case '\t': xn = next_tab_pos (x); break; case '\r': break; case '\b': if (d) xn = x - FONT_PER_CHAR(d); break; default: if (!FONT_PER_CHAR (c)) c = ' '; xn = x + FONT_PER_CHAR(c); break; } if (xn > l) break; x = xn; b++; } *q = b; return x;}int prop_font_strcolmove (unsigned char *str, int i, int column){ long q; CPushFont ("editor", 0); calc_text_pos_str (str, i, &q, column * FONT_MEAN_WIDTH); CPopFont (); return q;}#ifndef GTK/* b is the beginning of the line. l is the length in pixels up to a point on some character which is unknown. The character pos is returned in *q and the characters pixel x pos from b is return'ed. */int calc_text_pos2 (CWidget * w, long b, long *q, int l){ int r; CPushFont ("editor", 0); r = calc_text_pos_str ((unsigned char *) w->text, b, q, l); CPopFont (); return r;}int highlight_this_line;/* this is for the text widget (i.e. nroff formatting) */void convert_text2 (CWidget * w, long q, cache_type * line, int x, int x_max, int row){ int c = 0, d; cache_type s, *p; long m1, m2; m1 = min (w->mark1, w->mark2); m2 = max (w->mark1, w->mark2); p = line; p->c.ch = p->style = 0; for (;;) { d = c; c = (unsigned char) w->text[q]; p[1].c.ch = p[1].style = 0; p->c.fg = p->c.bg = 0xFF; /* default background colors */ if (highlight_this_line) p->c.style |= MOD_HIGHLIGHTED; if (q >= m1 && q < m2) p->c.style |= MOD_MARKED; switch (c) { case '\0': case '\n': (p++)->c.ch |= ' '; if (highlight_this_line) { q--; x += FONT_PER_CHAR (' '); } else return; break; case '\t': if (FIXED_FONT) { int i; i = next_tab_pos (x) - x; x += i; s = *p; while (i > 0) { i -= FONT_PER_CHAR (' '); (p++)->c.ch = s.c.ch | ' '; p->c.ch = p->style = 0; } } else { (p++)->c.ch |= '\t'; x = next_tab_pos (x); } break; case '\r': break; case '\b': if (d) { --p; x -= FONT_PER_CHAR (d); if (d == '_') p->c.style |= MOD_ITALIC; else p->c.style |= MOD_BOLD; } break; default: if (!FONT_PER_CHAR (c)) { c = ' '; p->c.style |= MOD_ABNORMAL; } x += FONT_PER_CHAR (c); (p++)->c.ch = c; break; } if (x > x_max) break; q++; } p->c.ch = p->style = 0;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -