diff --git a/Makefile.am b/Makefile.am index 941dd83b..55ccfc22 100644 --- a/Makefile.am +++ b/Makefile.am @@ -107,7 +107,7 @@ AWESOME_CFLAGS = -std=gnu99 -pipe \ -Wunused -Winit-self -Wpointer-arith -Wredundant-decls \ -Wmissing-prototypes -Wmissing-format-attribute -Wmissing-noreturn endif -AM_CPPFLAGS = $(XFT_CFLAGS) $(X_CFLAGS) $(CAIRO_CFLAGS) $(CONFUSE_CFLAGS) $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(AWESOME_CFLAGS) +AM_CPPFLAGS = $(X_CFLAGS) $(PANGOCAIRO_CFLAGS) $(CONFUSE_CFLAGS) $(XRANDR_CFLAGS) $(XINERAMA_CFLAGS) $(AWESOME_CFLAGS) bin_PROGRAMS += awesome awesome_SOURCES = \ @@ -140,7 +140,7 @@ awesome_SOURCES = \ ewmh.c ewmh.h awesome_SOURCES += $(LAYOUTS) awesome_SOURCES += $(WIDGETS) -awesome_LDADD = $(XFT_LIBS) $(X_LIBS) $(CAIRO_LIBS) $(CONFUSE_LIBS) $(XRANDR_LIBS) $(XINERAMA_LIBS) +awesome_LDADD = $(X_LIBS) $(PANGOCAIRO_LIBS) $(CONFUSE_LIBS) $(XRANDR_LIBS) $(XINERAMA_LIBS) bin_PROGRAMS += awesome-client awesome_client_SOURCES = \ @@ -159,7 +159,7 @@ awesome_message_SOURCES = \ common/xscreen.h common/xscreen.c \ awesome-message.c -awesome_message_LDADD = $(XFT_LIBS) $(X_LIBS) $(CAIRO_LIBS) $(CONFUSE_LIBS) $(XINERAMA_LIBS) +awesome_message_LDADD = $(X_LIBS) $(PANGOCAIRO_LIBS) $(CONFUSE_LIBS) $(XINERAMA_LIBS) bin_PROGRAMS += awesome-menu awesome_menu_SOURCES = \ @@ -171,7 +171,7 @@ awesome_menu_SOURCES = \ common/xutil.h common/xutil.c \ awesome-menu.c -awesome_menu_LDADD = $(XFT_LIBS) $(X_LIBS) $(CAIRO_LIBS) $(CONFUSE_LIBS) $(XINERAMA_LIBS) +awesome_menu_LDADD = $(X_LIBS) $(PANGOCAIRO_LIBS) $(CONFUSE_LIBS) $(XINERAMA_LIBS) if HAVE_XMLTO if HAVE_ASCIIDOC diff --git a/README b/README index b50e97c3..08719928 100644 --- a/README +++ b/README @@ -5,7 +5,7 @@ awesome is an extremely fast, small, and dynamic window manager for X. Requirements ------------ In order to build awesome itself, you need header files and libs of: - - Xlib, Xinerama, Xrandr, Xft + - Xlib, Xinerama, Xrandr, Pango - libconfuse >= 2.6 - cairo diff --git a/awesomerc.5.txt b/awesomerc.5.txt index b03c5bdf..9c0dcda8 100644 --- a/awesomerc.5.txt +++ b/awesomerc.5.txt @@ -524,7 +524,7 @@ Note: when there is no whitespace, quotes are optional. -> "true" or "false" -> #ff9933 (hexadecimal color notation: #red green blue) -> 0.3, 0,8 (often values between 0 and 1 are useful) - -> Xft font: mono-10, fixed-12, sans-8, ... + -> Pango font: sans 10, sans italic 10, fixed 12, ... -> foobar (choose a name/string) -> "/home/awesome/pics/icon.png" (path to image) -> 1, 10, -3 (positive numbers are required mostly) diff --git a/awesomerc.in b/awesomerc.in index bfa2d0f6..34136e01 100644 --- a/awesomerc.in +++ b/awesomerc.in @@ -4,7 +4,7 @@ screen 0 { normal { - font = "vera-10" + font = "vera 10" fg = "#eeeeee" bg = "#111111" border = "#6666ff" diff --git a/common/draw.c b/common/draw.c index 275b140c..b8a3d4bb 100644 --- a/common/draw.c +++ b/common/draw.c @@ -20,7 +20,6 @@ */ #include -#include #include #include @@ -99,6 +98,7 @@ draw_context_new(Display *disp, int phys_screen, int width, int height, Drawable d->drawable = dw; d->surface = cairo_xlib_surface_create(disp, dw, d->visual, width, height); d->cr = cairo_create(d->surface); + d->layout = pango_cairo_create_layout(d->cr); return d; }; @@ -109,11 +109,70 @@ draw_context_new(Display *disp, int phys_screen, int width, int height, Drawable void draw_context_delete(DrawCtx *ctx) { + g_object_unref(ctx->layout); cairo_surface_destroy(ctx->surface); cairo_destroy(ctx->cr); p_delete(&ctx); } +/** Create a new Pango font + * \param disp Display ref + * \param fontname Pango fontname (e.g. [FAMILY-LIST] [STYLE-OPTIONS] [SIZE]) + */ +font_t * +draw_font_new(Display *disp, char *fontname) +{ + cairo_surface_t *surface; + cairo_t *cr; + PangoLayout *layout; + font_t *font = p_new(font_t, 1); + PangoContext *context; + PangoFontMetrics *font_metrics; + + /* Create a dummy cairo surface, cairo context and pango layout in + * order to get font informations */ + surface = cairo_xlib_surface_create(disp, + DefaultScreen(disp), + DefaultVisual(disp, DefaultScreen(disp)), + DisplayWidth(disp, DefaultScreen(disp)), + DisplayHeight(disp, DefaultScreen(disp))); + + cr = cairo_create(surface); + layout = pango_cairo_create_layout(cr); + + /* Get the font description used to set text on a PangoLayout */ + font->desc = pango_font_description_from_string(fontname); + pango_layout_set_font_description(layout, font->desc); + + /* Get height */ + pango_layout_get_pixel_size(layout, NULL, &font->height); + + /* Get ascent and descent */ + context = pango_layout_get_context(layout); + font_metrics = pango_context_get_metrics(context, font->desc, NULL); + + /* Values in PangoFontMetrics are given in Pango units */ + font->ascent = PANGO_PIXELS(pango_font_metrics_get_ascent(font_metrics)); + font->descent = PANGO_PIXELS(pango_font_metrics_get_descent(font_metrics)); + + pango_font_metrics_unref(font_metrics); + g_object_unref(layout); + cairo_destroy(cr); + cairo_surface_destroy(surface); + + return font; +} + +/** Delete a font + * \param font font_t to delete + */ +void +draw_font_free(font_t *font) +{ + pango_font_description_free(font->desc); + p_delete(&font); +} + /** Draw text into a draw context * \param ctx DrawCtx to draw to * \param area area to draw to @@ -136,7 +195,6 @@ draw_text(DrawCtx *ctx, int nw = 0, x, y; ssize_t len, olen; char *buf = NULL, *utf8 = NULL; - cairo_font_face_t *font_face; draw_rectangle(ctx, area, True, style.bg); @@ -175,12 +233,11 @@ draw_text(DrawCtx *ctx, buf[len - 3] = '.'; } - font_face = cairo_ft_font_face_create_for_pattern(style.font->pattern); - cairo_set_font_face(ctx->cr, font_face); - cairo_set_font_size(ctx->cr, style.font->height); + pango_layout_set_text(ctx->layout, text, -1); + pango_layout_set_font_description(ctx->layout, style.font->desc); x = area.x + padding; - y = area.y + style.font->ascent + (ctx->height - style.font->height) / 2; + y = area.y + (ctx->height - style.font->height) / 2; switch(align) { @@ -201,7 +258,8 @@ draw_text(DrawCtx *ctx, style.shadow.green / 65535.0, style.shadow.blue / 65535.0); cairo_move_to(ctx->cr, x + style.shadow_offset, y + style.shadow_offset); - cairo_show_text(ctx->cr, buf); + pango_cairo_update_layout(ctx->cr, ctx->layout); + pango_cairo_show_layout(ctx->cr, ctx->layout); } cairo_set_source_rgb(ctx->cr, @@ -209,9 +267,8 @@ draw_text(DrawCtx *ctx, style.fg.green / 65535.0, style.fg.blue / 65535.0); cairo_move_to(ctx->cr, x, y); - cairo_show_text(ctx->cr, buf); - - cairo_font_face_destroy(font_face); + pango_cairo_update_layout(ctx->cr, ctx->layout); + pango_cairo_show_layout(ctx->cr, ctx->layout); p_delete(&buf); } @@ -597,12 +654,12 @@ draw_rotate(DrawCtx *ctx, int phys_screen, double angle, int tx, int ty) * \return text width */ unsigned short -draw_textwidth(Display *disp, XftFont *font, char *text) +draw_textwidth(Display *disp, font_t *font, char *text) { cairo_surface_t *surface; cairo_t *cr; - cairo_font_face_t *font_face; - cairo_text_extents_t te; + PangoLayout *layout; + PangoRectangle ext; if (!a_strlen(text)) return 0; @@ -612,15 +669,15 @@ draw_textwidth(Display *disp, XftFont *font, char *text) DisplayWidth(disp, DefaultScreen(disp)), DisplayHeight(disp, DefaultScreen(disp))); cr = cairo_create(surface); - font_face = cairo_ft_font_face_create_for_pattern(font->pattern); - cairo_set_font_face(cr, font_face); - cairo_set_font_size(cr, font->height); - cairo_text_extents(cr, text, &te); + layout = pango_cairo_create_layout(cr); + pango_layout_set_text(layout, text, -1); + pango_layout_set_font_description(layout, font->desc); + pango_layout_get_pixel_extents(layout, NULL, &ext); + g_object_unref(layout); cairo_destroy(cr); cairo_surface_destroy(surface); - cairo_font_face_destroy(font_face); - return MAX(te.x_advance, te.width); + return ext.width; } /** Transform a string to a Alignment type. @@ -683,7 +740,7 @@ draw_style_init(Display *disp, int phys_screen, cfg_t *cfg, return; if((buf = cfg_getstr(cfg, "font"))) - c->font = XftFontOpenName(disp, phys_screen, buf); + c->font = draw_font_new(disp, buf); draw_color_new(disp, phys_screen, cfg_getstr(cfg, "fg"), &c->fg); diff --git a/common/draw.h b/common/draw.h index d86fea5d..2be2cad9 100644 --- a/common/draw.h +++ b/common/draw.h @@ -27,7 +27,7 @@ #include #include -#include +#include #include "common/util.h" #include "common/list.h" @@ -81,6 +81,14 @@ area_get_intersect_area(area_t a, area_t b) return g; } +typedef struct +{ + PangoFontDescription *desc; + int height; + int ascent; + int descent; +} font_t; + typedef struct { /** Foreground color */ @@ -94,7 +102,7 @@ typedef struct /** Shadow offset */ int shadow_offset; /** Font */ - XftFont *font; + font_t *font; } style_t; typedef struct @@ -108,11 +116,14 @@ typedef struct int depth; cairo_t *cr; cairo_surface_t *surface; + PangoLayout *layout; } DrawCtx; DrawCtx *draw_context_new(Display *, int, int, int, Drawable); void draw_context_delete(DrawCtx *); +font_t *draw_font_new(Display *disp, char *fontname); +void draw_font_free(font_t *); void draw_text(DrawCtx *, area_t, Alignment, int, char *, style_t); void draw_rectangle(DrawCtx *, area_t, Bool, XColor); void draw_rectangle_gradient(DrawCtx *, area_t, Bool, area_t, XColor *, XColor *, XColor *); @@ -125,7 +136,7 @@ void draw_image(DrawCtx *, int, int, int, const char *); void draw_image_from_argb_data(DrawCtx *, int, int, int, int, int, unsigned char *); area_t draw_get_image_size(const char *filename); Drawable draw_rotate(DrawCtx *, int, double, int, int); -unsigned short draw_textwidth(Display *, XftFont *, char *); +unsigned short draw_textwidth(Display *, font_t *, char *); Alignment draw_get_align(const char *); Bool draw_color_new(Display *, int, const char *, XColor *); void draw_style_init(Display *, int, cfg_t *, style_t *, style_t *); diff --git a/configure.ac b/configure.ac index 06e60061..94ea525b 100644 --- a/configure.ac +++ b/configure.ac @@ -106,12 +106,10 @@ AC_DEFINE_UNQUOTED([AWESOME_COMPILE_BY], ["$aw_whoami"], [build user]) # Checks for libraries. AC_PATH_XTRA -PKG_CHECK_MODULES([CAIRO], [cairo],, - [AC_MSG_ERROR([awesome requires cairo.])]) +PKG_CHECK_MODULES([PANGOCAIRO], [pangocairo],, + [AC_MSG_ERROR([awesome requires pangocairo.])]) PKG_CHECK_MODULES([CONFUSE], [libconfuse >= 2.6],, [AC_MSG_ERROR([awesome requires libconfuse >= 2.6.])]) -PKG_CHECK_MODULES([XFT], [xft],, - [AC_MSG_ERROR([awesome requires xft.])]) PKG_CHECK_MODULES([XINERAMA], [xinerama],, [AC_MSG_ERROR([awesome requires Xinerama.])]) PKG_CHECK_MODULES([XRANDR], [xrandr],, diff --git a/widgets/textbox.c b/widgets/textbox.c index 5a85a553..87652cfb 100644 --- a/widgets/textbox.c +++ b/widgets/textbox.c @@ -65,7 +65,7 @@ static widget_tell_status_t textbox_tell(Widget *widget, char *property, char *command) { Data *d = widget->data; - XftFont *newfont; + font_t *newfont; if(!a_strcmp(property, "text")) { @@ -88,11 +88,10 @@ textbox_tell(Widget *widget, char *property, char *command) return WIDGET_ERROR_FORMAT_COLOR; else if(!a_strcmp(property, "font")) { - if((newfont = XftFontOpenName(globalconf.display, - get_phys_screen(widget->statusbar->screen), command))) + if((newfont = draw_font_new(globalconf.display, command))) { if(d->style.font != globalconf.screens[widget->statusbar->screen].styles.normal.font) - XftFontClose(globalconf.display, d->style.font); + draw_font_free(d->style.font); d->style.font = newfont; } else