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 \
-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

2
README
View File

@ -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

View File

@ -524,7 +524,7 @@ Note: when there is no whitespace, quotes are optional.
<boolean> -> "true" or "false"
<color> -> #ff9933 (hexadecimal color notation: #red green blue)
<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)
<image> -> "/home/awesome/pics/icon.png" (path to image)
<integer> -> 1, 10, -3 (positive numbers are required mostly)

View File

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

View File

@ -20,7 +20,6 @@
*/
#include <cairo.h>
#include <cairo-ft.h>
#include <cairo-xlib.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->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);

View File

@ -27,7 +27,7 @@
#include <confuse.h>
#include <X11/Xlib.h>
#include <X11/Xft/Xft.h>
#include <pango/pangocairo.h>
#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 *);

View File

@ -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],,

View File

@ -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