Use Pango for fonts instead of Xft (which hasn't been ported yet to

XCB) to measure text.
This commit is contained in:
Arnaud Fontaine 2008-03-17 11:38:49 +00:00 committed by Julien Danjou
parent 3a63b7bb52
commit 542a944361
8 changed files with 103 additions and 38 deletions

View File

@ -107,7 +107,7 @@ AWESOME_CFLAGS = -std=gnu99 -pipe \
-Wunused -Winit-self -Wpointer-arith -Wredundant-decls \ -Wunused -Winit-self -Wpointer-arith -Wredundant-decls \
-Wmissing-prototypes -Wmissing-format-attribute -Wmissing-noreturn -Wmissing-prototypes -Wmissing-format-attribute -Wmissing-noreturn
endif 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 bin_PROGRAMS += awesome
awesome_SOURCES = \ awesome_SOURCES = \
@ -140,7 +140,7 @@ awesome_SOURCES = \
ewmh.c ewmh.h ewmh.c ewmh.h
awesome_SOURCES += $(LAYOUTS) awesome_SOURCES += $(LAYOUTS)
awesome_SOURCES += $(WIDGETS) 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 bin_PROGRAMS += awesome-client
awesome_client_SOURCES = \ awesome_client_SOURCES = \
@ -159,7 +159,7 @@ awesome_message_SOURCES = \
common/xscreen.h common/xscreen.c \ common/xscreen.h common/xscreen.c \
awesome-message.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 bin_PROGRAMS += awesome-menu
awesome_menu_SOURCES = \ awesome_menu_SOURCES = \
@ -171,7 +171,7 @@ awesome_menu_SOURCES = \
common/xutil.h common/xutil.c \ common/xutil.h common/xutil.c \
awesome-menu.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_XMLTO
if HAVE_ASCIIDOC if HAVE_ASCIIDOC

2
README
View File

@ -5,7 +5,7 @@ awesome is an extremely fast, small, and dynamic window manager for X.
Requirements Requirements
------------ ------------
In order to build awesome itself, you need header files and libs of: In order to build awesome itself, you need header files and libs of:
- Xlib, Xinerama, Xrandr, Xft - Xlib, Xinerama, Xrandr, Pango
- libconfuse >= 2.6 - libconfuse >= 2.6
- cairo - cairo

View File

@ -524,7 +524,7 @@ Note: when there is no whitespace, quotes are optional.
<boolean> -> "true" or "false" <boolean> -> "true" or "false"
<color> -> #ff9933 (hexadecimal color notation: #red green blue) <color> -> #ff9933 (hexadecimal color notation: #red green blue)
<float> -> 0.3, 0,8 (often values between 0 and 1 are useful) <float> -> 0.3, 0,8 (often values between 0 and 1 are useful)
<font> -> Xft font: mono-10, fixed-12, sans-8, ... <font> -> Pango font: sans 10, sans italic 10, fixed 12, ...
<identifier> -> foobar (choose a name/string) <identifier> -> foobar (choose a name/string)
<image> -> "/home/awesome/pics/icon.png" (path to image) <image> -> "/home/awesome/pics/icon.png" (path to image)
<integer> -> 1, 10, -3 (positive numbers are required mostly) <integer> -> 1, 10, -3 (positive numbers are required mostly)

View File

@ -4,7 +4,7 @@ screen 0
{ {
normal normal
{ {
font = "vera-10" font = "vera 10"
fg = "#eeeeee" fg = "#eeeeee"
bg = "#111111" bg = "#111111"
border = "#6666ff" border = "#6666ff"

View File

@ -20,7 +20,6 @@
*/ */
#include <cairo.h> #include <cairo.h>
#include <cairo-ft.h>
#include <cairo-xlib.h> #include <cairo-xlib.h>
#include <langinfo.h> #include <langinfo.h>
@ -99,6 +98,7 @@ draw_context_new(Display *disp, int phys_screen, int width, int height, Drawable
d->drawable = dw; d->drawable = dw;
d->surface = cairo_xlib_surface_create(disp, dw, d->visual, width, height); d->surface = cairo_xlib_surface_create(disp, dw, d->visual, width, height);
d->cr = cairo_create(d->surface); d->cr = cairo_create(d->surface);
d->layout = pango_cairo_create_layout(d->cr);
return d; return d;
}; };
@ -109,11 +109,70 @@ draw_context_new(Display *disp, int phys_screen, int width, int height, Drawable
void void
draw_context_delete(DrawCtx *ctx) draw_context_delete(DrawCtx *ctx)
{ {
g_object_unref(ctx->layout);
cairo_surface_destroy(ctx->surface); cairo_surface_destroy(ctx->surface);
cairo_destroy(ctx->cr); cairo_destroy(ctx->cr);
p_delete(&ctx); 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 /** Draw text into a draw context
* \param ctx DrawCtx to draw to * \param ctx DrawCtx to draw to
* \param area area to draw to * \param area area to draw to
@ -136,7 +195,6 @@ draw_text(DrawCtx *ctx,
int nw = 0, x, y; int nw = 0, x, y;
ssize_t len, olen; ssize_t len, olen;
char *buf = NULL, *utf8 = NULL; char *buf = NULL, *utf8 = NULL;
cairo_font_face_t *font_face;
draw_rectangle(ctx, area, True, style.bg); draw_rectangle(ctx, area, True, style.bg);
@ -175,12 +233,11 @@ draw_text(DrawCtx *ctx,
buf[len - 3] = '.'; buf[len - 3] = '.';
} }
font_face = cairo_ft_font_face_create_for_pattern(style.font->pattern); pango_layout_set_text(ctx->layout, text, -1);
cairo_set_font_face(ctx->cr, font_face); pango_layout_set_font_description(ctx->layout, style.font->desc);
cairo_set_font_size(ctx->cr, style.font->height);
x = area.x + padding; 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) switch(align)
{ {
@ -201,7 +258,8 @@ draw_text(DrawCtx *ctx,
style.shadow.green / 65535.0, style.shadow.green / 65535.0,
style.shadow.blue / 65535.0); style.shadow.blue / 65535.0);
cairo_move_to(ctx->cr, x + style.shadow_offset, y + style.shadow_offset); 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, cairo_set_source_rgb(ctx->cr,
@ -209,9 +267,8 @@ draw_text(DrawCtx *ctx,
style.fg.green / 65535.0, style.fg.green / 65535.0,
style.fg.blue / 65535.0); style.fg.blue / 65535.0);
cairo_move_to(ctx->cr, x, y); cairo_move_to(ctx->cr, x, y);
cairo_show_text(ctx->cr, buf); pango_cairo_update_layout(ctx->cr, ctx->layout);
pango_cairo_show_layout(ctx->cr, ctx->layout);
cairo_font_face_destroy(font_face);
p_delete(&buf); p_delete(&buf);
} }
@ -597,12 +654,12 @@ draw_rotate(DrawCtx *ctx, int phys_screen, double angle, int tx, int ty)
* \return text width * \return text width
*/ */
unsigned short unsigned short
draw_textwidth(Display *disp, XftFont *font, char *text) draw_textwidth(Display *disp, font_t *font, char *text)
{ {
cairo_surface_t *surface; cairo_surface_t *surface;
cairo_t *cr; cairo_t *cr;
cairo_font_face_t *font_face; PangoLayout *layout;
cairo_text_extents_t te; PangoRectangle ext;
if (!a_strlen(text)) if (!a_strlen(text))
return 0; return 0;
@ -612,15 +669,15 @@ draw_textwidth(Display *disp, XftFont *font, char *text)
DisplayWidth(disp, DefaultScreen(disp)), DisplayWidth(disp, DefaultScreen(disp)),
DisplayHeight(disp, DefaultScreen(disp))); DisplayHeight(disp, DefaultScreen(disp)));
cr = cairo_create(surface); cr = cairo_create(surface);
font_face = cairo_ft_font_face_create_for_pattern(font->pattern); layout = pango_cairo_create_layout(cr);
cairo_set_font_face(cr, font_face); pango_layout_set_text(layout, text, -1);
cairo_set_font_size(cr, font->height); pango_layout_set_font_description(layout, font->desc);
cairo_text_extents(cr, text, &te); pango_layout_get_pixel_extents(layout, NULL, &ext);
g_object_unref(layout);
cairo_destroy(cr); cairo_destroy(cr);
cairo_surface_destroy(surface); 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. /** Transform a string to a Alignment type.
@ -683,7 +740,7 @@ draw_style_init(Display *disp, int phys_screen, cfg_t *cfg,
return; return;
if((buf = cfg_getstr(cfg, "font"))) 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, draw_color_new(disp, phys_screen,
cfg_getstr(cfg, "fg"), &c->fg); cfg_getstr(cfg, "fg"), &c->fg);

View File

@ -27,7 +27,7 @@
#include <confuse.h> #include <confuse.h>
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xft/Xft.h> #include <pango/pangocairo.h>
#include "common/util.h" #include "common/util.h"
#include "common/list.h" #include "common/list.h"
@ -81,6 +81,14 @@ area_get_intersect_area(area_t a, area_t b)
return g; return g;
} }
typedef struct
{
PangoFontDescription *desc;
int height;
int ascent;
int descent;
} font_t;
typedef struct typedef struct
{ {
/** Foreground color */ /** Foreground color */
@ -94,7 +102,7 @@ typedef struct
/** Shadow offset */ /** Shadow offset */
int shadow_offset; int shadow_offset;
/** Font */ /** Font */
XftFont *font; font_t *font;
} style_t; } style_t;
typedef struct typedef struct
@ -108,11 +116,14 @@ typedef struct
int depth; int depth;
cairo_t *cr; cairo_t *cr;
cairo_surface_t *surface; cairo_surface_t *surface;
PangoLayout *layout;
} DrawCtx; } DrawCtx;
DrawCtx *draw_context_new(Display *, int, int, int, Drawable); DrawCtx *draw_context_new(Display *, int, int, int, Drawable);
void draw_context_delete(DrawCtx *); 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_text(DrawCtx *, area_t, Alignment, int, char *, style_t);
void draw_rectangle(DrawCtx *, area_t, Bool, XColor); void draw_rectangle(DrawCtx *, area_t, Bool, XColor);
void draw_rectangle_gradient(DrawCtx *, area_t, Bool, area_t, XColor *, XColor *, 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 *); void draw_image_from_argb_data(DrawCtx *, int, int, int, int, int, unsigned char *);
area_t draw_get_image_size(const char *filename); area_t draw_get_image_size(const char *filename);
Drawable draw_rotate(DrawCtx *, int, double, int, int); 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 *); Alignment draw_get_align(const char *);
Bool draw_color_new(Display *, int, const char *, XColor *); Bool draw_color_new(Display *, int, const char *, XColor *);
void draw_style_init(Display *, int, cfg_t *, style_t *, style_t *); void draw_style_init(Display *, int, cfg_t *, style_t *, style_t *);

View File

@ -106,12 +106,10 @@ AC_DEFINE_UNQUOTED([AWESOME_COMPILE_BY], ["$aw_whoami"], [build user])
# Checks for libraries. # Checks for libraries.
AC_PATH_XTRA AC_PATH_XTRA
PKG_CHECK_MODULES([CAIRO], [cairo],, PKG_CHECK_MODULES([PANGOCAIRO], [pangocairo],,
[AC_MSG_ERROR([awesome requires cairo.])]) [AC_MSG_ERROR([awesome requires pangocairo.])])
PKG_CHECK_MODULES([CONFUSE], [libconfuse >= 2.6],, PKG_CHECK_MODULES([CONFUSE], [libconfuse >= 2.6],,
[AC_MSG_ERROR([awesome requires 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],, PKG_CHECK_MODULES([XINERAMA], [xinerama],,
[AC_MSG_ERROR([awesome requires Xinerama.])]) [AC_MSG_ERROR([awesome requires Xinerama.])])
PKG_CHECK_MODULES([XRANDR], [xrandr],, PKG_CHECK_MODULES([XRANDR], [xrandr],,

View File

@ -65,7 +65,7 @@ static widget_tell_status_t
textbox_tell(Widget *widget, char *property, char *command) textbox_tell(Widget *widget, char *property, char *command)
{ {
Data *d = widget->data; Data *d = widget->data;
XftFont *newfont; font_t *newfont;
if(!a_strcmp(property, "text")) if(!a_strcmp(property, "text"))
{ {
@ -88,11 +88,10 @@ textbox_tell(Widget *widget, char *property, char *command)
return WIDGET_ERROR_FORMAT_COLOR; return WIDGET_ERROR_FORMAT_COLOR;
else if(!a_strcmp(property, "font")) else if(!a_strcmp(property, "font"))
{ {
if((newfont = XftFontOpenName(globalconf.display, if((newfont = draw_font_new(globalconf.display, command)))
get_phys_screen(widget->statusbar->screen), command)))
{ {
if(d->style.font != globalconf.screens[widget->statusbar->screen].styles.normal.font) 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; d->style.font = newfont;
} }
else else