|
16 | 16 | #define MAX(a,b) ((a > b) ? a : b)
|
17 | 17 |
|
18 | 18 | typedef struct fontset_item_t {
|
19 |
| - xcb_font_t xcb_ft; |
20 |
| - int height; |
21 |
| - int width; |
22 |
| - int descent; |
23 |
| - unsigned short char_max; |
24 |
| - unsigned short char_min; |
| 19 | + xcb_font_t xcb_ft; |
| 20 | + xcb_query_font_reply_t *info; |
| 21 | + xcb_charinfo_t *table; |
| 22 | + int avg_height; |
| 23 | + unsigned short char_max; |
| 24 | + unsigned short char_min; |
25 | 25 | } fontset_item_t;
|
26 | 26 |
|
27 | 27 | enum {
|
@@ -54,7 +54,6 @@ xcb_set_bg (int i)
|
54 | 54 | {
|
55 | 55 | xcb_change_gc (c, draw_gc , XCB_GC_BACKGROUND, (const unsigned []){ palette[i] });
|
56 | 56 | xcb_change_gc (c, clear_gc , XCB_GC_FOREGROUND, (const unsigned []){ palette[i] });
|
57 |
| - xcb_change_gc (c, underl_gc, XCB_GC_FOREGROUND, (const unsigned []){ palette[i] }); |
58 | 57 | }
|
59 | 58 |
|
60 | 59 | void
|
@@ -85,34 +84,44 @@ xcb_set_fontset (int i)
|
85 | 84 | int
|
86 | 85 | draw_char (int x, int align, wchar_t ch)
|
87 | 86 | {
|
| 87 | + int ch_width; |
| 88 | + |
| 89 | + ch_width = (ch > sel_font->char_min && ch < sel_font->char_max) ? |
| 90 | + sel_font->table[ch - sel_font->char_min].character_width : |
| 91 | + 0; |
| 92 | + |
| 93 | + |
| 94 | + if (ch_width == 0) |
| 95 | + return 0; |
| 96 | + |
88 | 97 | switch (align) {
|
89 | 98 | case ALIGN_C:
|
90 | 99 | xcb_copy_area (c, canvas, canvas, draw_gc, bar_width / 2 - x / 2, 0,
|
91 |
| - bar_width / 2 - (x + sel_font->width) / 2, 0, x, BAR_HEIGHT); |
92 |
| - x = bar_width / 2 - (x + sel_font->width) / 2 + x; |
| 100 | + bar_width / 2 - (x + ch_width) / 2, 0, x, BAR_HEIGHT); |
| 101 | + x = bar_width / 2 - (x + ch_width) / 2 + x; |
93 | 102 | break;
|
94 | 103 | case ALIGN_R:
|
95 | 104 | xcb_copy_area (c, canvas, canvas, draw_gc, bar_width - x, 0,
|
96 |
| - bar_width - x - sel_font->width, 0, x, BAR_HEIGHT); |
97 |
| - x = bar_width - sel_font->width; |
| 105 | + bar_width - x - ch_width, 0, x, BAR_HEIGHT); |
| 106 | + x = bar_width - ch_width; |
98 | 107 | break;
|
99 | 108 | }
|
100 | 109 |
|
101 | 110 | /* Draw the background first */
|
102 |
| - xcb_fill_rect (clear_gc, x, 0, sel_font->width, BAR_HEIGHT); |
103 |
| - |
104 |
| - /* Draw the underline */ |
105 |
| - if (BAR_UNDERLINE_HEIGHT) |
106 |
| - xcb_fill_rect (underl_gc, x, BAR_HEIGHT-BAR_UNDERLINE_HEIGHT, sel_font->width, BAR_UNDERLINE_HEIGHT); |
| 111 | + xcb_fill_rect (clear_gc, x, 0, ch_width, BAR_HEIGHT); |
107 | 112 |
|
108 | 113 | /* xcb accepts string in UCS-2 BE, so swap */
|
109 | 114 | ch = (ch >> 8) | (ch << 8);
|
110 | 115 |
|
111 | 116 | /* String baseline coordinates */
|
112 |
| - xcb_image_text_16 (c, 1, canvas, draw_gc, x, BAR_HEIGHT / 2 + sel_font->height / 2 - sel_font->descent, |
| 117 | + xcb_image_text_16 (c, 1, canvas, draw_gc, x, BAR_HEIGHT / 2 + sel_font->avg_height / 2 - sel_font->info->font_descent, |
113 | 118 | (xcb_char2b_t *)&ch);
|
114 | 119 |
|
115 |
| - return sel_font->width; |
| 120 | + /* Draw the underline */ |
| 121 | + if (BAR_UNDERLINE_HEIGHT) |
| 122 | + xcb_fill_rect (underl_gc, x, BAR_UNDERLINE*(BAR_HEIGHT-BAR_UNDERLINE_HEIGHT), ch_width, BAR_UNDERLINE_HEIGHT); |
| 123 | + |
| 124 | + return ch_width; |
116 | 125 | }
|
117 | 126 |
|
118 | 127 | void
|
@@ -214,19 +223,17 @@ font_load (const char **font_list)
|
214 | 223 | font_info = xcb_query_font_reply (c, queryreq, NULL);
|
215 | 224 |
|
216 | 225 | fontset[i].xcb_ft = font;
|
217 |
| - fontset[i].width = font_info->max_bounds.character_width; |
218 |
| - fontset[i].descent = font_info->font_descent; |
| 226 | + fontset[i].table = xcb_query_font_char_infos (font_info); |
| 227 | + fontset[i].info = font_info; |
219 | 228 | fontset[i].char_max= font_info->max_byte1 << 8 | font_info->max_char_or_byte2;
|
220 | 229 | fontset[i].char_min= font_info->min_byte1 << 8 | font_info->min_char_or_byte2;
|
221 | 230 |
|
222 | 231 | max_height = MAX(font_info->font_ascent + font_info->font_descent, max_height);
|
223 |
| - |
224 |
| - free (font_info); |
225 | 232 | }
|
226 | 233 |
|
227 | 234 | /* To have an uniform alignment */
|
228 | 235 | for (int i = 0; i < FONT_MAX; i++)
|
229 |
| - fontset[i].height = max_height; |
| 236 | + fontset[i].avg_height = max_height; |
230 | 237 |
|
231 | 238 | return 0;
|
232 | 239 | }
|
@@ -258,12 +265,12 @@ set_ewmh_atoms (xcb_window_t root)
|
258 | 265 | reply = xcb_intern_atom_reply (c, cookies[4], NULL);
|
259 | 266 | atoms[4] = reply->atom; free (reply);
|
260 | 267 |
|
261 |
| - do { |
262 |
| - reply1 = xcb_get_property_reply (c, xcb_get_property (c, 0, root, atoms[4], XCB_ATOM_ATOM, 0, -1), NULL); |
263 |
| - } while (!xcb_get_property_value_length (reply1)); |
264 |
| - |
265 | 268 | compliance_lvl = 0;
|
266 | 269 |
|
| 270 | + reply1 = xcb_get_property_reply (c, xcb_get_property (c, 0, root, atoms[4], XCB_ATOM_ATOM, 0, -1), NULL); |
| 271 | + if (!reply) |
| 272 | + return compliance_lvl; |
| 273 | + |
267 | 274 | for (xcb_atom_t *a = xcb_get_property_value (reply1);
|
268 | 275 | a && a != xcb_get_property_value_end (reply1).data;
|
269 | 276 | a++)
|
@@ -319,7 +326,7 @@ init (void)
|
319 | 326 | root = scr->root;
|
320 | 327 |
|
321 | 328 | /* Load the font */
|
322 |
| - if (font_load ((const char* []){ BAR_MAIN_FONT, BAR_FALLBACK_FONT })) |
| 329 | + if (font_load ((const char* []){ BAR_FONT })) |
323 | 330 | exit (1);
|
324 | 331 |
|
325 | 332 | /* Create the main window */
|
@@ -360,10 +367,13 @@ init (void)
|
360 | 367 | void
|
361 | 368 | cleanup (void)
|
362 | 369 | {
|
363 |
| - if (fontset[FONT_MAIN].xcb_ft) |
364 |
| - xcb_close_font (c, fontset[FONT_MAIN].xcb_ft); |
365 |
| - if (fontset[FONT_FALLBACK].xcb_ft) |
366 |
| - xcb_close_font (c, fontset[FONT_FALLBACK].xcb_ft); |
| 370 | + int i; |
| 371 | + for (i = 0; i < FONT_MAX; i++) { |
| 372 | + if (fontset[i].info) |
| 373 | + free (fontset[i].info); |
| 374 | + if (fontset[i].xcb_ft) |
| 375 | + xcb_close_font (c, fontset[i].xcb_ft); |
| 376 | + } |
367 | 377 | if (canvas)
|
368 | 378 | xcb_free_pixmap (c, canvas);
|
369 | 379 | if (win)
|
|
0 commit comments