📄 xtext.c
字号:
/* gives width of a string, excluding the mIRC codes */static intgtk_xtext_text_width (GtkXText * xtext, unsigned char *text, int len, int *mb_ret){ unsigned char *new_buf; int new_len, mb; new_buf = gtk_xtext_strip_color (text, len, xtext->scratch_buffer, &new_len, xtext->fonttype, &mb); if (mb_ret) *mb_ret = mb; if (xtext->fonttype == FONT_1BYTE || !mb) return gtk_xtext_text_width_8bit (xtext, new_buf, new_len); return gdk_text_width (xtext->font, new_buf, new_len);}/* actually draw text to screen */static intgtk_xtext_render_flush (GtkXText * xtext, int x, int y, unsigned char *str, int len, GdkGC *gc, int is_mb){ int str_width; int dofill;#ifdef USE_XLIB XFontStruct *xfont; GC xgc; Drawable xdraw_buf; Display *xdisplay;#endif if (xtext->dont_render || len < 1) return 0; if (xtext->fonttype == FONT_1BYTE || !is_mb) str_width = gtk_xtext_text_width_8bit (xtext, str, len); else str_width = gdk_text_width (xtext->font, str, len); dofill = TRUE; /* backcolor is always handled by XDrawImageString */ if (!xtext->backcolor) { if (xtext->skip_fills) { dofill = FALSE; } else if (xtext->do_underline_fills_only) { if (xtext->underline) /* don't bother drawing the text */ goto dounder; /* redraw the background at the descent (e.g. redraws the background where the j's and y's end). This is used for unrendering a highlight. */ gdk_draw_rectangle (GTK_WIDGET (xtext)->window, xtext->bgc, 1, x, y + 1, str_width, 1); dofill = FALSE; } else if (xtext->pixmap) { /* draw the background pixmap behind the text - CAUSES FLICKER HERE!! */ gdk_draw_rectangle (GTK_WIDGET (xtext)->window, xtext->bgc, 1, x, y - xtext->font->ascent, str_width, xtext->fontsize); dofill = FALSE; /* non pixmap bg is done by XDrawImageString */ } }#ifdef USE_XLIB xgc = GDK_GC_XGC (gc); xdraw_buf = GDK_WINDOW_XWINDOW (xtext->draw_buf); xdisplay = GDK_WINDOW_XDISPLAY (GTK_WIDGET (xtext)->window); xfont = GDK_FONT_XFONT (xtext->font); switch (xtext->fonttype) { case FONT_1BYTE: if (dofill) XDrawImageString (xdisplay, xdraw_buf, xgc, x, y, str, len); else XDrawString (xdisplay, xdraw_buf, xgc, x, y, str, len); if (xtext->bold) XDrawString (xdisplay, xdraw_buf, xgc, x + 1, y, str, len); break; case FONT_2BYTE: len /= 2; if (dofill) XDrawImageString16 (xdisplay, xdraw_buf, xgc, x, y, (XChar2b *) str, len); else XDrawString16 (xdisplay, xdraw_buf, xgc, x, y, (XChar2b *) str, len); if (xtext->bold) XDrawString16 (xdisplay, xdraw_buf, xgc, x + 1, y, (XChar2b *) str, len); break; case FONT_SET: if (dofill) XmbDrawImageString (xdisplay, xdraw_buf, (XFontSet) xfont, xgc, x, y, str, len); else XmbDrawString (xdisplay, xdraw_buf, (XFontSet) xfont, xgc, x, y, str, len); if (xtext->bold) XmbDrawString (xdisplay, xdraw_buf, (XFontSet) xfont, xgc, x + 1, y, str, len); }#else /* don't have Xlib, gdk version --- */ if (dofill) { GdkGCValues val; gdk_gc_get_values (gc, &val); xtext_set_fg (gc, val.background.pixel); gdk_draw_rectangle (xtext->draw_buf, gc, 1, x, y - xtext->font->ascent, str_width, xtext->fontsize); xtext_set_fg (gc, val.foreground.pixel); } gdk_draw_text (xtext->draw_buf, xtext->font, gc, x, y, str, len); if (xtext->bold) gdk_draw_text (xtext->draw_buf, xtext->font, gc, x + 1, y, str, len);#endif if (xtext->underline) {dounder: gdk_draw_line (xtext->draw_buf, gc, x, y+1, x+str_width-1, y+1); } return str_width;}static voidgtk_xtext_reset (GtkXText * xtext, int mark, int attribs){ if (attribs) { xtext->underline = FALSE; xtext->bold = FALSE; } if (!mark) { xtext->backcolor = FALSE; if (xtext->col_fore != 18) xtext_set_fg (xtext->fgc, xtext->palette[18]); if (xtext->col_back != 19) xtext_set_bg (xtext->fgc, xtext->palette[19]); } xtext->col_fore = 18; xtext->col_back = 19; xtext->parsing_color = FALSE; xtext->parsing_backcolor = FALSE; xtext->nc = 0;}/* render a single line, which WONT wrap, and parse mIRC colors */static intgtk_xtext_render_str (GtkXText * xtext, int y, textentry * ent, unsigned char *str, int len, int win_width, int indent, int line){ GdkGC *gc; int i = 0, x = indent, j = 0; unsigned char *pstr = str; int col_num, tmp; int offset; int mark = FALSE; int hilight = FALSE; int ret = 1; offset = str - ent->str; if (line < 255 && line >= 0) xtext->grid_offset[line] = offset; gc = xtext->fgc; /* our foreground GC */ if (ent->mark_start != -1 && ent->mark_start <= i + offset && ent->mark_end > i + offset) { xtext_set_bg (gc, xtext->palette[16]); xtext_set_fg (gc, xtext->palette[17]); xtext->backcolor = TRUE; mark = TRUE; }#ifdef MOTION_MONITOR if (xtext->hilight_ent == ent && xtext->hilight_start <= i + offset && xtext->hilight_end > i + offset) { xtext->underline = TRUE; hilight = TRUE; }#endif if (!xtext->skip_border_fills) { /* draw background to the left of the text */ if (str == ent->str && indent && xtext->time_stamp) { /* don't overwrite the timestamp */ if (indent > xtext->stamp_width) { gdk_draw_rectangle (xtext->draw_buf, xtext->bgc, 1, xtext->stamp_width, y - xtext->font->ascent, indent - xtext->stamp_width, xtext->fontsize); } } else { /* fill the indent area with background gc */ gdk_draw_rectangle (xtext->draw_buf, xtext->bgc, 1, 0, y - xtext->font->ascent, indent, xtext->fontsize); } } while (i < len) {#ifdef MOTION_MONITOR if (xtext->hilight_ent == ent && xtext->hilight_start == (i + offset)) { x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); pstr += j; j = 0; xtext->underline = TRUE; hilight = TRUE; }#endif if (!mark && ent->mark_start == (i + offset)) { x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); pstr += j; j = 0; xtext_set_bg (gc, xtext->palette[16]); xtext_set_fg (gc, xtext->palette[17]); xtext->backcolor = TRUE; mark = TRUE; } if ((xtext->parsing_color && isdigit (str[i]) && xtext->nc < 2) || (xtext->parsing_color && str[i] == ',' && isdigit (str[i+1]) && xtext->nc < 3)) { pstr++; if (str[i] == ',') { xtext->parsing_backcolor = TRUE; if (xtext->nc) { xtext->num[xtext->nc] = 0; xtext->nc = 0; col_num = atoi (xtext->num) % 16; xtext->col_fore = col_num; if (!mark) xtext_set_fg (gc, xtext->palette[col_num]); } } else { xtext->num[xtext->nc] = str[i]; if (xtext->nc < 7) xtext->nc++; } } else { if (xtext->parsing_color) { xtext->parsing_color = FALSE; if (xtext->nc) { xtext->num[xtext->nc] = 0; xtext->nc = 0; col_num = atoi (xtext->num); if (col_num == 99) /* mIRC lameness */ col_num = 19; else col_num = col_num % 16; if (xtext->parsing_backcolor) { if (col_num == 19) xtext->backcolor = FALSE; else xtext->backcolor = TRUE; if (!mark) xtext_set_bg (gc, xtext->palette[col_num]); xtext->col_back = col_num; } else { if (!mark) xtext_set_fg (gc, xtext->palette[col_num]); xtext->col_fore = col_num; } xtext->parsing_backcolor = FALSE; } else { /* got a \003<non-digit>... i.e. reset colors */ x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); pstr += j; j = 0; gtk_xtext_reset (xtext, mark, FALSE); } } switch (str[i]) { /* FIXME for non-fixed width fonts. \t may not match ' ' width */ case '\t': str[i] = ' '; j++; break; case '\n': /*case ATTR_BEEP:*/ break; case ATTR_REVERSE: x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); pstr += j + 1; j = 0; tmp = xtext->col_fore; xtext->col_fore = xtext->col_back; xtext->col_back = tmp; if (!mark) { xtext_set_fg (gc, xtext->palette[xtext->col_fore]); xtext_set_bg (gc, xtext->palette[xtext->col_back]); } if (xtext->col_back != 19) xtext->backcolor = TRUE; else xtext->backcolor = FALSE; break; case ATTR_BOLD: x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); xtext->bold = !xtext->bold; pstr += j + 1; j = 0; break; case ATTR_UNDERLINE: x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); xtext->underline = !xtext->underline; pstr += j + 1; j = 0; break; case ATTR_RESET: x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); pstr += j + 1; j = 0; gtk_xtext_reset (xtext, mark, !hilight); break; case ATTR_COLOR: x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); xtext->parsing_color = TRUE; pstr += j + 1; j = 0; break; default: j++; } } i++;#ifdef MOTION_MONITOR if (xtext->hilight_ent == ent && xtext->hilight_end == (i + offset)) { x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); pstr += j; j = 0; xtext->underline = FALSE; if (xtext->jump_out_early) { /* stop drawing this ent */ ret = 0; break; } hilight = FALSE; }#endif if (mark && ent->mark_end == (i + offset)) { x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); pstr += j; j = 0; xtext_set_bg (gc, xtext->palette[xtext->col_back]); xtext_set_fg (gc, xtext->palette[xtext->col_fore]); if (xtext->col_back != 19) xtext->backcolor = TRUE; else xtext->backcolor = FALSE; mark = FALSE; } } if (j) x += gtk_xtext_render_flush (xtext, x, y, pstr, j, gc, ent->mb); if (mark) { xtext_set_bg (gc, xtext->palette[xtext->col_back]); xtext_set_fg (gc, xtext->palette[xtext->col_fore]); if (xtext->col_back != 19) xtext->backcolor = TRUE; else xtext->backcolor = FALSE; } /* draw separator now so it doesn't appear to flicker */ gtk_xtext_draw_sep (xtext, y - xtext->font->ascent); /* draw background to the right of the text */ if (!xtext->skip_border_fills) gdk_draw_rectangle (xtext->draw_buf, xtext->bgc, 1, x, y - xtext->font->ascent, (win_width + MARGIN) - x, xtext->fontsize); return ret;}#ifdef USE_XLIB/* get the desktop/root window - thanks Eterm */static Window desktop_window = None;static Windowget_desktop_window (Window the_window){ Atom prop, type, prop2; int format; unsigned long length, after; unsigned char *data; unsigned int nchildren; Window w, root, *children, parent; prop = XInternAtom (GDK_DISPLAY (), "_XROOTPMAP_ID", True); prop2 = XInternAtom (GDK_DISPLAY (), "_XROOTCOLOR_PIXEL", True); if (prop == None && prop2 == None) return None; for (w = the_window; w; w = parent) { if ((XQueryTree (GDK_DISPLAY (), w, &root, &parent, &children, &nchildren)) == False) return None; if (nchildren) XFree (children); if (prop != None) { XGetWindowProperty (GDK_DISPLAY (), w, prop, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data); } else { XGetWindowProperty (GDK_DISPLAY (), w, prop2, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data); } if (data) XFree (data); if (type != None) { return (desktop_window = w); } } return (desktop_window = None);}/* stolen from zvt, which was stolen from Eterm */static Pixmapget_pixmap_prop (Window the_window){ Atom type; int format; unsigned long length, after; unsigned char *data; Pixmap pix = None; static Atom prop = None; if (desktop_window == None) desktop_window = get_desktop_window (the_window); if (desktop_window == None) desktop_window = GDK_ROOT_WINDOW (); if (prop == None) prop = XInternAtom (GDK_DISPLAY (), "_XROOTPMAP_ID", True); if (prop == None) return None; XGetWindowProperty (GDK_DISPLAY (), desktop_window, prop, 0L, 1L, False, AnyPropertyType, &type, &format, &length, &after, &data); if (data) { if (type == XA_PIXMAP) pix = *((Pixmap *) data); XFree (data); } return pix;}#ifdef USE_MMX#include "mmx_cmod.h"static GdkPixmap *shade_pixmap_mmx (GtkXText * xtext, Pixmap p, int x, int y, int w, int h){ int dummy, width, height, depth; GdkPixmap *shaded_pix; Window root; Pixmap tmp; XImage *ximg; XGCValues gcv; GC tgc; XGetGeometry (GDK_DISPLAY (), p, &root, &dummy, &dummy, &width, &height, &dummy, &depth); if (width < x + w || height < y + h || x < 0 || y < 0) { gcv.subwindow_mode = IncludeInferiors; gcv.graphics_exposures = False; tgc = XCreateGC (GDK_DISPLAY (), p, GCGraphicsExposures|GCSubwindowMode, &gcv); tmp = XCreatePixmap (GDK_DISPLAY (), p, w, h, depth); XSetTile (GDK_DISPLAY (), tgc, p); XSetFillStyle (GDK_DISPLAY (), tgc, FillTiled); XSetTSOrigin (GDK_DISPLAY (), tgc, -x, -y); XFillRectangle (GDK_DISPLAY (), tmp, tgc, 0, 0, w, h); XFreeGC (GDK_DISPLAY (), tgc); ximg = XGetImage (GDK_DISPLAY (), tmp, 0, 0, w, h, -1, ZPixmap); XFreePixmap (GDK_DISPLAY (), tmp); } else { ximg = XGetImage (GDK_DISPLAY (), p, x, y, w, h, -1, ZPixmap); } switch (depth) { /* 1 and 8 not supported */ case 15: shade_ximage_15_mmx (ximg->data, ximg->bytes_per_line, w, h, xtext->tint_red, xtext->tint_green, xtext->tint_blue); break; case 16: shade_ximage_16_mmx (ximg->data, ximg->bytes_per_line, w, h, xtext->tint_red, xtext->tint_green, xtext->tint_blue); break; case 24: if (ximg->bits_per_pixel != 32) break; case 32: shade_ximage_32_mmx (ximg->data, ximg->bytes_per_line, w, h, xtext->tint_red, xtext->tint_green, xtext->tint_blue); break; } if (xtext->recycle) shaded_pix = xtext->pixmap; else shaded_pix = gdk_pixmap_new (GTK_WIDGET (xtext)->window, w, h, depth); XPutImage (GDK_DISPLAY (), GDK_WINDOW_XWINDOW (shaded_pix), GDK_GC_XGC (xtext->fgc), ximg, 0, 0, 0, 0, w, h); XDestroyImage (ximg);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -