continued with draw.c and draw.h implementation, now the integration begins
aafeaf73
2 file(s) · +71 −29
| 1 | 1 | /* See LICENSE file for copyright and license details. */ |
|
| 2 | 2 | #include <stdio.h> |
|
| 3 | 3 | #include <stdlib.h> |
|
| 4 | + | #include <string.h> |
|
| 4 | 5 | #include <X11/Xlib.h> |
|
| 5 | 6 | ||
| 6 | 7 | #include "draw.h" |
|
| 55 | 56 | if(font->set) { |
|
| 56 | 57 | XFontStruct **xfonts; |
|
| 57 | 58 | char **font_names; |
|
| 58 | - | ||
| 59 | 59 | XExtentsOfFontSet(font->set); |
|
| 60 | 60 | n = XFontsOfFontSet(font->set, &xfonts, &font_names); |
|
| 61 | 61 | while(n--) { |
|
| 107 | 107 | ||
| 108 | 108 | void |
|
| 109 | 109 | draw_setfont(Draw *draw, Fnt *font) { |
|
| 110 | - | if(!draw || !font) |
|
| 110 | + | if(!draw) |
|
| 111 | 111 | return; |
|
| 112 | 112 | draw->font = font; |
|
| 113 | 113 | } |
|
| 114 | 114 | ||
| 115 | 115 | void |
|
| 116 | 116 | draw_setfg(Draw *draw, Col *col) { |
|
| 117 | - | if(!draw || !col) |
|
| 117 | + | if(!draw) |
|
| 118 | 118 | return; |
|
| 119 | 119 | draw->fg = col; |
|
| 120 | 120 | } |
|
| 121 | 121 | ||
| 122 | 122 | void |
|
| 123 | 123 | draw_setbg(Draw *draw, Col *col) { |
|
| 124 | - | if(!draw || !col) |
|
| 124 | + | if(!draw) |
|
| 125 | 125 | return; |
|
| 126 | 126 | draw->bg = col; |
|
| 127 | 127 | } |
|
| 128 | 128 | ||
| 129 | 129 | void |
|
| 130 | - | draw_rect(Draw *draw, int x, int y, unsigned int w, unsigned int h) { |
|
| 131 | - | if(!draw) |
|
| 130 | + | draw_rect(Draw *draw, int x, int y, unsigned int w, unsigned int h, Bool filled, Bool empty, Bool invert) { |
|
| 131 | + | int dx; |
|
| 132 | + | ||
| 133 | + | if(!draw || !draw->font || !draw->fg || !draw->bg) |
|
| 132 | 134 | return; |
|
| 133 | - | /* TODO: draw the rectangle */ |
|
| 135 | + | XSetForeground(draw->dpy, draw->gc, invert ? draw->bg->rgb : draw->fg->rgb); |
|
| 136 | + | dx = (draw->font->ascent + draw->font->descent + 2) / 4; |
|
| 137 | + | if(filled) |
|
| 138 | + | XFillRectangle(draw->dpy, draw->drawable, draw->gc, x+1, y+1, dx+1, dx+1); |
|
| 139 | + | else if(empty) |
|
| 140 | + | XDrawRectangle(draw->dpy, draw->drawable, draw->gc, x+1, y+1, dx, dx); |
|
| 134 | 141 | } |
|
| 135 | 142 | ||
| 136 | 143 | void |
|
| 137 | - | draw_text(Draw *draw, int x, int y, const char *text) { |
|
| 138 | - | if(!draw) |
|
| 144 | + | draw_text(Draw *draw, int x, int y, unsigned int w, unsigned int h, const char *text, Bool invert) { |
|
| 145 | + | char buf[256]; |
|
| 146 | + | int i, tx, ty, len, olen; |
|
| 147 | + | TextExtents tex; |
|
| 148 | + | ||
| 149 | + | if(!draw || !draw->fg || !draw->bg) |
|
| 150 | + | return; |
|
| 151 | + | XSetForeground(draw->dpy, draw->gc, invert ? draw->fg->rgb : draw->bg->rgb); |
|
| 152 | + | XFillRectangle(draw->dpy, draw->drawable, draw->gc, x, y, w, h); |
|
| 153 | + | if(!text || !draw->font) |
|
| 154 | + | return; |
|
| 155 | + | olen = strlen(text); |
|
| 156 | + | draw_getextents(draw, text, olen, &tex); |
|
| 157 | + | ty = y + (h / 2) - tex.yOff; |
|
| 158 | + | tx = x + tex.xOff; |
|
| 159 | + | /* shorten text if necessary */ |
|
| 160 | + | for(len = MIN(olen, sizeof buf); len && tex.w > w - tex.h; len--) |
|
| 161 | + | draw_getextents(draw, text, len, &tex); |
|
| 162 | + | if(!len) |
|
| 139 | 163 | return; |
|
| 140 | - | /* TODO: draw the text */ |
|
| 164 | + | memcpy(buf, text, len); |
|
| 165 | + | if(len < olen) |
|
| 166 | + | for(i = len; i && i > len - 3; buf[--i] = '.'); |
|
| 167 | + | XSetForeground(draw->dpy, draw->gc, invert ? draw->bg->rgb : draw->fg->rgb); |
|
| 168 | + | if(draw->font->set) |
|
| 169 | + | XmbDrawString(draw->dpy, draw->drawable, draw->font->set, draw->gc, tx, ty, buf, len); |
|
| 170 | + | else |
|
| 171 | + | XDrawString(draw->dpy, draw->drawable, draw->gc, tx, ty, buf, len); |
|
| 141 | 172 | } |
|
| 142 | 173 | ||
| 143 | 174 | void |
|
| 144 | 175 | draw_map(Draw *draw, int x, int y, unsigned int w, unsigned int h) { |
|
| 145 | 176 | if(!draw) |
|
| 146 | 177 | return; |
|
| 147 | - | /* TODO: map the draw contents in the region */ |
|
| 178 | + | XCopyArea(draw->dpy, draw->drawable, draw->win, draw->gc, x, y, w, h, x, y); |
|
| 179 | + | XSync(draw->dpy, False); |
|
| 148 | 180 | } |
|
| 181 | + | ||
| 149 | 182 | ||
| 150 | 183 | void |
|
| 151 | - | draw_getextents(Draw *draw, const char *text, TextExtents *extents) { |
|
| 152 | - | if(!draw || !extents) |
|
| 184 | + | draw_getextents(Draw *draw, const char *text, unsigned int len, TextExtents *extents) { |
|
| 185 | + | XRectangle r; |
|
| 186 | + | ||
| 187 | + | if(!draw || !draw->font || !text) |
|
| 153 | 188 | return; |
|
| 154 | - | /* TODO: get extents */ |
|
| 189 | + | if(draw->font->set) { |
|
| 190 | + | XmbTextExtents(draw->font->set, text, len, NULL, &r); |
|
| 191 | + | extents->xOff = r.x; |
|
| 192 | + | extents->yOff = r.y; |
|
| 193 | + | extents->w = r.width; |
|
| 194 | + | extents->h = r.height; |
|
| 195 | + | } |
|
| 196 | + | else { |
|
| 197 | + | extents->h = draw->font->ascent + draw->font->descent; |
|
| 198 | + | extents->w = XTextWidth(draw->font->xfont, text, len); |
|
| 199 | + | extents->xOff = extents->h / 2; |
|
| 200 | + | extents->yOff = (extents->h / 2) + draw->font->ascent; |
|
| 201 | + | } |
|
| 155 | 202 | } |
|
| 13 | 13 | XFontStruct *xfont; |
|
| 14 | 14 | }; |
|
| 15 | 15 | typedef struct _XFont Fnt; |
|
| 16 | - | /* X11 types - end */ |
|
| 17 | 16 | ||
| 18 | - | typedef struct { |
|
| 19 | - | unsigned int w; |
|
| 20 | - | unsigned int h; |
|
| 21 | - | int x; |
|
| 22 | - | int y; |
|
| 23 | - | int xOff; |
|
| 24 | - | int yOff; |
|
| 25 | - | } TextExtents; |
|
| 26 | - | ||
| 27 | - | ||
| 28 | - | /* X11 types - begin */ |
|
| 29 | 17 | typedef struct _XDraw Draw; |
|
| 30 | 18 | struct _XDraw { |
|
| 31 | 19 | unsigned int w, h; |
|
| 39 | 27 | Fnt *font; |
|
| 40 | 28 | }; |
|
| 41 | 29 | ||
| 30 | + | typedef struct { |
|
| 31 | + | unsigned int w; |
|
| 32 | + | unsigned int h; |
|
| 33 | + | int xOff; |
|
| 34 | + | int yOff; |
|
| 35 | + | } TextExtents; |
|
| 36 | + | ||
| 42 | 37 | /* Drawable abstraction */ |
|
| 43 | 38 | Draw *draw_create(Display *dpy, int screen, Window win, unsigned int w, unsigned int h); |
|
| 44 | 39 | void draw_resize(Draw *draw, unsigned int w, unsigned int h); |
|
| 58 | 53 | void draw_setbg(Draw *draw, Col *col); |
|
| 59 | 54 | ||
| 60 | 55 | /* Drawing functions */ |
|
| 61 | - | void draw_rect(Draw *draw, int x, int y, unsigned int w, unsigned int h); |
|
| 62 | - | void draw_text(Draw *draw, int x, int y, const char *text); |
|
| 56 | + | void draw_rect(Draw *draw, int x, int y, unsigned int w, unsigned int h, Bool filled, Bool empty, Bool invert); |
|
| 57 | + | void draw_text(Draw *draw, int x, int y, unsigned int w, unsigned int h, const char *text, Bool invert); |
|
| 63 | 58 | ||
| 64 | 59 | /* Map functions */ |
|
| 65 | 60 | void draw_map(Draw *draw, int x, int y, unsigned int w, unsigned int h); |
|
| 66 | 61 | ||
| 67 | 62 | /* Text functions */ |
|
| 68 | - | void draw_getextents(Draw *draw, const char *text, TextExtents *extents); |
|
| 63 | + | void draw_getextents(Draw *draw, const char *text, unsigned int len, TextExtents *extents); |
|
| 69 | 64 | ||