mirror of
https://github.com/0intro/wmii
synced 2024-11-22 05:42:05 +03:00
Add Xft support.
This commit is contained in:
parent
3dd6ee6658
commit
65f7040f2c
148
cmd/wmii/x11.c
148
cmd/wmii/x11.c
@ -26,6 +26,8 @@ static MapEnt* abucket[137];
|
||||
static int errorhandler(Display*, XErrorEvent*);
|
||||
static int (*xlib_errorhandler) (Display*, XErrorEvent*);
|
||||
|
||||
static XftColor* xftcolor(ulong);
|
||||
|
||||
|
||||
/* Rectangles/Points */
|
||||
XRectangle
|
||||
@ -249,11 +251,20 @@ freeimage(Image *img) {
|
||||
|
||||
assert(img->type == WImage);
|
||||
|
||||
if(img->xft)
|
||||
XftDrawDestroy(img->xft);
|
||||
XFreePixmap(display, img->w);
|
||||
XFreeGC(display, img->gc);
|
||||
free(img);
|
||||
}
|
||||
|
||||
static XftDraw*
|
||||
xftdrawable(Image *img) {
|
||||
if(img->xft == nil)
|
||||
img->xft = XftDrawCreate(display, img->w, scr.visual, scr.colormap);
|
||||
return img->xft;
|
||||
}
|
||||
|
||||
/* Windows */
|
||||
Window*
|
||||
createwindow_visual(Window *parent, Rectangle r,
|
||||
@ -309,6 +320,8 @@ void
|
||||
destroywindow(Window *w) {
|
||||
assert(w->type == WWindow);
|
||||
sethandler(w, nil);
|
||||
if(w->xft)
|
||||
XftDrawDestroy(w->xft);
|
||||
if(w->gc)
|
||||
XFreeGC(display, w->gc);
|
||||
XDestroyWindow(display, w->w);
|
||||
@ -561,16 +574,25 @@ drawstring(Image *dst, Font *font,
|
||||
}
|
||||
|
||||
setgccol(dst, col);
|
||||
if(font->set)
|
||||
switch(font->type) {
|
||||
case FFontSet:
|
||||
Xutf8DrawString(display, dst->w,
|
||||
font->set, dst->gc,
|
||||
font->font.set, dst->gc,
|
||||
x, y,
|
||||
buf, len);
|
||||
else {
|
||||
XSetFont(display, dst->gc, font->xfont->fid);
|
||||
break;
|
||||
case FXft:
|
||||
XftDrawStringUtf8(xftdrawable(dst), xftcolor(col),
|
||||
font->font.xft,
|
||||
x, y, (uchar*)buf, len);
|
||||
break;
|
||||
case FX11:
|
||||
XSetFont(display, dst->gc, font->font.x11->fid);
|
||||
XDrawString(display, dst->w, dst->gc,
|
||||
x, y,
|
||||
buf, len);
|
||||
x, y, buf, len);
|
||||
break;
|
||||
default:
|
||||
die("Invalid font type.");
|
||||
}
|
||||
|
||||
done:
|
||||
@ -617,55 +639,98 @@ loadcolor(CTuple *c, char *str) {
|
||||
&& namedcolor(buf+16, &c->border);
|
||||
}
|
||||
|
||||
static XftColor*
|
||||
xftcolor(ulong col) {
|
||||
XftColor *c;
|
||||
|
||||
c = emallocz(sizeof *c);
|
||||
*c = (XftColor) {
|
||||
col, {
|
||||
(col>>8) & 0xff00,
|
||||
(col>>0) & 0xff00,
|
||||
(col<<8) & 0xff00,
|
||||
(col>>16) & 0xff00,
|
||||
}
|
||||
};
|
||||
return freelater(c);
|
||||
}
|
||||
|
||||
/* Fonts */
|
||||
Font*
|
||||
loadfont(char *name) {
|
||||
Biobuf *b;
|
||||
Font *f;
|
||||
XFontStruct **xfonts;
|
||||
char **missing, **font_names;
|
||||
Biobuf *b;
|
||||
Font *f;
|
||||
int n, i;
|
||||
|
||||
missing = nil;
|
||||
f = emallocz(sizeof *f);
|
||||
f->name = estrdup(name);
|
||||
f->set = XCreateFontSet(display, name, &missing, &n, nil);
|
||||
if(missing) {
|
||||
b = Bfdopen(dup(2), O_WRONLY);
|
||||
Bprint(b, "%s: note: missing fontset%s for '%s':", argv0,
|
||||
(n > 1 ? "s" : ""), name);
|
||||
for(i = 0; i < n; i++)
|
||||
Bprint(b, "%s %s", (i ? "," : ""), missing[i]);
|
||||
Bprint(b, "\n");
|
||||
Bterm(b);
|
||||
freestringlist(missing);
|
||||
}
|
||||
if(!strncmp(f->name, "xft:", 4)) {
|
||||
f->type = FXft;
|
||||
|
||||
if(f->set) {
|
||||
XFontsOfFontSet(f->set, &xfonts, &font_names);
|
||||
f->ascent = xfonts[0]->ascent;
|
||||
f->descent = xfonts[0]->descent;
|
||||
f->font.xft = XftFontOpenXlfd(display, scr.screen, f->name + 4);
|
||||
if(!f->font.xft)
|
||||
f->font.xft = XftFontOpenName(display, scr.screen, f->name + 4);
|
||||
if(!f->font.xft)
|
||||
goto error;
|
||||
|
||||
f->ascent = f->font.xft->ascent;
|
||||
f->descent = f->font.xft->descent;
|
||||
}else {
|
||||
f->xfont = XLoadQueryFont(display, name);
|
||||
if(!f->xfont) {
|
||||
fprint(2, "%s: cannot load font: %s\n", argv0, name);
|
||||
freefont(f);
|
||||
return nil;
|
||||
f->font.set = XCreateFontSet(display, name, &missing, &n, nil);
|
||||
if(missing) {
|
||||
b = Bfdopen(dup(2), O_WRONLY);
|
||||
Bprint(b, "%s: note: missing fontset%s for '%s':", argv0,
|
||||
(n > 1 ? "s" : ""), name);
|
||||
for(i = 0; i < n; i++)
|
||||
Bprint(b, "%s %s", (i ? "," : ""), missing[i]);
|
||||
Bprint(b, "\n");
|
||||
Bterm(b);
|
||||
freestringlist(missing);
|
||||
}
|
||||
|
||||
f->ascent = f->xfont->ascent;
|
||||
f->descent = f->xfont->descent;
|
||||
if(f->font.set) {
|
||||
f->type = FFontSet;
|
||||
XFontsOfFontSet(f->font.set, &xfonts, &font_names);
|
||||
f->ascent = xfonts[0]->ascent;
|
||||
f->descent = xfonts[0]->descent;
|
||||
}else {
|
||||
f->type = FX11;
|
||||
f->font.x11 = XLoadQueryFont(display, name);
|
||||
if(!f->font.x11)
|
||||
goto error;
|
||||
|
||||
f->ascent = f->font.x11->ascent;
|
||||
f->descent = f->font.x11->descent;
|
||||
}
|
||||
}
|
||||
f->height = f->ascent + f->descent;
|
||||
return f;
|
||||
|
||||
error:
|
||||
fprint(2, "%s: cannot load font: %s\n", argv0, name);
|
||||
f->type = 0;
|
||||
freefont(f);
|
||||
return nil;
|
||||
}
|
||||
|
||||
void
|
||||
freefont(Font *f) {
|
||||
if(f->set)
|
||||
XFreeFontSet(display, f->set);
|
||||
if(f->xfont)
|
||||
XFreeFont(display, f->xfont);
|
||||
switch(f->type) {
|
||||
case FFontSet:
|
||||
XFreeFontSet(display, f->font.set);
|
||||
break;
|
||||
case FXft:
|
||||
XftFontClose(display, f->font.xft);
|
||||
break;
|
||||
case FX11:
|
||||
XFreeFont(display, f->font.x11);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(f->name);
|
||||
free(f);
|
||||
}
|
||||
@ -673,12 +738,21 @@ freefont(Font *f) {
|
||||
uint
|
||||
textwidth_l(Font *font, char *text, uint len) {
|
||||
XRectangle r;
|
||||
XGlyphInfo i;
|
||||
|
||||
if(font->set) {
|
||||
Xutf8TextExtents(font->set, text, len, nil, &r);
|
||||
switch(font->type) {
|
||||
case FFontSet:
|
||||
Xutf8TextExtents(font->font.set, text, len, nil, &r);
|
||||
return r.width;
|
||||
case FXft:
|
||||
XftTextExtentsUtf8(display, font->font.xft, (uchar*)text, len, &i);
|
||||
return i.width;
|
||||
case FX11:
|
||||
return XTextWidth(font->font.x11, text, len);
|
||||
default:
|
||||
die("Invalid font type");
|
||||
return 0; /* shut up ken */
|
||||
}
|
||||
return XTextWidth(font->xfont, text, len);
|
||||
}
|
||||
|
||||
uint
|
||||
|
@ -33,8 +33,8 @@ P9PATHS = ${PLAN9}:"'$${HOME}/plan9'":/usr/local/plan9:/usr/local/9:/opt/plan9:/
|
||||
# are painfully slow, and should be avoided.
|
||||
#BINSH = /bin/ash
|
||||
|
||||
INCX11 = -I/usr/X11R6/include
|
||||
LIBX11 = -L/usr/X11R6/lib -lX11
|
||||
INCX11 = $$(pkg-config --cflags xft)
|
||||
LIBX11 = $$(pkg-config --libs xft)
|
||||
LIBICONV = # Leave blank if your libc includes iconv (glibc does)
|
||||
LIBIXP = $(LIBDIR)/libixp.a
|
||||
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define Screen XScreen
|
||||
#include <X11/Xlib.h>
|
||||
#include <X11/Xutil.h>
|
||||
#include <X11/Xft/Xft.h>
|
||||
#ifdef _X11_VISIBLE
|
||||
# include <X11/Xatom.h>
|
||||
# include <X11/extensions/shape.h>
|
||||
@ -27,12 +28,20 @@ enum Align {
|
||||
Center = NEast | SWest,
|
||||
};
|
||||
|
||||
enum FontType {
|
||||
FX11 = 1,
|
||||
FFontSet,
|
||||
FXft,
|
||||
};
|
||||
|
||||
enum WindowType {
|
||||
WWindow,
|
||||
WImage,
|
||||
};
|
||||
|
||||
typedef enum Align Align;
|
||||
typedef enum FontType FontType;
|
||||
typedef enum WindowType WindowType;
|
||||
|
||||
typedef XSetWindowAttributes WinAttr;
|
||||
|
||||
@ -76,12 +85,16 @@ struct Ewmh {
|
||||
};
|
||||
|
||||
struct Font {
|
||||
XFontStruct *xfont;
|
||||
XFontSet set;
|
||||
int ascent;
|
||||
int descent;
|
||||
uint height;
|
||||
char *name;
|
||||
int type;
|
||||
union {
|
||||
XFontStruct* x11;
|
||||
XFontSet set;
|
||||
XftFont* xft;
|
||||
} font;
|
||||
int ascent;
|
||||
int descent;
|
||||
uint height;
|
||||
char* name;
|
||||
};
|
||||
|
||||
struct Handlers {
|
||||
@ -122,6 +135,7 @@ struct Window {
|
||||
int type;
|
||||
XID w;
|
||||
GC gc;
|
||||
XftDraw* xft;
|
||||
Rectangle r;
|
||||
int border;
|
||||
Window* parent;
|
||||
|
Loading…
Reference in New Issue
Block a user