2 * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3 * Copyright (C) 2007-2008 Kim Woelders
5 * Permission is hereby granted, free of charge, to any person obtaining a copy
6 * of this software and associated documentation files (the "Software"), to
7 * deal in the Software without restriction, including without limitation the
8 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
9 * sell copies of the Software, and to permit persons to whom the Software is
10 * furnished to do so, subject to the following conditions:
12 * The above copyright notice and this permission notice shall be included in
13 * all copies of the Software, its documentation and marketing & publicity
14 * materials, and acknowledgment shall be given in the documentation, materials
15 * and software packages that this Software was used.
17 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
20 * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
21 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
22 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 TextGetLines(const char *text, int *count)
41 while ((text[j]) && (text[j] != '\n'))
44 list = EREALLOC(char *, list, k);
45 list[k - 1] = EMALLOC(char, j - i + 1);
47 strncpy(list[k - 1], &(text[i]), (j - i));
48 list[k - 1][j - i] = 0;
58 TextStateLoadFont(TextState * ts)
61 if ((ts->efont) || (ts->xfont) || (ts->xfontset))
63 if ((ts->efont) || (ts->xfontset))
72 char s[4096], w[4046], *s2, *ss;
75 s2 = strdup(ts->fontname);
82 ts->efont = Efont_load(s, atoi(w));
87 Efont_extents(ts->efont, " ", &as, &ds, NULL, NULL, NULL,
89 ts->xfontset_ascent = as;
99 if ((!ts->xfont) && (strchr(ts->fontname, ',') == NULL))
101 ts->xfont = XLoadQueryFont(disp, ts->fontname);
104 ts->xfontset_ascent = ts->xfont->ascent;
105 ts->height = ts->xfont->ascent + ts->xfont->descent;
113 int i, missing_cnt, font_cnt;
115 char **missing_list, *def_str, **fn;
118 ts->xfontset = XCreateFontSet(disp, ts->fontname, &missing_list,
119 &missing_cnt, &def_str);
121 ts->xfontset = XCreateFontSet(disp, "fixed", &missing_list,
122 &missing_cnt, &def_str);
124 XFreeStringList(missing_list);
127 font_cnt = XFontsOfFontSet(ts->xfontset, &fs, &fn);
128 ts->xfontset_ascent = 0;
129 for (i = 0; i < font_cnt; i++)
130 ts->xfontset_ascent = MAX(fs[i]->ascent, ts->xfontset_ascent);
132 for (i = 0; i < font_cnt; i++)
133 descent = MAX(fs[i]->descent, descent);
134 ts->height = ts->xfontset_ascent + descent;
139 TextSize(TextState * ts, const char *text, int *width, int *height, int fsize)
147 lines = TextGetLines(text, &num_lines);
154 TextStateLoadFont(ts);
158 for (i = 0; i < num_lines; i++)
160 int ascent, descent, wid;
162 Efont_extents(ts->efont, lines[i], &ascent, &descent, &wid,
163 NULL, NULL, NULL, NULL);
164 *height += ascent + descent;
169 else if (ts->xfontset)
171 for (i = 0; i < num_lines; i++)
173 XRectangle ret1, ret2;
175 XmbTextExtents(ts->xfontset, lines[i], strlen(lines[i]), &ret1,
177 *height += ret2.height;
178 if (ret2.width > *width)
183 else if ((ts->xfont) && (ts->xfont->min_byte1 == 0) &&
184 (ts->xfont->max_byte1 == 0))
186 for (i = 0; i < num_lines; i++)
190 wid = XTextWidth(ts->xfont, lines[i], strlen(lines[i]));
191 *height += ts->xfont->ascent + ts->xfont->descent;
196 else if ((ts->xfont))
198 for (i = 0; i < num_lines; i++)
202 wid = XTextWidth16(ts->xfont, (XChar2b *) lines[i],
203 strlen(lines[i]) / 2);
204 *height += ts->xfont->ascent + ts->xfont->descent;
209 #endif /* USE_XFONT */
210 freestrlist(lines, num_lines);
216 TextDraw(TextState * ts, Window win, char *text,
217 int x, int y, int w, int h, int fsize, int justification)
225 lines = TextGetLines(text, &num_lines);
232 TextStateLoadFont(ts);
237 gc = XCreateGC(disp, win, 0, &gcv);
241 for (i = 0; i < num_lines; i++)
243 int ascent, descent, wid;
245 Efont_extents(ts->efont, lines[i], &ascent, &descent, &wid,
246 NULL, NULL, NULL, NULL);
249 xx = x + (((w - wid) * justification) >> 10);
252 EAllocColor(&ts->bg_col);
253 XSetForeground(disp, gc, ts->bg_col.pixel);
254 EFont_draw_string(disp, win, gc, xx + 1, yy + 1,
255 lines[i], ts->efont, VRoot.vis, VRoot.cmap);
257 else if (ts->effect == 2)
259 EAllocColor(&ts->bg_col);
260 XSetForeground(disp, gc, ts->bg_col.pixel);
261 EFont_draw_string(disp, win, gc, xx - 1, yy,
262 lines[i], ts->efont, VRoot.vis, VRoot.cmap);
263 EFont_draw_string(disp, win, gc, xx + 1, yy,
264 lines[i], ts->efont, VRoot.vis, VRoot.cmap);
265 EFont_draw_string(disp, win, gc, xx, yy - 1,
266 lines[i], ts->efont, VRoot.vis, VRoot.cmap);
267 EFont_draw_string(disp, win, gc, xx, yy + 1,
268 lines[i], ts->efont, VRoot.vis, VRoot.cmap);
270 EAllocColor(&ts->fg_col);
271 XSetForeground(disp, gc, ts->fg_col.pixel);
272 EFont_draw_string(disp, win, gc, xx, yy,
273 lines[i], ts->efont, VRoot.vis, VRoot.cmap);
274 yy += ascent + descent;
277 else if (ts->xfontset)
279 for (i = 0; i < num_lines; i++)
281 XRectangle ret1, ret2;
283 XmbTextExtents(ts->xfontset, lines[i], strlen(lines[i]), &ret1,
286 yy += ts->xfontset_ascent;
287 xx = x + (((w - ret2.width) * justification) >> 10);
290 EAllocColor(&ts->bg_col);
291 XSetForeground(disp, gc, ts->bg_col.pixel);
292 XmbDrawString(disp, win, ts->xfontset, gc, xx + 1, yy + 1,
293 lines[i], strlen(lines[i]));
295 else if (ts->effect == 2)
297 EAllocColor(&ts->bg_col);
298 XSetForeground(disp, gc, ts->bg_col.pixel);
299 XmbDrawString(disp, win, ts->xfontset, gc, xx - 1, yy,
300 lines[i], strlen(lines[i]));
301 XmbDrawString(disp, win, ts->xfontset, gc, xx + 1, yy,
302 lines[i], strlen(lines[i]));
303 XmbDrawString(disp, win, ts->xfontset, gc, xx, yy - 1,
304 lines[i], strlen(lines[i]));
305 XmbDrawString(disp, win, ts->xfontset, gc, xx, yy + 1,
306 lines[i], strlen(lines[i]));
308 EAllocColor(&ts->fg_col);
309 XSetForeground(disp, gc, ts->fg_col.pixel);
310 XmbDrawString(disp, win, ts->xfontset, gc, xx, yy,
311 lines[i], strlen(lines[i]));
316 else if ((ts->xfont) && (ts->xfont->min_byte1 == 0) &&
317 (ts->xfont->max_byte1 == 0))
319 XSetFont(disp, gc, ts->xfont->fid);
320 for (i = 0; i < num_lines; i++)
324 wid = XTextWidth(ts->xfont, lines[i], strlen(lines[i]));
326 yy += ts->xfont->ascent;
327 xx = x + (((w - wid) * justification) >> 10);
330 EAllocColor(&ts->bg_col);
331 XSetForeground(disp, gc, ts->bg_col.pixel);
332 XDrawString(disp, win, gc, xx + 1, yy + 1,
333 lines[i], strlen(lines[i]));
335 else if (ts->effect == 2)
337 EAllocColor(&ts->bg_col);
338 XSetForeground(disp, gc, ts->bg_col.pixel);
339 XDrawString(disp, win, gc, xx - 1, yy,
340 lines[i], strlen(lines[i]));
341 XDrawString(disp, win, gc, xx + 1, yy,
342 lines[i], strlen(lines[i]));
343 XDrawString(disp, win, gc, xx, yy - 1,
344 lines[i], strlen(lines[i]));
345 XDrawString(disp, win, gc, xx, yy + 1,
346 lines[i], strlen(lines[i]));
348 EAllocColor(&ts->fg_col);
349 XSetForeground(disp, gc, ts->fg_col.pixel);
350 XDrawString(disp, win, gc, xx, yy, lines[i], strlen(lines[i]));
351 yy += ts->xfont->ascent + ts->xfont->descent;
354 else if ((ts->xfont))
356 XSetFont(disp, gc, ts->xfont->fid);
357 for (i = 0; i < num_lines; i++)
361 wid = XTextWidth16(ts->xfont, (XChar2b *) lines[i],
362 strlen(lines[i]) / 2);
364 yy += ts->xfont->ascent;
365 xx = x + (((w - wid) * justification) >> 10);
368 EAllocColor(&ts->bg_col);
369 XSetForeground(disp, gc, ts->bg_col.pixel);
370 XDrawString16(disp, win, gc, xx + 1, yy + 1,
371 (XChar2b *) lines[i], strlen(lines[i]) / 2);
373 else if (ts->effect == 2)
375 EAllocColor(&ts->bg_col);
376 XSetForeground(disp, gc, ts->bg_col.pixel);
377 XDrawString16(disp, win, gc, xx - 1, yy,
378 (XChar2b *) lines[i], strlen(lines[i]) / 2);
379 XDrawString16(disp, win, gc, xx + 1, yy,
380 (XChar2b *) lines[i], strlen(lines[i]) / 2);
381 XDrawString16(disp, win, gc, xx, yy - 1,
382 (XChar2b *) lines[i], strlen(lines[i]) / 2);
383 XDrawString16(disp, win, gc, xx, yy + 1,
384 (XChar2b *) lines[i], strlen(lines[i]) / 2);
386 EAllocColor(&ts->fg_col);
387 XSetForeground(disp, gc, ts->fg_col.pixel);
388 XDrawString16(disp, win, gc, xx, yy,
389 (XChar2b *) lines[i], strlen(lines[i]) / 2);
390 yy += ts->xfont->ascent + ts->xfont->descent;
393 #endif /* USE_XFONT */
394 freestrlist(lines, num_lines);