Skip to content

Commit

Permalink
Add pango support
Browse files Browse the repository at this point in the history
  • Loading branch information
mstg committed Mar 14, 2016
1 parent f3eb56c commit 4a74cfa
Show file tree
Hide file tree
Showing 7 changed files with 214 additions and 21 deletions.
4 changes: 4 additions & 0 deletions LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -19,3 +19,7 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

Pango support is heavily based on https://github.com/s-ol/i3bgbar/blob/master/libi3
Copyright © 2009-2011, Michael Stapelberg and contributors
All rights reserved.
2 changes: 0 additions & 2 deletions Makefile.am

This file was deleted.

7 changes: 5 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ i3 scratchpad manager
[AUR package](https://aur.archlinux.org/packages/zx-git/)

```
usage: zx [ -h | -x | -H | -d | -b | -f | -n | -F | -a | -B | -p]
usage: zx [ -h | -x | -H | -d | -b | -f | -n | -F | -a | -B | -p | -t]
-h shows help
-x sets x offset
-H sets height
Expand All @@ -18,6 +18,7 @@ usage: zx [ -h | -x | -H | -d | -b | -f | -n | -F | -a | -B | -p]
-a sets border color
-B sets border
-p pin to bottom of screen
-t font type (pango | xcb)
```

# About zx
Expand Down Expand Up @@ -68,9 +69,10 @@ border=1
floating=0
font_color=0xFFFFFF
daemon=0
font=fixed
pin_bottom=1
height=25
font_type=pango
font=DejaVu Sans Mono 4
```

Config explanation
Expand All @@ -84,6 +86,7 @@ daemon (int) - run in daemon mode or not
font (char) - font name
pin_bottom (int) - pin to bottom of screen
height (int) - height of zx bar
font_type (char) - font type; either pango (for antialiased fonts) or xcb (old xfontsel fonts)
```

You can also show/hide zx on command by sending it a USR1 signal (ex. `killall -USR1 zx`)
Expand Down
3 changes: 3 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@ AC_PROG_CC
# Checks for libraries.
PKG_CHECK_MODULES([xcb], [xcb])
PKG_CHECK_MODULES([i3ipc], [i3ipc-glib-1.0])
PKG_CHECK_MODULES([pango], [pango])
PKG_CHECK_MODULES([pangocairo], [pangocairo])
PKG_CHECK_MODULES([cairo], [cairo])

# Checks for header files.
AC_CHECK_HEADERS([stdlib.h string.h unistd.h glib.h])
Expand Down
22 changes: 21 additions & 1 deletion include/xcb_helper.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ THE SOFTWARE.
This file is going to make it easier for you to work with xcb. Feel free to copy
*/
#include <xcb/xcb.h>
#include <cairo/cairo-xcb.h>
#include <pango/pangocairo.h>

enum {
NET_WM_WINDOW_TYPE,
Expand All @@ -45,6 +47,21 @@ enum {
XCB_H_NO_FONT
};

#define PANGO 0
#define xcb 1

typedef struct pango_font {
PangoFontDescription *pango_desc;
xcb_visualtype_t *root_visual_type;
double pango_font_red;
double pango_font_green;
double pango_font_blue;

double pango_bgfont_red;
double pango_bgfont_green;
double pango_bgfont_blue;
} pango_font;

typedef struct xcb_helper_struct {
xcb_connection_t *c;
xcb_window_t window;
Expand All @@ -68,6 +85,9 @@ typedef struct xcb_helper_struct {
int font_width;
int font_height;
int font_descent;
int font_type;
pango_font *pfont;
xcb_visualtype_t *root_visual_type;
} xcb_helper_struct;

void xcb_h_setup(xcb_helper_struct *internal);
Expand Down Expand Up @@ -96,7 +116,7 @@ void xcb_h_draw_fill_rect(xcb_helper_struct *internal, int gcnum, int num, xcb_r

void xcb_h_setup_font(xcb_helper_struct *internal, const char *fontname);

int xcb_h_draw_text(xcb_helper_struct *internal, int gcnum, int x, int y, const char *text);
int xcb_h_draw_text(xcb_helper_struct *internal, int gcnum, int x, int y, const char *text, int max_width);

void xcb_h_destroy(int exit_status, void *internal);

Expand Down
134 changes: 129 additions & 5 deletions src/xcb_helper.c
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ void xcb_h_check_cookie(xcb_helper_struct *internal, xcb_void_cookie_t cookie, c
xcb_generic_error_t *error = xcb_request_check(internal->c, cookie);
if (error) {
printf("%s\n", err);
exit(-1);
xcb_h_destroy(-1, internal);
exit(-1);
}
}

Expand Down Expand Up @@ -144,7 +144,110 @@ void xcb_h_draw_fill_rect(xcb_helper_struct *internal, int gcnum, int num, xcb_r
xcb_poly_fill_rectangle(internal->c, internal->window, internal->gc[gcnum], num, rect);
}

/*
From: https://github.com/s-ol/i3bgbar/blob/master/libi3
Copyright © 2009-2011, Michael Stapelberg and contributors
All rights reserved.
*/
PangoLayout *create_layout_with_dpi(xcb_helper_struct *_s, cairo_t *cr) {
PangoLayout *layout;
PangoContext *context;

context = pango_cairo_create_context(cr);
const double dpi = (double)180;
pango_cairo_context_set_resolution(context, dpi);
layout = pango_layout_new(context);
g_object_unref(context);

return layout;
}

xcb_visualtype_t *get_visualtype(xcb_screen_t *screen) {
xcb_depth_iterator_t depth_iter;
for (depth_iter = xcb_screen_allowed_depths_iterator(screen);
depth_iter.rem;
xcb_depth_next(&depth_iter)) {
xcb_visualtype_iterator_t visual_iter;
for (visual_iter = xcb_depth_visuals_iterator(depth_iter.data);
visual_iter.rem;
xcb_visualtype_next(&visual_iter)) {
if (screen->root_visual == visual_iter.data->visual_id)
return visual_iter.data;
}
}
return NULL;
}
int predict_text_width_pango(xcb_helper_struct *internal, const char *text) {
cairo_surface_t *surface = cairo_xcb_surface_create(internal->c, internal->screen->root, internal->root_visual_type, 1, 1);
cairo_t *cr = cairo_create(surface);
PangoLayout *layout = create_layout_with_dpi(internal, cr);

gint width;
pango_layout_set_font_description(layout, internal->pfont->pango_desc);
pango_layout_set_text(layout, text, strlen(text));
pango_cairo_update_layout(cr, layout);
pango_layout_get_pixel_size(layout, &width, NULL);

g_object_unref(layout);
cairo_destroy(cr);
cairo_surface_destroy(surface);

return width;
}
void draw_text_pango(xcb_helper_struct *internal, const char *text, int x, int y, int max_width) {
cairo_surface_t *surface = cairo_xcb_surface_create(internal->c, internal->window,
internal->root_visual_type, internal->x + internal->width, internal->y + internal->height);
cairo_t *cr = cairo_create(surface);
PangoLayout *layout = create_layout_with_dpi(internal, cr);
gint height;

int font_width = predict_text_width_pango(internal, text);
int font_size = pango_font_description_get_size(internal->pfont->pango_desc) / PANGO_SCALE;
pango_layout_set_font_description(layout, internal->pfont->pango_desc);
pango_layout_set_width(layout, (max_width) * font_size * PANGO_SCALE);
pango_layout_set_wrap(layout, PANGO_WRAP_CHAR);
pango_layout_set_ellipsize(layout, PANGO_ELLIPSIZE_END);

pango_layout_set_text(layout, text, strlen(text));

cairo_set_source_rgb(cr, internal->pfont->pango_font_red, internal->pfont->pango_font_green, internal->pfont->pango_font_blue);
pango_cairo_update_layout(cr, layout);
pango_layout_get_pixel_size(layout, NULL, &height);
cairo_move_to(cr, x - font_width/2, y-internal->font_height);
pango_cairo_show_layout(cr, layout);

g_object_unref(layout);
cairo_destroy(cr);
cairo_surface_destroy(surface);
}
/**/

void xcb_h_setup_font(xcb_helper_struct *internal, const char *fontname) {
if (internal->font_type == PANGO) {
internal->pfont->pango_desc = pango_font_description_from_string(fontname);
if (!internal->pfont->pango_desc) {
fprintf(stderr, "ERROR! Could not load pango font!\n");
xcb_h_destroy(-1, internal);
exit(-1);
}

internal->root_visual_type = get_visualtype(internal->screen);

cairo_surface_t *surface = cairo_xcb_surface_create(internal->c, internal->screen->root, internal->root_visual_type, 1, 1);
cairo_t *cr = cairo_create(surface);
PangoLayout *layout = create_layout_with_dpi(internal, cr);
pango_layout_set_font_description(layout, internal->pfont->pango_desc);

gint height;
pango_layout_get_pixel_size(layout, NULL, &height);
internal->font_height = height;

g_object_unref(layout);
cairo_destroy(cr);
cairo_surface_destroy(surface);
return;
}

internal->font = xcb_generate_id (internal->c);
xcb_void_cookie_t font_c = xcb_open_font_checked(internal->c, internal->font, strlen(fontname), fontname);
xcb_h_check_cookie(internal, font_c, "cant open font");
Expand All @@ -159,16 +262,27 @@ void xcb_h_setup_font(xcb_helper_struct *internal, const char *fontname) {
internal->gc[GC_FONT] = xcb_generate_id(internal->c);
xcb_create_gc(internal->c, internal->gc[GC_FONT], internal->window, XCB_GC_FOREGROUND | XCB_GC_BACKGROUND | XCB_GC_FONT, (const uint32_t[]){ internal->font_color,
internal->background, internal->font });

free(font_info);
}

int xcb_h_draw_text(xcb_helper_struct *internal, int gcnum, int x, int y, const char *text) {
if (!internal->font) {
int xcb_h_draw_text(xcb_helper_struct *internal, int gcnum, int x, int y, const char *text, int max_width) {
if ((internal->font_type == xcb && !internal->font) || (internal->font_type == PANGO && !internal->pfont)) {
printf("no font\n");
return XCB_H_NO_FONT;
}

xcb_void_cookie_t fontd_c = xcb_image_text_8_checked(internal->c, strlen(text), internal->window, internal->gc[gcnum], x, y, text);
xcb_h_check_cookie(internal, fontd_c, "cant draw text\n");
xcb_void_cookie_t fontd_c;
int ch_width;
switch (internal->font_type) {
case PANGO:
draw_text_pango(internal, text, x+max_width/2, y, max_width);
break;
case xcb:
fontd_c = xcb_image_text_8_checked(internal->c, strlen(text), internal->window, internal->gc[gcnum], x + max_width/2 - strlen(text)*2 - 30, y, text);
xcb_h_check_cookie(internal, fontd_c, "cant draw text\n");
break;
}

return 0;
}
Expand All @@ -180,6 +294,16 @@ void xcb_h_destroy(int exit_status, void *internal) {
xcb_free_gc(_internal->c, _internal->gc[i]);
}

switch (_internal->font_type) {
case PANGO:
if (_internal->pfont)
pango_font_description_free(_internal->pfont->pango_desc);
break;
case xcb:
if (_internal->font)
xcb_close_font(_internal->c, _internal->font);
}

if (_internal->c)
xcb_disconnect(_internal->c);

Expand Down
Loading

0 comments on commit 4a74cfa

Please sign in to comment.