use Cairo to render fonts

This commit is contained in:
Nikos Ntarmos 2007-10-16 02:20:03 +03:00 committed by Julien Danjou
parent 9360efb89e
commit 7ecbae334f
4 changed files with 46 additions and 27 deletions

59
draw.c
View file

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

2
draw.h
View file

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

View file

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

View file

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