diff options
Diffstat (limited to 'xft.go')
| -rw-r--r-- | xft.go | 131 |
1 files changed, 131 insertions, 0 deletions
@@ -0,0 +1,131 @@ +package main + +/* +#cgo pkg-config: xft xrender x11 fontconfig +#include <stdlib.h> +#include <X11/Xlib.h> +#include <X11/extensions/Xrender.h> +#include <X11/Xft/Xft.h> + +static Display *_dpy; +static XftDraw *_drw; +static XftFont *_ft; +static Visual *_vis; +static Colormap _cmap; +static XftColor _fg; +static int _scr; + +static int wm_xft_init(const char *pattern) +{ + int event_basep, error_basep; + _dpy = XOpenDisplay(NULL); + if (!_dpy) + return -1; + if (!XRenderQueryExtension(_dpy, &event_basep, &error_basep)) + return -3; + XftInit(NULL); + _scr = DefaultScreen(_dpy); + _vis = DefaultVisual(_dpy, _scr); + _cmap = DefaultColormap(_dpy, _scr); + _ft = XftFontOpenName(_dpy, _scr, pattern); + if (!_ft) + return -2; + return 0; +} + +static void wm_xft_setfg(unsigned int px) +{ + XRenderColor c; + c.red = ((px >> 16) & 0xff) << 8; + c.green = ((px >> 8) & 0xff) << 8; + c.blue = (px & 0xff) << 8; + c.alpha = 0xffff; + XftColorAllocValue(_dpy, _vis, _cmap, &c, &_fg); +} + +static int wm_xft_width(const char *s, int n) +{ + XGlyphInfo gi; + XftTextExtentsUtf8(_dpy, _ft, (const FcChar8 *)s, n, &gi); + return gi.xOff; +} + +static void wm_xft_draw(unsigned int win, int x, int y, + const char *s, int n, unsigned int fg) +{ + if (!_dpy || !_ft || !win) + return; + if (!_drw) + _drw = XftDrawCreate(_dpy, (Drawable)win, _vis, _cmap); + if (!_drw) + return; + XftDrawChange(_drw, (Drawable)win); + wm_xft_setfg(fg); + XftDrawStringUtf8(_drw, &_fg, _ft, x, y, (const FcChar8 *)s, n); + XFlush(_dpy); +} + +static int wm_xft_ascent(void) { return _ft ? _ft->ascent : 0; } +static int wm_xft_descent(void) { return _ft ? _ft->descent : 0; } +*/ +import "C" + +import ( + "unsafe" + + "github.com/BurntSushi/xgb/xproto" +) + +var xftOK bool + +func xftInit(pattern string) error { + cp := C.CString(pattern) + defer C.free(unsafe.Pointer(cp)) + + switch rc := int(C.wm_xft_init(cp)); rc { + case 0: + xftOK = true + return nil + case -1: + return errXftNoDisplay + case -2: + return errXftNoFont + default: + return errXftNoRender + } +} + +var ( + errXftNoDisplay = errXft("xft: cannot open display") + errXftNoFont = errXft("xft: cannot load font pattern") + errXftNoRender = errXft("xft: no RENDER extension") +) + +type errXft string + +func (e errXft) Error() string { return string(e) } + +func xftTextWidth(s string) int { + if !xftOK { + return 0 + } + cs := C.CString(s) + defer C.free(unsafe.Pointer(cs)) + return int(C.wm_xft_width(cs, C.int(len(s)))) +} + +func xftDrawText(win xproto.Window, x, baseline int, s string, fg uint32) { + if !xftOK || win == 0 { + return + } + cs := C.CString(s) + defer C.free(unsafe.Pointer(cs)) + C.wm_xft_draw(C.uint(win), C.int(x), C.int(baseline), cs, C.int(len(s)), C.uint(fg)) +} + +func xftMetrics() (ascent, descent int) { + if !xftOK { + return 0, 0 + } + return int(C.wm_xft_ascent()), int(C.wm_xft_descent()) +} |