From 14beabe55fa3cac03f598e138f363f1d50659564 Mon Sep 17 00:00:00 2001 From: Shawn Betts Date: Sat, 4 Jul 2009 20:58:21 -0700 Subject: fix inverted text when using xft Now the inverted rectangle is drawn first and the text overtop in the bg color. --- src/actions.c | 30 ++++++++++++++++------ src/bar.c | 81 +++++++++++++++++++++++++++++++++++++---------------------- src/data.h | 4 +-- src/globals.c | 6 ++--- src/globals.h | 6 ++++- src/input.c | 4 +-- src/main.c | 5 +++- src/screen.c | 47 +++++++++++++++++++++------------- src/split.c | 2 +- 9 files changed, 120 insertions(+), 65 deletions(-) (limited to 'src') diff --git a/src/actions.c b/src/actions.c index bb129ae..f582ab5 100644 --- a/src/actions.c +++ b/src/actions.c @@ -1772,7 +1772,7 @@ read_frame (struct argspec *spec, struct sbuf *s, struct cmdarg **arg) XClearWindow (dpy, wins[i]); /* Display the frame's number inside the window. */ - rp_draw_string (s, wins[i], s->normal_gc, + rp_draw_string (s, wins[i], STYLE_NORMAL, defaults.bar_x_padding, defaults.bar_y_padding + FONT_ASCENT(s), num, -1); @@ -3312,7 +3312,7 @@ cmd_license (int interactive, struct cmdarg **args) /* Print the text. */ for(i=0; license_text[i]; i++) { - rp_draw_string (s, s->help_window, s->normal_gc, + rp_draw_string (s, s->help_window, STYLE_NORMAL, x, y + FONT_ASCENT(s), license_text[i], -1); @@ -3364,19 +3364,19 @@ cmd_help (int interactive, struct cmdarg **args) XMapRaised (dpy, s->help_window); - rp_draw_string (s, s->help_window, s->normal_gc, + rp_draw_string (s, s->help_window, STYLE_NORMAL, 10, y + FONT_ASCENT(s), "ratpoison key bindings", -1); y += FONT_HEIGHT (s) * 2; - rp_draw_string (s, s->help_window, s->normal_gc, + rp_draw_string (s, s->help_window, STYLE_NORMAL, 10, y + FONT_ASCENT(s), "Command key: ", -1); keysym_name = keysym_to_string (prefix_key.sym, prefix_key.state); - rp_draw_string (s, s->help_window, s->normal_gc, + rp_draw_string (s, s->help_window, STYLE_NORMAL, 10 + rp_text_width (s, defaults.font, "Command key: ", -1), y + FONT_ASCENT(s), keysym_name, -1); @@ -3392,7 +3392,7 @@ cmd_help (int interactive, struct cmdarg **args) { keysym_name = keysym_to_string (map->actions[i].key, map->actions[i].state); - rp_draw_string (s, s->help_window, s->normal_gc, + rp_draw_string (s, s->help_window, STYLE_NORMAL, x, y + FONT_ASCENT(s), keysym_name, -1); @@ -3403,7 +3403,7 @@ cmd_help (int interactive, struct cmdarg **args) } else { - rp_draw_string (s, s->help_window, s->normal_gc, + rp_draw_string (s, s->help_window, STYLE_NORMAL, x, y + FONT_ASCENT(s), map->actions[i].data, -1); @@ -3643,6 +3643,13 @@ update_gc (rp_screen *s) GCForeground | GCBackground | GCFunction | GCLineWidth | GCSubwindowMode, &gv); + gv.foreground = s->bg_color; + gv.background = s->fg_color; + XFreeGC (dpy, s->inverse_gc); + s->inverse_gc = XCreateGC(dpy, s->root, + GCForeground | GCBackground + | GCFunction | GCLineWidth + | GCSubwindowMode, &gv); } #ifndef USE_XFT_FONT @@ -3996,7 +4003,7 @@ set_fgcolor (struct cmdarg **args) #ifdef USE_XFT_FONT if (!XftColorAllocName (dpy, DefaultVisual (dpy, screens[i].screen_num), DefaultColormap (dpy, screens[i].screen_num), - ARG_STRING(0), &screens[i].xft_color)) + ARG_STRING(0), &screens[i].xft_fg_color)) return cmdret_new (RET_FAILURE, "deffgcolor: unknown color"); #endif @@ -4028,6 +4035,13 @@ set_bgcolor (struct cmdarg **args) XSetWindowBackground (dpy, screens[i].frame_window, color.pixel); XSetWindowBackground (dpy, screens[i].help_window, color.pixel); +#ifdef USE_XFT_FONT + if (!XftColorAllocName (dpy, DefaultVisual (dpy, screens[i].screen_num), + DefaultColormap (dpy, screens[i].screen_num), + ARG_STRING(0), &screens[i].xft_bg_color)) + return cmdret_new (RET_FAILURE, "deffgcolor: unknown color"); +#endif + free (defaults.bgcolor_string); defaults.bgcolor_string = xstrdup (ARG_STRING(0)); } diff --git a/src/bar.c b/src/bar.c index 88b9966..e04caeb 100644 --- a/src/bar.c +++ b/src/bar.c @@ -321,39 +321,68 @@ line_beginning (char* msg, int pos) } static void -draw_string (rp_screen *s, char *msg) +draw_partial_string (rp_screen *s, char *msg, int line_no, int start, int end, int style) { + int line_height = FONT_HEIGHT (s); + + rp_draw_string (s, s->bar_window, style, + defaults.bar_x_padding, + defaults.bar_y_padding + FONT_ASCENT(s) + + line_no * line_height, + msg + start, end - start + 1); +} + +static void +draw_string (rp_screen *s, char *msg, int mark_start, int mark_end) +{ + XGCValues lgv; + GC lgc; + unsigned long mask; size_t i; int line_no; int start; - int line_height = FONT_HEIGHT (s); + int style = STYLE_NORMAL, update = 0; + + lgv.foreground = s->fg_color; + mask = GCForeground; + lgc = XCreateGC(dpy, s->root, mask, &lgv); /* Walk through the string, print each line. */ start = 0; line_no = 0; +/* if (mark_start == 0 && mark_end == 0) */ +/* mark_start = mark_end = -1; */ + for(i=0; i < strlen(msg); ++i) { - /* When we encounter a new line, print the text up to the new - line, and move down one line. */ + if (i == mark_start) + { + style = STYLE_INVERSE; + update = 1; + } + if (i == mark_end) + { + style = STYLE_NORMAL; + update = 1; + } if (msg[i] == '\n') + update = 2; + + if (update) { - rp_draw_string (s, s->bar_window, s->normal_gc, - defaults.bar_x_padding, - defaults.bar_y_padding + FONT_ASCENT(s) - + line_no * line_height, - msg + start, i - start); - line_no++; - start = i + 1; + draw_partial_string (s, msg, line_no, start, update == 2 ? i-1:i, style); + start = i; + if (update == 2) + { + line_no++; + start++; + } + update = 0; } } /* Print the last line. */ - rp_draw_string (s, s->bar_window, s->normal_gc, - defaults.bar_x_padding, - defaults.bar_y_padding + FONT_ASCENT(s) - + line_no * line_height, - msg + start, strlen (msg) - start); - + draw_partial_string (s, msg, line_no, start, strlen (msg)-1, style); XSync (dpy, False); } @@ -479,22 +508,14 @@ get_mark_box (char *msg, size_t mark_start, size_t mark_end, } static void -draw_inverse_box (rp_screen *s, int x, int y, int width, int height) +draw_box (rp_screen *s, int x, int y, int width, int height) { XGCValues lgv; GC lgc; unsigned long mask; lgv.foreground = s->fg_color; - lgv.function = GXxor; - mask = GCForeground | GCFunction; - lgc = XCreateGC(dpy, s->root, mask, &lgv); - - XFillRectangle (dpy, s->bar_window, lgc, - x, y, width, height); - XFreeGC (dpy, lgc); - - lgv.foreground = s->bg_color; + mask = GCForeground; lgc = XCreateGC(dpy, s->root, mask, &lgv); XFillRectangle (dpy, s->bar_window, lgc, @@ -513,7 +534,7 @@ draw_mark (rp_screen *s, char *msg, int mark_start, int mark_end) get_mark_box (msg, mark_start, mark_end, &x, &y, &width, &height); - draw_inverse_box (s, x, y, width, height); + draw_box (s, x, y, width, height); } static void @@ -550,14 +571,14 @@ marked_message_internal (char *msg, int mark_start, int mark_end) width = defaults.bar_x_padding * 2 + max_line_length(msg); height = FONT_HEIGHT (s) * num_lines + defaults.bar_y_padding * 2; - /* Display the string. */ prepare_bar (s, width, height); - draw_string (s, msg); /* Draw the mark over the designated part of the string. */ correct_mark (strlen (msg), &mark_start, &mark_end); draw_mark (s, msg, mark_start, mark_end); + draw_string (s, msg, mark_start, mark_end); + /* Keep a record of the message. */ update_last_message (msg, mark_start, mark_end); } diff --git a/src/data.h b/src/data.h index 947b571..806ece9 100644 --- a/src/data.h +++ b/src/data.h @@ -151,7 +151,7 @@ struct rp_group struct rp_screen { - GC normal_gc; + GC normal_gc, inverse_gc; Window root, bar_window, key_window, input_window, frame_window, help_window; int bar_is_raised; int screen_num; /* Our screen number as dictated my X */ @@ -178,7 +178,7 @@ struct rp_screen #ifdef USE_XFT_FONT XftFont *xft_font; - XftColor xft_color; + XftColor xft_fg_color, xft_bg_color; #endif }; diff --git a/src/globals.c b/src/globals.c index f21195f..7446bca 100644 --- a/src/globals.c +++ b/src/globals.c @@ -272,7 +272,7 @@ init_globals (void) /* Wrapper font functions to support Xft */ void -rp_draw_string (rp_screen *s, Drawable d, GC gc, int x, int y, char *string, int length) +rp_draw_string (rp_screen *s, Drawable d, int style, int x, int y, char *string, int length) { if (length < 0) length = strlen (string); @@ -285,7 +285,7 @@ rp_draw_string (rp_screen *s, Drawable d, GC gc, int x, int y, char *string, int DefaultColormap (dpy, s->screen_num)); if (draw) { - XftDrawString8 (draw, &s->xft_color, s->xft_font, x, y, (FcChar8*) string, length); + XftDrawString8 (draw, style == STYLE_NORMAL ? &s->xft_fg_color:&s->xft_bg_color, s->xft_font, x, y, (FcChar8*) string, length); XftDrawDestroy (draw); } else @@ -293,7 +293,7 @@ rp_draw_string (rp_screen *s, Drawable d, GC gc, int x, int y, char *string, int } else #endif - XmbDrawString (dpy, d, defaults.font, gc, x, y, string, length); + XmbDrawString (dpy, d, defaults.font, style == STYLE_NORMAL ? s->normal_gc:s->inverse_gc, x, y, string, length); } int diff --git a/src/globals.h b/src/globals.h index 452cf0d..cb5e16c 100644 --- a/src/globals.h +++ b/src/globals.h @@ -66,6 +66,10 @@ #define GROUP_DELETE_GROUP_NONEMPTY 1 #define GROUP_DELETE_LAST_GROUP 2 +/* Font styles */ +#define STYLE_NORMAL 0 +#define STYLE_INVERSE 1 + /* The list of groups. */ extern struct list_head rp_groups; @@ -195,7 +199,7 @@ void init_globals (void); /* Wrapper font functions to support Xft */ -void rp_draw_string (rp_screen *s, Drawable d, GC gc, int x, int y, char *string, int length); +void rp_draw_string (rp_screen *s, Drawable d, int style, int x, int y, char *string, int length); int rp_text_width (rp_screen *s, XFontSet font, char *string, int count); #endif diff --git a/src/input.c b/src/input.c index 35454df..e2c3054 100644 --- a/src/input.c +++ b/src/input.c @@ -450,13 +450,13 @@ update_input_window (rp_screen *s, rp_input_line *line) XClearWindow (dpy, s->input_window); XSync (dpy, False); - rp_draw_string (s, s->input_window, s->normal_gc, + rp_draw_string (s, s->input_window, STYLE_NORMAL, defaults.bar_x_padding, defaults.bar_y_padding + FONT_ASCENT(s), line->prompt, -1); - rp_draw_string (s, s->input_window, s->normal_gc, + rp_draw_string (s, s->input_window, STYLE_NORMAL, defaults.bar_x_padding + prompt_width, defaults.bar_y_padding + FONT_ASCENT(s), line->buffer, diff --git a/src/main.c b/src/main.c index 3c05152..c7ad72f 100644 --- a/src/main.c +++ b/src/main.c @@ -777,7 +777,9 @@ free_screen (rp_screen *s) if (s->xft_font) { XftColorFree (dpy, DefaultVisual (dpy, s->screen_num), - DefaultColormap (dpy, s->screen_num), &s->xft_color); + DefaultColormap (dpy, s->screen_num), &s->xft_fg_color); + XftColorFree (dpy, DefaultVisual (dpy, s->screen_num), + DefaultColormap (dpy, s->screen_num), &s->xft_bg_color); XftFontClose (dpy, s->xft_font); } #endif @@ -785,6 +787,7 @@ free_screen (rp_screen *s) XFreeCursor (dpy, s->rat); XFreeColormap (dpy, s->def_cmap); XFreeGC (dpy, s->normal_gc); + XFreeGC (dpy, s->inverse_gc); free (s->display_string); } diff --git a/src/screen.c b/src/screen.c index ed7376a..aaf7bd8 100644 --- a/src/screen.c +++ b/src/screen.c @@ -309,6 +309,12 @@ init_screen (rp_screen *s, int screen_num) GCForeground | GCBackground | GCFunction | GCLineWidth | GCSubwindowMode, &gv); + gv.foreground = s->bg_color; + gv.background = s->fg_color; + s->inverse_gc = XCreateGC(dpy, s->root, + GCForeground | GCBackground | GCFunction + | GCLineWidth | GCSubwindowMode, + &gv); /* Create the program bar window. */ s->bar_is_raised = 0; @@ -344,23 +350,30 @@ init_screen (rp_screen *s, int screen_num) #ifdef USE_XFT_FONT { - if (!XftColorAllocName (dpy, DefaultVisual (dpy, screen_num), - DefaultColormap (dpy, screen_num), - defaults.fgcolor_string, &s->xft_color)) - { - PRINT_ERROR(("Failed to allocate font color\n")); - s->xft_font = NULL; - } - else - { - s->xft_font = XftFontOpenName (dpy, screen_num, DEFAULT_XFT_FONT); - if (!s->xft_font) - { - PRINT_ERROR(("Failed to open font\n")); - XftColorFree (dpy, DefaultVisual (dpy, screen_num), - DefaultColormap (dpy, screen_num), &s->xft_color); - } - } + s->xft_font = XftFontOpenName (dpy, screen_num, DEFAULT_XFT_FONT); + if (!s->xft_font) + { + PRINT_ERROR(("Failed to open font\n")); + } + else + { + if (!XftColorAllocName (dpy, DefaultVisual (dpy, screen_num), + DefaultColormap (dpy, screen_num), + defaults.fgcolor_string, &s->xft_fg_color)) + { + PRINT_ERROR(("Failed to allocate font fg color\n")); + XftFontClose (dpy, s->xft_font); + s->xft_font = NULL; + } + if (!XftColorAllocName (dpy, DefaultVisual (dpy, screen_num), + DefaultColormap (dpy, screen_num), + defaults.bgcolor_string, &s->xft_bg_color)) + { + PRINT_ERROR(("Failed to allocate font fg color\n")); + XftFontClose (dpy, s->xft_font); + s->xft_font = NULL; + } + } } #endif } diff --git a/src/split.c b/src/split.c index 9b31b89..fa6e08f 100644 --- a/src/split.c +++ b/src/split.c @@ -1016,7 +1016,7 @@ show_frame_message (char *msg) XClearWindow (dpy, s->frame_window); XSync (dpy, False); - rp_draw_string (s, s->frame_window, s->normal_gc, + rp_draw_string (s, s->frame_window, STYLE_NORMAL, defaults.bar_x_padding, defaults.bar_y_padding + FONT_ASCENT(s), msgbuf->data, msgbuf->len); -- cgit v1.2.3