draw.c
changeset 2 a79188fe4a40
child 3 e969f3575b7a
equal deleted inserted replaced
1:f10194d4b76d 2:a79188fe4a40
       
     1 /*
       
     2  * (C)opyright MMIV-MMVI Anselm R. Garbe <garbeam at gmail dot com>
       
     3  * See LICENSE file for license details.
       
     4  */
       
     5 
       
     6 #include <stdio.h>
       
     7 #include <string.h>
       
     8 
       
     9 #include "draw.h"
       
    10 #include "util.h"
       
    11 
       
    12 static void
       
    13 drawborder(Display *dpy, Brush *b)
       
    14 {
       
    15 	XPoint points[5];
       
    16 	XSetLineAttributes(dpy, b->gc, 1, LineSolid, CapButt, JoinMiter);
       
    17 	XSetForeground(dpy, b->gc, b->color.border);
       
    18 	points[0].x = b->rect.x;
       
    19 	points[0].y = b->rect.y;
       
    20 	points[1].x = b->rect.width - 1;
       
    21 	points[1].y = 0;
       
    22 	points[2].x = 0;
       
    23 	points[2].y = b->rect.height - 1;
       
    24 	points[3].x = -(b->rect.width - 1);
       
    25 	points[3].y = 0;
       
    26 	points[4].x = 0;
       
    27 	points[4].y = -(b->rect.height - 1);
       
    28 	XDrawLines(dpy, b->drawable, b->gc, points, 5, CoordModePrevious);
       
    29 }
       
    30 
       
    31 void
       
    32 draw(Display *dpy, Brush *b)
       
    33 {
       
    34 	unsigned int x, y, w, h, len;
       
    35 	static char buf[256];
       
    36 	XGCValues gcv;
       
    37 
       
    38 	XSetForeground(dpy, b->gc, b->color.bg);
       
    39 	XFillRectangles(dpy, b->drawable, b->gc, &b->rect, 1);
       
    40 
       
    41 	if(b->border)
       
    42 		drawborder(dpy, b);
       
    43 
       
    44 	if(!b->text)
       
    45 		return;
       
    46 
       
    47 	len = strlen(b->text);
       
    48 	if(len >= sizeof(buf))
       
    49 		len = sizeof(buf) - 1;
       
    50 	memcpy(buf, b->text, len);
       
    51 	buf[len] = 0;
       
    52 
       
    53 	h = b->font->ascent + b->font->descent;
       
    54 	y = b->rect.y + (b->rect.height / 2) - (h / 2) + b->font->ascent;
       
    55 	x = b->rect.x + (h / 2);
       
    56 
       
    57 	/* shorten text if necessary */
       
    58 	while(len && (w = textwidth_l(b->font, buf, len)) > b->rect.width - h)
       
    59 		buf[--len] = 0;
       
    60 
       
    61 	if(w > b->rect.width)
       
    62 		return; /* too long */
       
    63 
       
    64 	gcv.foreground = b->color.fg;
       
    65 	gcv.background = b->color.bg;
       
    66 	if(b->font->set) {
       
    67 		XChangeGC(dpy, b->gc, GCForeground | GCBackground, &gcv);
       
    68 		XmbDrawImageString(dpy, b->drawable, b->font->set, b->gc,
       
    69 				x, y, buf, len);
       
    70 	}
       
    71 	else {
       
    72 		gcv.font = b->font->xfont->fid;
       
    73 		XChangeGC(dpy, b->gc, GCForeground | GCBackground | GCFont, &gcv);
       
    74 		XDrawImageString(dpy, b->drawable, b->gc, x, y, buf, len);
       
    75 	}
       
    76 }
       
    77 
       
    78 static unsigned long
       
    79 xloadcolor(Display *dpy, Colormap cmap, const char *colstr)
       
    80 {
       
    81 	XColor color;
       
    82 	XAllocNamedColor(dpy, cmap, colstr, &color, &color);
       
    83 	return color.pixel;
       
    84 }
       
    85 
       
    86 void
       
    87 loadcolor(Display *dpy, int screen, Color *c,
       
    88 		const char *bg, const char *fg, const char *border)
       
    89 {
       
    90 	Colormap cmap = DefaultColormap(dpy, screen);
       
    91 	c->bg = xloadcolor(dpy, cmap, bg);
       
    92 	c->fg = xloadcolor(dpy, cmap, fg);
       
    93 	c->border = xloadcolor(dpy, cmap, border);
       
    94 }
       
    95 
       
    96 unsigned int
       
    97 textwidth_l(Fnt *font, char *text, unsigned int len)
       
    98 {
       
    99 	if(font->set) {
       
   100 		XRectangle r;
       
   101 		XmbTextExtents(font->set, text, len, 0, &r);
       
   102 		return r.width;
       
   103 	}
       
   104 	return XTextWidth(font->xfont, text, len);
       
   105 }
       
   106 
       
   107 unsigned int
       
   108 textwidth(Fnt *font, char *text)
       
   109 {
       
   110 	return textwidth_l(font, text, strlen(text));
       
   111 }
       
   112 
       
   113 void
       
   114 loadfont(Display *dpy, Fnt *font, const char *fontstr)
       
   115 {
       
   116 	char **missing, *def;
       
   117 	int n;
       
   118 
       
   119 	missing = 0;
       
   120 	def = "?";
       
   121 	setlocale(LC_ALL, "");
       
   122 	if(font->set)
       
   123 		XFreeFontSet(dpy, font->set);
       
   124 	font->set = XCreateFontSet(dpy, fontstr, &missing, &n, &def);
       
   125 	if(missing) {
       
   126 		while(n--)
       
   127 			fprintf(stderr, "missing fontset: %s\n", missing[n]);
       
   128 		XFreeStringList(missing);
       
   129 		if(font->set) {
       
   130 			XFreeFontSet(dpy, font->set);
       
   131 			font->set = 0;
       
   132 		}
       
   133 	}
       
   134 	if(font->set) {
       
   135 		XFontSetExtents *font_extents;
       
   136 		XFontStruct **xfonts;
       
   137 		char **font_names;
       
   138 		unsigned int i;
       
   139 
       
   140 		font->ascent = font->descent = 0;
       
   141 		font_extents = XExtentsOfFontSet(font->set);
       
   142 		n = XFontsOfFontSet(font->set, &xfonts, &font_names);
       
   143 		for(i = 0, font->ascent = 0, font->descent = 0; i < n; i++) {
       
   144 			if(font->ascent < (*xfonts)->ascent)
       
   145 				font->ascent = (*xfonts)->ascent;
       
   146 			if(font->descent < (*xfonts)->descent)
       
   147 				font->descent = (*xfonts)->descent;
       
   148 			xfonts++;
       
   149 		}
       
   150 	}
       
   151 	else {
       
   152 		if(font->xfont)
       
   153 			XFreeFont(dpy, font->xfont);
       
   154 		font->xfont = 0;
       
   155 		font->xfont = XLoadQueryFont(dpy, fontstr);
       
   156 		if (!font->xfont)
       
   157 			font->xfont = XLoadQueryFont(dpy, "fixed");
       
   158 		if (!font->xfont)
       
   159 			error("error, cannot load 'fixed' font\n");
       
   160 		font->ascent = font->xfont->ascent;
       
   161 		font->descent = font->xfont->descent;
       
   162 	}
       
   163 }