use Cairo to render fonts
This commit is contained in:
parent
9360efb89e
commit
7ecbae334f
59
draw.c
59
draw.c
|
@ -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
2
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
|
||||
|
|
2
event.c
2
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)
|
||||
|
|
10
statusbar.c
10
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
|
||||
|
|
Loading…
Reference in New Issue