Lines 9-17
Link Here
|
9 |
|
9 |
|
10 |
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
10 |
#define MAX(a, b) ((a) > (b) ? (a) : (b)) |
11 |
#define MIN(a, b) ((a) < (b) ? (a) : (b)) |
11 |
#define MIN(a, b) ((a) < (b) ? (a) : (b)) |
12 |
#define DEFAULTFN "fixed" |
|
|
13 |
|
14 |
static Bool loadfont(DC *dc, const char *fontstr); |
15 |
|
12 |
|
16 |
void |
13 |
void |
17 |
drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { |
14 |
drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsigned long color) { |
Lines 23-29
drawrect(DC *dc, int x, int y, unsigned int w, unsigned int h, Bool fill, unsign
Link Here
|
23 |
} |
20 |
} |
24 |
|
21 |
|
25 |
void |
22 |
void |
26 |
drawtext(DC *dc, const char *text, unsigned long col[ColLast]) { |
23 |
drawtext(DC *dc, const char *text, ColorSet *col) { |
27 |
char buf[BUFSIZ]; |
24 |
char buf[BUFSIZ]; |
28 |
size_t mn, n = strlen(text); |
25 |
size_t mn, n = strlen(text); |
29 |
|
26 |
|
Lines 35-53
drawtext(DC *dc, const char *text, unsigned long col[ColLast]) {
Link Here
|
35 |
if(mn < n) |
32 |
if(mn < n) |
36 |
for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); |
33 |
for(n = MAX(mn-3, 0); n < mn; buf[n++] = '.'); |
37 |
|
34 |
|
38 |
drawrect(dc, 0, 0, dc->w, dc->h, True, BG(dc, col)); |
35 |
drawrect(dc, 0, 0, dc->w, dc->h, True, col->BG); |
39 |
drawtextn(dc, buf, mn, col); |
36 |
drawtextn(dc, buf, mn, col); |
40 |
} |
37 |
} |
41 |
|
38 |
|
42 |
void |
39 |
void |
43 |
drawtextn(DC *dc, const char *text, size_t n, unsigned long col[ColLast]) { |
40 |
drawtextn(DC *dc, const char *text, size_t n, ColorSet *col) { |
44 |
int x = dc->x + dc->font.height/2; |
41 |
int x = dc->x + dc->font.height/2; |
45 |
int y = dc->y + dc->font.ascent+1; |
42 |
int y = dc->y + dc->font.ascent+1; |
46 |
|
43 |
|
47 |
XSetForeground(dc->dpy, dc->gc, FG(dc, col)); |
44 |
XSetForeground(dc->dpy, dc->gc, col->FG); |
48 |
if(dc->font.set) |
45 |
if(dc->font.xft_font) { |
|
|
46 |
if (!dc->xftdraw) |
47 |
eprintf("error, xft drawable does not exist"); |
48 |
XftDrawStringUtf8(dc->xftdraw, &col->FG_xft, |
49 |
dc->font.xft_font, x, y, (unsigned char*)text, n); |
50 |
} else if(dc->font.set) { |
49 |
XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); |
51 |
XmbDrawString(dc->dpy, dc->canvas, dc->font.set, dc->gc, x, y, text, n); |
50 |
else { |
52 |
} else { |
51 |
XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); |
53 |
XSetFont(dc->dpy, dc->gc, dc->font.xfont->fid); |
52 |
XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); |
54 |
XDrawString(dc->dpy, dc->canvas, dc->gc, x, y, text, n); |
53 |
} |
55 |
} |
Lines 69-84
eprintf(const char *fmt, ...) {
Link Here
|
69 |
} |
71 |
} |
70 |
|
72 |
|
71 |
void |
73 |
void |
|
|
74 |
freecol(DC *dc, ColorSet *col) { |
75 |
if(col) { |
76 |
if(&col->FG_xft) |
77 |
XftColorFree(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), |
78 |
DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), &col->FG_xft); |
79 |
free(col); |
80 |
} |
81 |
} |
82 |
|
83 |
void |
72 |
freedc(DC *dc) { |
84 |
freedc(DC *dc) { |
|
|
85 |
if(dc->font.xft_font) { |
86 |
XftFontClose(dc->dpy, dc->font.xft_font); |
87 |
XftDrawDestroy(dc->xftdraw); |
88 |
} |
73 |
if(dc->font.set) |
89 |
if(dc->font.set) |
74 |
XFreeFontSet(dc->dpy, dc->font.set); |
90 |
XFreeFontSet(dc->dpy, dc->font.set); |
75 |
if(dc->font.xfont) |
91 |
if(dc->font.xfont) |
76 |
XFreeFont(dc->dpy, dc->font.xfont); |
92 |
XFreeFont(dc->dpy, dc->font.xfont); |
77 |
if(dc->canvas) |
93 |
if(dc->canvas) |
78 |
XFreePixmap(dc->dpy, dc->canvas); |
94 |
XFreePixmap(dc->dpy, dc->canvas); |
79 |
XFreeGC(dc->dpy, dc->gc); |
95 |
if(dc->gc) |
80 |
XCloseDisplay(dc->dpy); |
96 |
XFreeGC(dc->dpy, dc->gc); |
81 |
free(dc); |
97 |
if(dc->dpy) |
|
|
98 |
XCloseDisplay(dc->dpy); |
99 |
if(dc) |
100 |
free(dc); |
82 |
} |
101 |
} |
83 |
|
102 |
|
84 |
unsigned long |
103 |
unsigned long |
Lines 91-96
getcolor(DC *dc, const char *colstr) {
Link Here
|
91 |
return color.pixel; |
110 |
return color.pixel; |
92 |
} |
111 |
} |
93 |
|
112 |
|
|
|
113 |
ColorSet * |
114 |
initcolor(DC *dc, const char * foreground, const char * background) { |
115 |
ColorSet * col = (ColorSet *)malloc(sizeof(ColorSet)); |
116 |
if(!col) |
117 |
eprintf("error, cannot allocate memory for color set"); |
118 |
col->BG = getcolor(dc, background); |
119 |
col->FG = getcolor(dc, foreground); |
120 |
if(dc->font.xft_font) |
121 |
if(!XftColorAllocName(dc->dpy, DefaultVisual(dc->dpy, DefaultScreen(dc->dpy)), |
122 |
DefaultColormap(dc->dpy, DefaultScreen(dc->dpy)), foreground, &col->FG_xft)) |
123 |
eprintf("error, cannot allocate xft font color '%s'\n", foreground); |
124 |
return col; |
125 |
} |
126 |
|
94 |
DC * |
127 |
DC * |
95 |
initdc(void) { |
128 |
initdc(void) { |
96 |
DC *dc; |
129 |
DC *dc; |
Lines 109-131
initdc(void) {
Link Here
|
109 |
|
142 |
|
110 |
void |
143 |
void |
111 |
initfont(DC *dc, const char *fontstr) { |
144 |
initfont(DC *dc, const char *fontstr) { |
112 |
if(!loadfont(dc, fontstr ? fontstr : DEFAULTFN)) { |
|
|
113 |
if(fontstr != NULL) |
114 |
fprintf(stderr, "cannot load font '%s'\n", fontstr); |
115 |
if(fontstr == NULL || !loadfont(dc, DEFAULTFN)) |
116 |
eprintf("cannot load font '%s'\n", DEFAULTFN); |
117 |
} |
118 |
dc->font.height = dc->font.ascent + dc->font.descent; |
119 |
} |
120 |
|
121 |
Bool |
122 |
loadfont(DC *dc, const char *fontstr) { |
123 |
char *def, **missing, **names; |
145 |
char *def, **missing, **names; |
124 |
int i, n; |
146 |
int i, n; |
125 |
XFontStruct **xfonts; |
147 |
XFontStruct **xfonts; |
126 |
|
148 |
|
127 |
if(!*fontstr) |
149 |
missing = NULL; |
128 |
return False; |
|
|
129 |
if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { |
150 |
if((dc->font.set = XCreateFontSet(dc->dpy, fontstr, &missing, &n, &def))) { |
130 |
n = XFontsOfFontSet(dc->font.set, &xfonts, &names); |
151 |
n = XFontsOfFontSet(dc->font.set, &xfonts, &names); |
131 |
for(i = 0; i < n; i++) { |
152 |
for(i = 0; i < n; i++) { |
Lines 133-147
loadfont(DC *dc, const char *fontstr) {
Link Here
|
133 |
dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); |
154 |
dc->font.descent = MAX(dc->font.descent, xfonts[i]->descent); |
134 |
dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); |
155 |
dc->font.width = MAX(dc->font.width, xfonts[i]->max_bounds.width); |
135 |
} |
156 |
} |
136 |
} |
157 |
} else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { |
137 |
else if((dc->font.xfont = XLoadQueryFont(dc->dpy, fontstr))) { |
158 |
dc->font.ascent = dc->font.xfont->ascent; |
138 |
dc->font.ascent = dc->font.xfont->ascent; |
|
|
139 |
dc->font.descent = dc->font.xfont->descent; |
159 |
dc->font.descent = dc->font.xfont->descent; |
140 |
dc->font.width = dc->font.xfont->max_bounds.width; |
160 |
dc->font.width = dc->font.xfont->max_bounds.width; |
|
|
161 |
} else if((dc->font.xft_font = XftFontOpenName(dc->dpy, DefaultScreen(dc->dpy), fontstr))) { |
162 |
dc->font.ascent = dc->font.xft_font->ascent; |
163 |
dc->font.descent = dc->font.xft_font->descent; |
164 |
dc->font.width = dc->font.xft_font->max_advance_width; |
165 |
} else { |
166 |
eprintf("cannot load font '%s'\n", fontstr); |
141 |
} |
167 |
} |
142 |
if(missing) |
168 |
if(missing) |
143 |
XFreeStringList(missing); |
169 |
XFreeStringList(missing); |
144 |
return dc->font.set || dc->font.xfont; |
170 |
dc->font.height = dc->font.ascent + dc->font.descent; |
|
|
171 |
return; |
145 |
} |
172 |
} |
146 |
|
173 |
|
147 |
void |
174 |
void |
Lines 151-170
mapdc(DC *dc, Window win, unsigned int w, unsigned int h) {
Link Here
|
151 |
|
178 |
|
152 |
void |
179 |
void |
153 |
resizedc(DC *dc, unsigned int w, unsigned int h) { |
180 |
resizedc(DC *dc, unsigned int w, unsigned int h) { |
|
|
181 |
int screen = DefaultScreen(dc->dpy); |
154 |
if(dc->canvas) |
182 |
if(dc->canvas) |
155 |
XFreePixmap(dc->dpy, dc->canvas); |
183 |
XFreePixmap(dc->dpy, dc->canvas); |
156 |
|
184 |
|
157 |
dc->w = w; |
185 |
dc->w = w; |
158 |
dc->h = h; |
186 |
dc->h = h; |
159 |
dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, |
187 |
dc->canvas = XCreatePixmap(dc->dpy, DefaultRootWindow(dc->dpy), w, h, |
160 |
DefaultDepth(dc->dpy, DefaultScreen(dc->dpy))); |
188 |
DefaultDepth(dc->dpy, screen)); |
|
|
189 |
if(dc->font.xft_font && !(dc->xftdraw)) { |
190 |
dc->xftdraw = XftDrawCreate(dc->dpy, dc->canvas, DefaultVisual(dc->dpy,screen), DefaultColormap(dc->dpy,screen)); |
191 |
if(!(dc->xftdraw)) |
192 |
eprintf("error, cannot create xft drawable\n"); |
193 |
} |
161 |
} |
194 |
} |
162 |
|
195 |
|
163 |
int |
196 |
int |
164 |
textnw(DC *dc, const char *text, size_t len) { |
197 |
textnw(DC *dc, const char *text, size_t len) { |
165 |
if(dc->font.set) { |
198 |
if(dc->font.xft_font) { |
|
|
199 |
XGlyphInfo gi; |
200 |
XftTextExtentsUtf8(dc->dpy, dc->font.xft_font, (const FcChar8*)text, len, &gi); |
201 |
return gi.width; |
202 |
} else if(dc->font.set) { |
166 |
XRectangle r; |
203 |
XRectangle r; |
167 |
|
|
|
168 |
XmbTextExtents(dc->font.set, text, len, NULL, &r); |
204 |
XmbTextExtents(dc->font.set, text, len, NULL, &r); |
169 |
return r.width; |
205 |
return r.width; |
170 |
} |
206 |
} |