| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170 | /* * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com> * See LICENSE file for license details. */#include <stdio.h>#include <string.h>#include "draw.h"#include "util.h"static voiddrawborder(Display *dpy, Brush *b){	XPoint points[5];	XSetLineAttributes(dpy, b->gc, 1, LineSolid, CapButt, JoinMiter);	XSetForeground(dpy, b->gc, b->border);	points[0].x = b->rect.x;	points[0].y = b->rect.y;	points[1].x = b->rect.width - 1;	points[1].y = 0;	points[2].x = 0;	points[2].y = b->rect.height - 1;	points[3].x = -(b->rect.width - 1);	points[3].y = 0;	points[4].x = 0;	points[4].y = -(b->rect.height - 1);	XDrawLines(dpy, b->drawable, b->gc, points, 5, CoordModePrevious);}voiddraw(Display *dpy, Brush *b, Bool border, const char *text){	unsigned int x, y, w, h, len;	static char buf[256];	XGCValues gcv;	XSetForeground(dpy, b->gc, b->bg);	XFillRectangles(dpy, b->drawable, b->gc, &b->rect, 1);	if(border)		drawborder(dpy, b);	if(!text)		return;	len = strlen(text);	if(len >= sizeof(buf))		len = sizeof(buf) - 1;	memcpy(buf, text, len);	buf[len] = 0;	h = b->font.ascent + b->font.descent;	y = b->rect.y + (b->rect.height / 2) - (h / 2) + b->font.ascent;	x = b->rect.x + (h / 2);	/* shorten text if necessary */	while(len && (w = textwidth_l(&b->font, buf, len)) > b->rect.width - h)		buf[--len] = 0;	if(w > b->rect.width)		return; /* too long */	gcv.foreground = b->fg;	gcv.background = b->bg;	if(b->font.set) {		XChangeGC(dpy, b->gc, GCForeground | GCBackground, &gcv);		XmbDrawImageString(dpy, b->drawable, b->font.set, b->gc,				x, y, buf, len);	}	else {		gcv.font = b->font.xfont->fid;		XChangeGC(dpy, b->gc, GCForeground | GCBackground | GCFont, &gcv);		XDrawImageString(dpy, b->drawable, b->gc, x, y, buf, len);	}}static unsigned longxloadcolors(Display *dpy, Colormap cmap, const char *colstr){	XColor color;	XAllocNamedColor(dpy, cmap, colstr, &color, &color);	return color.pixel;}voidloadcolors(Display *dpy, int screen, Brush *b,		const char *bg, const char *fg, const char *border){	Colormap cmap = DefaultColormap(dpy, screen);	b->bg = xloadcolors(dpy, cmap, bg);	b->fg = xloadcolors(dpy, cmap, fg);	b->border = xloadcolors(dpy, cmap, border);}unsigned inttextwidth_l(Fnt *font, char *text, unsigned int len){	if(font->set) {		XRectangle r;		XmbTextExtents(font->set, text, len, 0, &r);		return r.width;	}	return XTextWidth(font->xfont, text, len);}unsigned inttextwidth(Fnt *font, char *text){	return textwidth_l(font, text, strlen(text));}voidloadfont(Display *dpy, Fnt *font, const char *fontstr){	char **missing, *def;	int n;	missing = 0;	def = "?";	setlocale(LC_ALL, "");	if(font->set)		XFreeFontSet(dpy, font->set);	font->set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);	if(missing) {		while(n--)			fprintf(stderr, "missing fontset: %s\n", missing[n]);		XFreeStringList(missing);		if(font->set) {			XFreeFontSet(dpy, font->set);			font->set = 0;		}	}	if(font->set) {		XFontSetExtents *font_extents;		XFontStruct **xfonts;		char **font_names;		unsigned int i;		font->ascent = font->descent = 0;		font_extents = XExtentsOfFontSet(font->set);		n = XFontsOfFontSet(font->set, &xfonts, &font_names);		for(i = 0, font->ascent = 0, font->descent = 0; i < n; i++) {			if(font->ascent < (*xfonts)->ascent)				font->ascent = (*xfonts)->ascent;			if(font->descent < (*xfonts)->descent)				font->descent = (*xfonts)->descent;			xfonts++;		}	}	else {		if(font->xfont)			XFreeFont(dpy, font->xfont);		font->xfont = 0;		font->xfont = XLoadQueryFont(dpy, fontstr);		if (!font->xfont)			font->xfont = XLoadQueryFont(dpy, "fixed");		if (!font->xfont)			error("error, cannot load 'fixed' font\n");		font->ascent = font->xfont->ascent;		font->descent = font->xfont->descent;	}	font->height = font->ascent + font->descent;}unsigned intlabelheight(Fnt *font){	return font->height + 4;}
 |