Update Serbian translation from master branch
[wmaker-crm.git] / WINGs / wmisc.c
blobba4c8a6a6240e3879fd535b0dc6b1cc99b228a43
2 #include "WINGsP.h"
4 #include <wraster.h>
5 #include <ctype.h>
7 void
8 W_DrawRelief(W_Screen * scr, Drawable d, int x, int y, unsigned int width,
9 unsigned int height, WMReliefType relief)
11 W_DrawReliefWithGC(scr, d, x, y, width, height, relief,
12 WMColorGC(scr->black), WMColorGC(scr->darkGray),
13 WMColorGC(scr->gray), WMColorGC(scr->white));
16 void
17 W_DrawReliefWithGC(W_Screen * scr, Drawable d, int x, int y, unsigned int width,
18 unsigned int height, WMReliefType relief, GC black, GC dark, GC light, GC white)
20 Display *dpy = scr->display;
21 GC bgc;
22 GC wgc;
23 GC lgc;
24 GC dgc;
26 switch (relief) {
27 case WRSimple:
28 XDrawRectangle(dpy, d, black, x, y, width - 1, height - 1);
29 return;
31 case WRRaised:
32 bgc = black;
33 dgc = dark;
34 wgc = white;
35 lgc = light;
36 break;
38 case WRSunken:
39 wgc = dark;
40 lgc = black;
41 bgc = white;
42 dgc = light;
43 break;
45 case WRPushed:
46 lgc = wgc = black;
47 dgc = bgc = white;
48 break;
50 case WRRidge:
51 lgc = bgc = dark;
52 dgc = wgc = white;
53 break;
55 case WRGroove:
56 wgc = dgc = dark;
57 lgc = bgc = white;
58 break;
60 default:
61 return;
63 /* top left */
64 XDrawLine(dpy, d, wgc, x, y, x + width - 1, y);
65 if (width > 2 && relief != WRRaised && relief != WRPushed) {
66 XDrawLine(dpy, d, lgc, x + 1, y + 1, x + width - 3, y + 1);
69 XDrawLine(dpy, d, wgc, x, y, x, y + height - 1);
70 if (height > 2 && relief != WRRaised && relief != WRPushed) {
71 XDrawLine(dpy, d, lgc, x + 1, y + 1, x + 1, y + height - 3);
74 /* bottom right */
75 XDrawLine(dpy, d, bgc, x, y + height - 1, x + width - 1, y + height - 1);
76 if (width > 2 && relief != WRPushed) {
77 XDrawLine(dpy, d, dgc, x + 1, y + height - 2, x + width - 2, y + height - 2);
80 XDrawLine(dpy, d, bgc, x + width - 1, y, x + width - 1, y + height - 1);
81 if (height > 2 && relief != WRPushed) {
82 XDrawLine(dpy, d, dgc, x + width - 2, y + 1, x + width - 2, y + height - 2);
86 static int findNextWord(const char *text, int limit)
88 int pos, len;
90 len = strcspn(text, " \t\n\r");
91 pos = len + strspn(text + len, " \t\n\r");
92 if (pos > limit)
93 pos = limit;
95 return pos;
98 static int fitText(const char *text, WMFont * font, int width, int wrap)
100 int i, w, beforecrlf, word1, word2;
102 /* text length before first cr/lf */
103 beforecrlf = strcspn(text, "\n");
105 if (!wrap || beforecrlf == 0)
106 return beforecrlf;
108 w = WMWidthOfString(font, text, beforecrlf);
109 if (w <= width) {
110 /* text up to first crlf fits */
111 return beforecrlf;
114 word1 = 0;
115 while (1) {
116 word2 = word1 + findNextWord(text + word1, beforecrlf - word1);
117 if (word2 >= beforecrlf)
118 break;
119 w = WMWidthOfString(font, text, word2);
120 if (w > width)
121 break;
122 word1 = word2;
125 for (i = word1; i < word2; i++) {
126 w = WMWidthOfString(font, text, i);
127 if (w > width) {
128 break;
132 /* keep words complete if possible */
133 if (!isspace(text[i]) && word1 > 0) {
134 i = word1;
135 } else if (isspace(text[i]) && i < beforecrlf) {
136 /* keep space on current row, so new row has next word in column 1 */
137 i++;
140 return i;
143 int W_GetTextHeight(WMFont * font, const char *text, int width, int wrap)
145 const char *ptr = text;
146 int count;
147 int length = strlen(text);
148 int h;
149 int fheight = WMFontHeight(font);
151 h = 0;
152 while (length > 0) {
153 count = fitText(ptr, font, width, wrap);
155 h += fheight;
157 if (isspace(ptr[count]))
158 count++;
160 ptr += count;
161 length -= count;
163 return h;
166 void
167 W_PaintText(W_View * view, Drawable d, WMFont * font, int x, int y,
168 int width, WMAlignment alignment, WMColor * color, int wrap,
169 const char *text, int length)
171 const char *ptr = text;
172 int line_width;
173 int line_x;
174 int count;
175 int fheight = WMFontHeight(font);
177 while (length > 0) {
178 count = fitText(ptr, font, width, wrap);
180 line_width = WMWidthOfString(font, ptr, count);
181 if (alignment == WALeft)
182 line_x = x;
183 else if (alignment == WARight)
184 line_x = x + width - line_width;
185 else
186 line_x = x + (width - line_width) / 2;
188 WMDrawString(view->screen, d, color, font, line_x, y, ptr, count);
190 if (wrap && ptr[count] != '\n')
191 y += fheight;
193 while (ptr[count] && ptr[count] == '\n') {
194 y += fheight;
195 count++;
198 ptr += count;
199 length -= count;
203 void
204 W_PaintTextAndImage(W_View * view, int wrap, WMColor * textColor, W_Font * font,
205 WMReliefType relief, const char *text,
206 WMAlignment alignment, W_Pixmap * image,
207 WMImagePosition position, WMColor * backColor, int ofs)
209 W_Screen *screen = view->screen;
210 int ix, iy;
211 int x, y, w, h;
212 Drawable d = view->window;
214 #ifdef DOUBLE_BUFFER
215 d = XCreatePixmap(screen->display, view->window, view->size.width, view->size.height, screen->depth);
216 #endif
218 /* background */
219 if (backColor) {
220 XFillRectangle(screen->display, d, WMColorGC(backColor),
221 0, 0, view->size.width, view->size.height);
222 } else {
223 if (view->attribs.background_pixmap) {
224 #ifndef DOUBLE_BUFFER
225 XClearWindow(screen->display, d);
226 #else
227 XCopyArea(screen->display, view->attribs.background_pixmap, d, screen->copyGC, 0, 0, view->size.width, view->size.height, 0, 0);
228 #endif
229 } else {
230 #ifndef DOUBLE_BUFFER
231 XClearWindow(screen->display, d);
232 #else
233 XSetForeground(screen->display, screen->copyGC, view->attribs.background_pixel);
234 XFillRectangle(screen->display, d, screen->copyGC, 0, 0, view->size.width, view->size.height);
235 #endif
239 if (relief == WRFlat) {
240 x = 0;
241 y = 0;
242 w = view->size.width;
243 h = view->size.height;
244 } else {
245 x = 1;
246 y = 1;
247 w = view->size.width - 3;
248 h = view->size.height - 3;
251 /* calc. image alignment */
252 if (position != WIPNoImage && image != NULL) {
253 switch (position) {
254 case WIPOverlaps:
255 case WIPImageOnly:
256 ix = (view->size.width - image->width) / 2;
257 iy = (view->size.height - image->height) / 2;
259 x = 2;
260 y = 0;
262 break;
264 case WIPLeft:
265 ix = x;
266 iy = y + (h - image->height) / 2;
267 x = x + image->width + 5;
268 y = 0;
269 w -= image->width + 5;
270 break;
272 case WIPRight:
273 ix = view->size.width - image->width - x;
274 iy = y + (h - image->height) / 2;
275 w -= image->width + 5;
276 break;
278 case WIPBelow:
279 ix = (view->size.width - image->width) / 2;
280 iy = h - image->height;
281 y = 0;
282 h -= image->height;
283 break;
285 default:
286 case WIPAbove:
287 ix = (view->size.width - image->width) / 2;
288 iy = y;
289 y = image->height;
290 h -= image->height;
291 break;
294 ix += ofs;
295 iy += ofs;
297 XSetClipOrigin(screen->display, screen->clipGC, ix, iy);
298 XSetClipMask(screen->display, screen->clipGC, image->mask);
300 if (image->depth == 1)
301 XCopyPlane(screen->display, image->pixmap, d, screen->clipGC,
302 0, 0, image->width, image->height, ix, iy, 1);
303 else
304 XCopyArea(screen->display, image->pixmap, d, screen->clipGC,
305 0, 0, image->width, image->height, ix, iy);
308 /* draw text */
309 if (position != WIPImageOnly && text != NULL) {
310 int textHeight;
312 textHeight = W_GetTextHeight(font, text, w - 8, wrap);
313 W_PaintText(view, d, font, x + ofs + 4, y + ofs + (h - textHeight) / 2, w - 8,
314 alignment, textColor, wrap, text, strlen(text));
317 /* draw relief */
318 W_DrawRelief(screen, d, 0, 0, view->size.width, view->size.height, relief);
320 #ifdef DOUBLE_BUFFER
321 XCopyArea(screen->display, d, view->window, screen->copyGC, 0, 0,
322 view->size.width, view->size.height, 0, 0);
323 XFreePixmap(screen->display, d);
324 #endif
327 WMPoint wmkpoint(int x, int y)
329 WMPoint point;
331 point.x = x;
332 point.y = y;
334 return point;
337 WMSize wmksize(unsigned int width, unsigned int height)
339 WMSize size;
341 size.width = width;
342 size.height = height;
344 return size;
347 WMRect wmkrect(int x, int y, unsigned int width, unsigned int height)
349 WMRect rect;
351 rect.pos.x = x;
352 rect.pos.y = y;
353 rect.size.width = width;
354 rect.size.height = height;
356 return rect;