From 7ecbae334fdca117c20dedc8361d5b1f386ea569 Mon Sep 17 00:00:00 2001 From: Nikos Ntarmos Date: Tue, 16 Oct 2007 02:20:03 +0300 Subject: [PATCH] use Cairo to render fonts --- draw.c | 59 ++++++++++++++++++++++++++++++++++++----------------- draw.h | 2 +- event.c | 2 +- statusbar.c | 10 ++++----- 4 files changed, 46 insertions(+), 27 deletions(-) diff --git a/draw.c b/draw.c index f03831528..5faa421d3 100644 --- a/draw.c +++ b/draw.c @@ -20,6 +20,7 @@ */ #include +#include #include #include #include "layout.h" @@ -32,19 +33,27 @@ drawtext(Display *disp, int screen, int x, int y, int w, int h, Drawable drawabl int nw = 0; static char buf[256]; size_t len, olen; - XRenderColor xrcolor; - XftColor xftcolor; - XftDraw *xftdrawable; + cairo_font_face_t *font_face; + cairo_surface_t *surface; + cairo_t *cr; drawrectangle(disp, screen, x, y, w, h, drawable, dw, dh, True, color[ColBG]); if(!a_strlen(text)) return; + + surface = cairo_xlib_surface_create(disp, drawable, DefaultVisual(disp, screen), dw, dh); + cr = cairo_create(surface); + font_face = (cairo_font_face_t *)cairo_ft_font_face_create_for_pattern(font->pattern); + cairo_set_font_face(cr, font_face); + cairo_set_font_size(cr, font->height); + cairo_set_source_rgb(cr, color[ColFG].red / 65535.0, color[ColFG].green / 65535.0, color[ColFG].blue / 65535.0); + olen = len = a_strlen(text); if(len >= sizeof(buf)) len = sizeof(buf) - 1; memcpy(buf, text, len); buf[len] = 0; - while(len && (nw = textwidth(disp, font, buf, len)) > w - font->height) + while(len && (nw = textwidth(disp, font, buf)) > w) buf[--len] = 0; if(nw > w) return; /* too long */ @@ -57,17 +66,13 @@ drawtext(Display *disp, int screen, int x, int y, int w, int h, Drawable drawabl if(len > 3) buf[len - 3] = '.'; } - xrcolor.red = color[ColFG].red; - xrcolor.green = color[ColFG].green; - xrcolor.blue = color[ColFG].blue; - XftColorAllocValue(disp, DefaultVisual(disp, screen), DefaultColormap(disp, screen), &xrcolor, &xftcolor); - xftdrawable = XftDrawCreate(disp, drawable, DefaultVisual(disp, screen), DefaultColormap(disp, screen)); - XftDrawStringUtf8(xftdrawable, &xftcolor, font, - x + (font->height / 2), - y + (h / 2) - (font->height / 2) + font->ascent, - (XftChar8 *) buf, len); - XftColorFree(disp, DefaultVisual(disp, screen), DefaultColormap(disp, screen), &xftcolor); - XftDrawDestroy(xftdrawable); + + cairo_move_to(cr, x + font->height / 2, y + font->height); + cairo_show_text(cr, buf); + + cairo_font_face_destroy(font_face); + cairo_destroy(cr); + cairo_surface_destroy(surface); } void @@ -121,11 +126,27 @@ drawcircle(Display *disp, int screen, int x, int y, int r, Drawable drawable, in } unsigned short -textwidth(Display *disp, XftFont *font, char *text, ssize_t len) +textwidth(Display *disp, XftFont *font, char *text) { - XGlyphInfo gi; - XftTextExtentsUtf8(disp, font, (FcChar8 *) text, len, &gi); - return gi.width; + cairo_surface_t *surface; + cairo_t *cr; + cairo_font_face_t *font_face; + cairo_text_extents_t te; + + surface = cairo_xlib_surface_create(disp, DefaultScreen(disp), + DefaultVisual(disp, DefaultScreen(disp)), + 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); + cairo_destroy(cr); + cairo_surface_destroy(surface); + cairo_font_face_destroy(font_face); + + return MAX(te.x_advance, te.width) + font->height; } // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 diff --git a/draw.h b/draw.h index d0bf4739e..333b207d2 100644 --- a/draw.h +++ b/draw.h @@ -27,6 +27,6 @@ void drawtext(Display *, int, int, int, int, int, Drawable, int, int, XftFont *, const char *, XColor []); void drawrectangle(Display *, int, int, int, int, int, Drawable, int, int, Bool, XColor); void drawcircle(Display *, int, int, int, int, Drawable, int, int, Bool, XColor); -inline unsigned short textwidth(Display *, XftFont *, char *, ssize_t); +unsigned short textwidth(Display *, XftFont *, char *); #endif // vim: filetype=c:expandtab:shiftwidth=4:tabstop=8:softtabstop=4:encoding=utf-8:textwidth=99 diff --git a/event.c b/event.c index 5ebc72d29..d4964704b 100644 --- a/event.c +++ b/event.c @@ -159,7 +159,7 @@ handle_event_buttonpress(XEvent * e, awesome_config *awesomeconf) { for(i = 0; i < awesomeconf[screen].ntags; i++) { - x += textwidth(e->xany.display, awesomeconf[screen].font, awesomeconf[screen].tags[i].name, a_strlen(awesomeconf[screen].tags[i].name)) + awesomeconf[screen].font->height; + x += textwidth(e->xany.display, awesomeconf[screen].font, awesomeconf[screen].tags[i].name); if(ev->x < x) { if(ev->button == Button1) diff --git a/statusbar.c b/statusbar.c index ff889b74a..129878ff7 100644 --- a/statusbar.c +++ b/statusbar.c @@ -53,8 +53,7 @@ drawstatusbar(awesome_config * awesomeconf) for(i = 0; i < awesomeconf->ntags; i++) { w = textwidth(awesomeconf->display, awesomeconf->font, - awesomeconf->tags[i].name, a_strlen(awesomeconf->tags[i].name)) - + awesomeconf->font->height; + awesomeconf->tags[i].name); if(awesomeconf->tags[i].selected) { drawtext(awesomeconf->display, awesomeconf->phys_screen, @@ -108,8 +107,7 @@ drawstatusbar(awesome_config * awesomeconf) awesomeconf->font, awesomeconf->current_layout->symbol, awesomeconf->colors_normal); z = x + awesomeconf->statusbar.txtlayoutwidth; - w = textwidth(awesomeconf->display, awesomeconf->font, awesomeconf->statustext, a_strlen(awesomeconf->statustext)) - + awesomeconf->font->height; + w = textwidth(awesomeconf->display, awesomeconf->font, awesomeconf->statustext); x = awesomeconf->statusbar.width - w; if(x < z) { @@ -184,7 +182,7 @@ initstatusbar(Display *disp, int screen, Statusbar *statusbar, Cursor cursor, Xf ScreenInfo *si = get_screen_info(disp, screen, NULL); statusbar->width = si[screen].width; - statusbar->height = font->height + 2; + statusbar->height = font->height * 1.5; p_delete(&si); statusbar->screen = screen; @@ -212,7 +210,7 @@ initstatusbar(Display *disp, int screen, Statusbar *statusbar, Cursor cursor, Xf for(i = 0; i < nlayouts; i++) statusbar->txtlayoutwidth = MAX(statusbar->txtlayoutwidth, - (font->height + textwidth(disp, font, layouts[i].symbol, a_strlen(layouts[i].symbol)))); + (textwidth(disp, font, layouts[i].symbol))); } void