Support for non-monospaced fonts. Changed the font definition in the config.

This commit is contained in:
LemonBoy 2012-07-25 16:55:26 +02:00
parent 1abd4c2d5a
commit a4a3c805e3
3 changed files with 35 additions and 27 deletions

View File

@ -3,8 +3,8 @@ b(ar) a(in't) r(ecursive)
2012 (C) The Lemon Man 2012 (C) The Lemon Man
A lightweight bar based on XCB (yay). Provides foreground/background color A lightweight bar based on XCB (yay). Provides foreground/background color
switching along with text alignment (screw you dzen!), nothing less and switching along with text alignment (screw you dzen!), full utf8 support
nothing more. and reduced memory footprint. Nothing less and nothing more.
Options Options
------- -------

53
bar.c
View File

@ -15,12 +15,12 @@
#define MAX(a,b) ((a > b) ? a : b) #define MAX(a,b) ((a > b) ? a : b)
typedef struct fontset_item_t { typedef struct fontset_item_t {
xcb_font_t xcb_ft; xcb_font_t xcb_ft;
int height; xcb_query_font_reply_t *info;
int width; xcb_charinfo_t *table;
int descent; int avg_height;
unsigned short char_max; unsigned short char_max;
unsigned short char_min; unsigned short char_min;
} fontset_item_t; } fontset_item_t;
enum { enum {
@ -77,34 +77,43 @@ xcb_set_fontset (int i)
int int
draw_char (int x, int align, wchar_t ch) draw_char (int x, int align, wchar_t ch)
{ {
int ch_width;
ch_width = (ch > sel_font->char_min && ch < sel_font->char_max) ?
sel_font->table[ch - sel_font->char_min].character_width :
0;
if (ch_width == 0)
return 0;
switch (align) { switch (align) {
case 1: case 1:
xcb_copy_area (c, canvas, canvas, draw_gc, bar_width / 2 - x / 2, 0, xcb_copy_area (c, canvas, canvas, draw_gc, bar_width / 2 - x / 2, 0,
bar_width / 2 - (x + sel_font->width) / 2, 0, x, BAR_HEIGHT); bar_width / 2 - (x + ch_width) / 2, 0, x, BAR_HEIGHT);
x = bar_width / 2 - (x + sel_font->width) / 2 + x; x = bar_width / 2 - (x + ch_width) / 2 + x;
break; break;
case 2: case 2:
xcb_copy_area (c, canvas, canvas, draw_gc, bar_width - x, 0, xcb_copy_area (c, canvas, canvas, draw_gc, bar_width - x, 0,
bar_width - x - sel_font->width, 0, x, BAR_HEIGHT); bar_width - x - ch_width, 0, x, BAR_HEIGHT);
x = bar_width - sel_font->width; x = bar_width - ch_width;
break; break;
} }
/* Draw the background first */ /* Draw the background first */
xcb_fill_rect (clear_gc, x, 0, sel_font->width, BAR_HEIGHT); xcb_fill_rect (clear_gc, x, 0, ch_width, BAR_HEIGHT);
/* Draw the underline */ /* Draw the underline */
if (BAR_UNDERLINE_HEIGHT) if (BAR_UNDERLINE_HEIGHT)
xcb_fill_rect (underl_gc, x, BAR_HEIGHT-BAR_UNDERLINE_HEIGHT, sel_font->width, BAR_UNDERLINE_HEIGHT); xcb_fill_rect (underl_gc, x, BAR_HEIGHT-BAR_UNDERLINE_HEIGHT, ch_width, BAR_UNDERLINE_HEIGHT);
/* xcb accepts string in UCS-2 BE, so swap */ /* xcb accepts string in UCS-2 BE, so swap */
ch = (ch >> 8) | (ch << 8); ch = (ch >> 8) | (ch << 8);
/* String baseline coordinates */ /* String baseline coordinates */
xcb_image_text_16 (c, 1, canvas, draw_gc, x, BAR_HEIGHT / 2 + sel_font->height / 2 - sel_font->descent, xcb_image_text_16 (c, 1, canvas, draw_gc, x, BAR_HEIGHT / 2 + sel_font->avg_height / 2 - sel_font->info->font_descent,
(xcb_char2b_t *)&ch); (xcb_char2b_t *)&ch);
return sel_font->width; return ch_width;
} }
void void
@ -206,19 +215,17 @@ font_load (const char **font_list)
font_info = xcb_query_font_reply (c, queryreq, NULL); font_info = xcb_query_font_reply (c, queryreq, NULL);
fontset[i].xcb_ft = font; fontset[i].xcb_ft = font;
fontset[i].width = font_info->max_bounds.character_width; fontset[i].table = xcb_query_font_char_infos (font_info);
fontset[i].descent = font_info->font_descent; fontset[i].info = font_info;
fontset[i].char_max= font_info->max_byte1 << 8 | font_info->max_char_or_byte2; fontset[i].char_max= font_info->max_byte1 << 8 | font_info->max_char_or_byte2;
fontset[i].char_min= font_info->min_byte1 << 8 | font_info->min_char_or_byte2; fontset[i].char_min= font_info->min_byte1 << 8 | font_info->min_char_or_byte2;
max_height = MAX(font_info->font_ascent + font_info->font_descent, max_height); max_height = MAX(font_info->font_ascent + font_info->font_descent, max_height);
free (font_info);
} }
/* To have an uniform alignment */ /* To have an uniform alignment */
for (int i = 0; i < FONT_MAX; i++) for (int i = 0; i < FONT_MAX; i++)
fontset[i].height = max_height; fontset[i].avg_height = max_height;
return 0; return 0;
} }
@ -306,7 +313,7 @@ init (void)
root = scr->root; root = scr->root;
/* Load the font */ /* Load the font */
if (font_load ((const char* []){ BAR_MAIN_FONT, BAR_FALLBACK_FONT })) if (font_load ((const char* []){ BAR_FONT }))
exit (1); exit (1);
/* Create the main window */ /* Create the main window */
@ -348,8 +355,10 @@ init (void)
void void
cleanup (void) cleanup (void)
{ {
xcb_close_font (c, fontset[FONT_MAIN].xcb_ft); for (int i = 0; i < FONT_MAX; i++) {
xcb_close_font (c, fontset[FONT_FALLBACK].xcb_ft); free (fontset[i].info);
xcb_close_font (c, fontset[i].xcb_ft);
}
xcb_free_pixmap (c, canvas); xcb_free_pixmap (c, canvas);
xcb_destroy_window (c, win); xcb_destroy_window (c, win);
xcb_free_gc (c, draw_gc); xcb_free_gc (c, draw_gc);

View File

@ -4,9 +4,8 @@
#define BAR_UNDERLINE_HEIGHT 2 #define BAR_UNDERLINE_HEIGHT 2
/* Whether to put the bar at the screen bottom or not */ /* Whether to put the bar at the screen bottom or not */
#define BAR_BOTTOM 0 #define BAR_BOTTOM 0
/* The font used for the bar */ /* The fonts used for the bar, comma separated. Only the first 2 will be used. */
#define BAR_MAIN_FONT "-*-terminus-medium-r-normal-*-12-*-*-*-c-*-*-1" #define BAR_FONT "-*-terminus-medium-r-normal-*-12-*-*-*-c-*-*-1","fixed"
#define BAR_FALLBACK_FONT "fixed"
/* Color palette */ /* Color palette */
#define COLOR0 0x1A1A1A /* background */ #define COLOR0 0x1A1A1A /* background */
#define COLOR1 0xA9A9A9 /* foreground */ #define COLOR1 0xA9A9A9 /* foreground */