e16/src/text.c

879 lines
24 KiB
C

/*
* Copyright (C) 2000-2005 Carsten Haitzler, Geoff Harrison and various contributors
* Copyright (C) 2004-2005 Kim Woelders
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies of the Software, its documentation and marketing & publicity
* materials, and acknowledgment shall be given in the documentation, materials
* and software packages that this Software was used.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "E.h"
#define ExTextExtents XmbTextExtents
#define ExDrawString XmbDrawString
static void TextDrawRotTo(Window win, Drawable * drawable, int x, int y,
int w, int h, TextState * ts);
static void TextDrawRotBack(Window win, Drawable drawable, int x, int y,
int w, int h, TextState * ts);
TextState *
TextclassGetTextState(TextClass * tclass, int state, int active, int sticky)
{
if (active)
{
if (!sticky)
{
switch (state)
{
case STATE_NORMAL:
return tclass->active.normal;
case STATE_HILITED:
return tclass->active.hilited;
case STATE_CLICKED:
return tclass->active.clicked;
case STATE_DISABLED:
return tclass->active.disabled;
default:
break;
}
}
else
{
switch (state)
{
case STATE_NORMAL:
return tclass->sticky_active.normal;
case STATE_HILITED:
return tclass->sticky_active.hilited;
case STATE_CLICKED:
return tclass->sticky_active.clicked;
case STATE_DISABLED:
return tclass->sticky_active.disabled;
default:
break;
}
}
}
else if (sticky)
{
switch (state)
{
case STATE_NORMAL:
return tclass->sticky.normal;
case STATE_HILITED:
return tclass->sticky.hilited;
case STATE_CLICKED:
return tclass->sticky.clicked;
case STATE_DISABLED:
return tclass->sticky.disabled;
default:
break;
}
}
else
{
switch (state)
{
case STATE_NORMAL:
return tclass->norm.normal;
case STATE_HILITED:
return tclass->norm.hilited;
case STATE_CLICKED:
return tclass->norm.clicked;
case STATE_DISABLED:
return tclass->norm.disabled;
default:
break;
}
}
return NULL;
}
static char **
TextGetLines(const char *text, int *count)
{
int i, j, k;
char **list = NULL;
*count = 0;
i = 0;
k = 0;
if (!text)
return NULL;
*count = 1;
while (text[i])
{
j = i;
while ((text[j]) && (text[j] != '\n'))
j++;
k++;
list = Erealloc(list, sizeof(char *) * k);
list[k - 1] = Emalloc(sizeof(char) * (j - i + 1));
strncpy(list[k - 1], &(text[i]), (j - i));
list[k - 1][j - i] = 0;
i = j;
if (text[i] == '\n')
i++;
}
*count = k;
return list;
}
static void
TextStateLoadFont(TextState * ts)
{
if (!ts->fontname)
return;
/* Quit if already done */
if ((ts->efont) || (ts->xfont) || (ts->xfontset))
return;
ts->need_utf8 = Mode.text.utf8_int;
/* Try FreeType */
{
char s[4096], w[4046], *s2, *ss;
s2 = NULL;
s2 = Estrdup(ts->fontname);
ss = strchr(s2, '/');
if (ss)
{
*ss = ' ';
word(s2, 1, w);
Esnprintf(s, sizeof(s), "ttfonts/%s.ttf", w);
word(s2, 2, w);
ss = ThemeFileFind(s);
if (ss)
{
ts->efont = Efont_load(ss, atoi(w));
Efree(ss);
}
}
if (s2)
Efree(s2);
if (ts->efont)
ts->need_utf8 = 1;
}
if (ts->efont)
goto done;
/* Try X11 XCreateFontSet */
{
int i, missing_cnt, font_cnt;
char **missing_list, *def_str, **fn;
XFontStruct **fs;
ts->xfontset = XCreateFontSet(disp, ts->fontname, &missing_list,
&missing_cnt, &def_str);
if (missing_cnt)
XFreeStringList(missing_list);
if (!ts->xfontset)
{
ts->xfontset = XCreateFontSet(disp, "fixed", &missing_list,
&missing_cnt, &def_str);
if (missing_cnt)
XFreeStringList(missing_list);
}
if (ts->xfontset)
{
ts->xfontset_ascent = 0;
font_cnt = XFontsOfFontSet(ts->xfontset, &fs, &fn);
for (i = 0; i < font_cnt; i++)
ts->xfontset_ascent = MAX(fs[i]->ascent, ts->xfontset_ascent);
}
}
if (ts->xfontset)
goto done;
/* Try X11 XLoadQueryFont */
if (strchr(ts->fontname, ',') == NULL)
ts->xfont = XLoadQueryFont(disp, ts->fontname);
if (ts->xfont)
goto done;
/* This one really should succeed! */
ts->xfont = XLoadQueryFont(disp, "fixed");
done:
return;
}
void
TextSize(TextClass * tclass, int active, int sticky, int state,
const char *text, int *width, int *height, int fsize __UNUSED__)
{
const char *str;
char **lines;
int i, num_lines;
TextState *ts;
*width = 0;
*height = 0;
if (!text)
return;
ts = TextclassGetTextState(tclass, state, active, sticky);
if (!ts)
return;
TextStateLoadFont(ts);
/* Do encoding conversion, if necessary */
str = EstrInt2Enc(text, ts->need_utf8);
lines = TextGetLines(str, &num_lines);
EstrInt2EncFree(str, ts->need_utf8);
if (!lines)
return;
if (ts->efont)
{
for (i = 0; i < num_lines; i++)
{
int ascent, descent, wid;
Efont_extents(ts->efont, lines[i], &ascent, &descent, &wid, NULL,
NULL, NULL, NULL);
*height += ascent + descent;
if (wid > *width)
*width = wid;
}
}
else if (ts->xfontset)
{
for (i = 0; i < num_lines; i++)
{
XRectangle ret1, ret2;
ExTextExtents(ts->xfontset, lines[i], strlen(lines[i]), &ret1,
&ret2);
*height += ret2.height;
if (ret2.width > *width)
*width = ret2.width;
}
}
else if ((ts->xfont) && (ts->xfont->min_byte1 == 0)
&& (ts->xfont->max_byte1 == 0))
{
for (i = 0; i < num_lines; i++)
{
int wid;
wid = XTextWidth(ts->xfont, lines[i], strlen(lines[i]));
*height += ts->xfont->ascent + ts->xfont->descent;
if (wid > *width)
*width = wid;
}
}
else if ((ts->xfont))
{
for (i = 0; i < num_lines; i++)
{
int wid;
wid = XTextWidth16(ts->xfont, (XChar2b *) lines[i],
strlen(lines[i]) / 2);
*height += ts->xfont->ascent + ts->xfont->descent;
if (wid > *width)
*width = wid;
}
}
EstrlistFree(lines, num_lines);
}
void
TextstateDrawText(TextState * ts, Window win, const char *text, int x, int y,
int w, int h, int fsize __UNUSED__, int justification)
{
const char *str;
char **lines;
int i, num_lines;
int xx, yy;
static GC gc = 0;
int textwidth_limit, offset_x, offset_y;
Pixmap drawable;
if (w <= 0 || h <= 0)
return;
TextStateLoadFont(ts);
/* Do encoding conversion, if necessary */
str = EstrInt2Enc(text, ts->need_utf8);
lines = TextGetLines(str, &num_lines);
EstrInt2EncFree(str, ts->need_utf8);
if (!lines)
return;
if (!gc)
gc = ECreateGC(win, 0, NULL);
if (ts->style.orientation == FONT_TO_RIGHT ||
ts->style.orientation == FONT_TO_LEFT)
textwidth_limit = w;
else
textwidth_limit = h;
xx = x;
yy = y;
if (ts->efont)
{
for (i = 0; i < num_lines; i++)
{
int ascent, descent, wid;
Efont_extents(ts->efont, lines[i], &ascent, &descent, &wid, NULL,
NULL, NULL, NULL);
if (wid > textwidth_limit)
{
char *new_line;
int nuke_count = 0;
int len;
len = strlen(lines[i]);
new_line = Emalloc(len + 10);
while (wid > textwidth_limit)
{
nuke_count++;
if (nuke_count > len)
{
new_line[0] = 0;
strncat(new_line, lines[i], 1);
strcat(new_line, "...");
break;
}
new_line[0] = 0;
strncat(new_line, lines[i], (len - nuke_count) / 2);
strcat(new_line, "...");
strcat(new_line,
lines[i] + ((len - nuke_count) / 2) + nuke_count);
Efont_extents(ts->efont, new_line, &ascent, &descent,
&wid, NULL, NULL, NULL, NULL);
}
Efree(lines[i]);
lines[i] = new_line;
}
if (i == 0)
yy += ascent;
xx = x + (((textwidth_limit - wid) * justification) >> 10);
if (ts->style.orientation != FONT_TO_RIGHT)
drawable =
ECreatePixmap(VRoot.win, wid + 2, ascent + descent + 2,
GetWinDepth(win));
else
drawable = win;
TextDrawRotTo(win, &drawable, xx - 1, yy - 1 - ascent, wid + 2,
ascent + descent + 2, ts);
if (ts->style.orientation == FONT_TO_RIGHT)
{
offset_x = xx;
offset_y = yy;
}
else
{
offset_x = 1;
offset_y = ascent + 1;
}
if (ts->effect == 1)
{
EAllocColor(&ts->bg_col);
XSetForeground(disp, gc, ts->bg_col.pixel);
EFont_draw_string(disp, drawable, gc, offset_x + 1,
offset_y + 1, lines[i], ts->efont,
VRoot.vis, VRoot.cmap);
}
else if (ts->effect == 2)
{
EAllocColor(&ts->bg_col);
XSetForeground(disp, gc, ts->bg_col.pixel);
EFont_draw_string(disp, drawable, gc, offset_x - 1, offset_y,
lines[i], ts->efont, VRoot.vis, VRoot.cmap);
EFont_draw_string(disp, drawable, gc, offset_x + 1, offset_y,
lines[i], ts->efont, VRoot.vis, VRoot.cmap);
EFont_draw_string(disp, drawable, gc, offset_x, offset_y - 1,
lines[i], ts->efont, VRoot.vis, VRoot.cmap);
EFont_draw_string(disp, drawable, gc, offset_x, offset_y + 1,
lines[i], ts->efont, VRoot.vis, VRoot.cmap);
}
EAllocColor(&ts->fg_col);
XSetForeground(disp, gc, ts->fg_col.pixel);
EFont_draw_string(disp, drawable, gc, offset_x, offset_y, lines[i],
ts->efont, VRoot.vis, VRoot.cmap);
TextDrawRotBack(win, drawable, xx - 1, yy - 1 - ascent, wid + 2,
ascent + descent + 2, ts);
if (drawable != win)
EFreePixmap(drawable);
yy += ascent + descent;
}
}
else if (ts->xfontset)
{
for (i = 0; i < num_lines; i++)
{
XRectangle ret1, ret2;
ExTextExtents(ts->xfontset, lines[i], strlen(lines[i]), &ret1,
&ret2);
if (ret2.width > textwidth_limit)
{
char *new_line;
int nuke_count = 0;
int len;
wchar_t *wc_line = NULL;
int wc_len;
len = strlen(lines[i]);
new_line = Emalloc(len + 10);
wc_len = mbstowcs(NULL, lines[i], 0);
if (wc_len > 0)
{
wc_line =
(wchar_t *) Emalloc((wc_len + 1) * sizeof(wchar_t));
mbstowcs(wc_line, lines[i], len);
wc_line[wc_len] = (wchar_t) '\0';
}
while (ret2.width > textwidth_limit)
{
nuke_count++;
if (nuke_count > wc_len)
{
int mlen;
new_line[0] = 0;
if (MB_CUR_MAX > 1 && wc_len > 0)
{ /* if multibyte locale,... */
mlen = mblen(lines[i], MB_CUR_MAX);
if (mlen < 0)
mlen = 1;
}
else
mlen = 1;
strncat(new_line, lines[i], mlen);
strcat(new_line, "...");
break;
}
new_line[0] = 0;
if (MB_CUR_MAX > 1 && wc_len > 0)
{
int j, k, len_mb;
for (j = k = 0; k < (wc_len - nuke_count) / 2; k++)
{
len_mb = wctomb(new_line + j, wc_line[k]);
if (len_mb > 0)
j += len_mb;
}
new_line[j] = '\0';
strcat(new_line, "...");
j += 3;
len_mb =
wcstombs(new_line + j,
wc_line + (wc_len - nuke_count) / 2 +
nuke_count, len + 10 - j);
if (len_mb > 0)
j += len_mb;
new_line[j] = '\0';
}
else
{
strncat(new_line, lines[i], (len - nuke_count) / 2);
strcat(new_line, "...");
strcat(new_line,
lines[i] + ((len - nuke_count) / 2) +
nuke_count);
}
ExTextExtents(ts->xfontset, new_line, strlen(new_line),
&ret1, &ret2);
}
Efree(lines[i]);
lines[i] = new_line;
if (wc_len > 0)
Efree(wc_line);
}
if (i == 0)
yy += ts->xfontset_ascent;
xx = x + (((textwidth_limit - ret2.width) * justification) >> 10);
if (ts->style.orientation != FONT_TO_RIGHT)
drawable =
ECreatePixmap(VRoot.win, ret2.width + 2,
ret2.height + 2, GetWinDepth(win));
else
drawable = win;
TextDrawRotTo(win, &drawable, xx - 1,
yy - (ts->xfontset_ascent) - 1, ret2.width + 2,
ret2.height + 2, ts);
if (ts->style.orientation == FONT_TO_RIGHT)
{
offset_x = xx;
offset_y = yy;
}
else
{
offset_x = 1;
offset_y = ts->xfontset_ascent + 1;
}
if (ts->effect == 1)
{
EAllocColor(&ts->bg_col);
XSetForeground(disp, gc, ts->bg_col.pixel);
ExDrawString(disp, drawable, ts->xfontset, gc, offset_x + 1,
offset_y + 1, lines[i], strlen(lines[i]));
}
else if (ts->effect == 2)
{
EAllocColor(&ts->bg_col);
XSetForeground(disp, gc, ts->bg_col.pixel);
ExDrawString(disp, drawable, ts->xfontset, gc, offset_x - 1,
offset_y, lines[i], strlen(lines[i]));
ExDrawString(disp, drawable, ts->xfontset, gc, offset_x + 1,
offset_y, lines[i], strlen(lines[i]));
ExDrawString(disp, drawable, ts->xfontset, gc, offset_x,
offset_y - 1, lines[i], strlen(lines[i]));
ExDrawString(disp, drawable, ts->xfontset, gc, offset_x,
offset_y + 1, lines[i], strlen(lines[i]));
}
EAllocColor(&ts->fg_col);
XSetForeground(disp, gc, ts->fg_col.pixel);
ExDrawString(disp, drawable, ts->xfontset, gc, offset_x, offset_y,
lines[i], strlen(lines[i]));
TextDrawRotBack(win, drawable, xx - 1,
yy - (ts->xfontset_ascent) - 1, ret2.width + 2,
ret2.height + 2, ts);
if (drawable != win)
EFreePixmap(drawable);
yy += ret2.height;
}
}
else if ((ts->xfont) && (ts->xfont->min_byte1 == 0)
&& (ts->xfont->max_byte1 == 0))
{
XSetFont(disp, gc, ts->xfont->fid);
for (i = 0; i < num_lines; i++)
{
int wid, ascent, descent;
wid = XTextWidth(ts->xfont, lines[i], strlen(lines[i]));
ascent = ts->xfont->ascent;
descent = ts->xfont->descent;
if (wid > textwidth_limit)
{
char *new_line;
int nuke_count = 0;
int len;
len = strlen(lines[i]);
new_line = Emalloc(len + 10);
while (wid > textwidth_limit)
{
nuke_count++;
if (nuke_count > len)
{
new_line[0] = 0;
strncat(new_line, lines[i], 1);
strcat(new_line, "...");
break;
}
new_line[0] = 0;
strncat(new_line, lines[i], (len - nuke_count) / 2);
strcat(new_line, "...");
strcat(new_line,
lines[i] + ((len - nuke_count) / 2) + nuke_count);
wid = XTextWidth(ts->xfont, new_line, strlen(new_line));
}
Efree(lines[i]);
lines[i] = new_line;
}
if (i == 0)
yy += ts->xfont->ascent;
xx = x + (((textwidth_limit - wid) * justification) >> 10);
if (ts->style.orientation != FONT_TO_RIGHT)
drawable =
ECreatePixmap(VRoot.win, wid + 2, ascent + descent + 2,
GetWinDepth(win));
else
drawable = win;
TextDrawRotTo(win, &drawable, xx - 1, yy - ascent - 1, wid + 2,
ascent + descent + 2, ts);
if (ts->style.orientation == FONT_TO_RIGHT)
{
offset_x = xx;
offset_y = yy;
}
else
{
offset_x = 1;
offset_y = ascent + 1;
}
if (ts->effect == 1)
{
EAllocColor(&ts->bg_col);
XSetForeground(disp, gc, ts->bg_col.pixel);
XDrawString(disp, drawable, gc, offset_x + 1, offset_y + 1,
lines[i], strlen(lines[i]));
}
else if (ts->effect == 2)
{
EAllocColor(&ts->bg_col);
XSetForeground(disp, gc, ts->bg_col.pixel);
XDrawString(disp, drawable, gc, offset_x - 1, offset_y,
lines[i], strlen(lines[i]));
XDrawString(disp, drawable, gc, offset_x + 1, offset_y,
lines[i], strlen(lines[i]));
XDrawString(disp, drawable, gc, offset_x, offset_y - 1,
lines[i], strlen(lines[i]));
XDrawString(disp, drawable, gc, offset_x, offset_y + 1,
lines[i], strlen(lines[i]));
}
EAllocColor(&ts->fg_col);
XSetForeground(disp, gc, ts->fg_col.pixel);
XDrawString(disp, drawable, gc, offset_x, offset_y, lines[i],
strlen(lines[i]));
TextDrawRotBack(win, drawable, xx - 1, yy - 1 - ascent, wid + 2,
ascent + descent + 2, ts);
if (drawable != win)
EFreePixmap(drawable);
yy += ts->xfont->ascent + ts->xfont->descent;
}
}
else if ((ts->xfont))
{
XSetFont(disp, gc, ts->xfont->fid);
for (i = 0; i < num_lines; i++)
{
int wid, ascent, descent;
wid = XTextWidth16(ts->xfont, (XChar2b *) lines[i],
strlen(lines[i]) / 2);
ascent = ts->xfont->ascent;
descent = ts->xfont->descent;
if (wid > textwidth_limit)
{
char *new_line;
int nuke_count = 0;
int len;
len = strlen(lines[i]);
new_line = Emalloc(len + 20);
while (wid > textwidth_limit)
{
nuke_count += 2;
if (nuke_count > len)
{
new_line[0] = 0;
strncat(new_line, lines[i], 1);
strcat(new_line, ". . . ");
break;
}
new_line[0] = 0;
strncat(new_line, lines[i], (len - nuke_count) / 4);
strcat(new_line, ". . . ");
strcat(new_line,
lines[i] + ((len - nuke_count) / 4) + nuke_count);
wid =
XTextWidth16(ts->xfont, (XChar2b *) new_line,
strlen(new_line) / 2);
}
Efree(lines[i]);
lines[i] = new_line;
}
if (i == 0)
yy += ts->xfont->ascent;
xx = x + (((textwidth_limit - wid) * justification) >> 10);
if (ts->style.orientation != FONT_TO_RIGHT)
drawable =
ECreatePixmap(VRoot.win, wid + 2, ascent + descent + 2,
GetWinDepth(win));
else
drawable = win;
TextDrawRotTo(win, &drawable, xx - 1, yy - ascent - 1, wid + 2,
ascent + descent + 2, ts);
if (ts->style.orientation == FONT_TO_RIGHT)
{
offset_x = xx;
offset_y = yy;
}
else
{
offset_x = 1;
offset_y = ascent + 1;
}
if (ts->effect == 1)
{
EAllocColor(&ts->bg_col);
XSetForeground(disp, gc, ts->bg_col.pixel);
XDrawString16(disp, drawable, gc, offset_x + 1, offset_y + 1,
(XChar2b *) lines[i], strlen(lines[i]) / 2);
}
else if (ts->effect == 2)
{
EAllocColor(&ts->bg_col);
XSetForeground(disp, gc, ts->bg_col.pixel);
XDrawString16(disp, drawable, gc, offset_x - 1, offset_y,
(XChar2b *) lines[i], strlen(lines[i]) / 2);
XDrawString16(disp, drawable, gc, offset_y + 1, offset_y,
(XChar2b *) lines[i], strlen(lines[i]) / 2);
XDrawString16(disp, drawable, gc, offset_x, offset_y - 1,
(XChar2b *) lines[i], strlen(lines[i]) / 2);
XDrawString16(disp, drawable, gc, offset_x, offset_y + 1,
(XChar2b *) lines[i], strlen(lines[i]) / 2);
}
EAllocColor(&ts->fg_col);
XSetForeground(disp, gc, ts->fg_col.pixel);
XDrawString16(disp, drawable, gc, offset_x, offset_y,
(XChar2b *) lines[i], strlen(lines[i]) / 2);
TextDrawRotBack(win, drawable, xx - 1, yy - 1 - ascent, wid + 2,
ascent + descent + 2, ts);
if (drawable != win)
EFreePixmap(drawable);
yy += ts->xfont->ascent + ts->xfont->descent;
}
}
EstrlistFree(lines, num_lines);
}
void
TextDraw(TextClass * tclass, Window win, int active, int sticky, int state,
const char *text, int x, int y, int w, int h, int fsize,
int justification)
{
TextState *ts;
if (!tclass || !text)
return;
ts = TextclassGetTextState(tclass, state, active, sticky);
if (!ts)
return;
TextstateDrawText(ts, win, text, x, y, w, h, fsize, justification);
}
void
TextDrawRotTo(Window win, Drawable * drawable, int x, int y, int w, int h,
TextState * ts)
{
Imlib_Image *ii = NULL;
int win_x, win_y;
unsigned int win_w, win_h, win_b, win_d;
Window rr;
switch (ts->style.orientation)
{
case FONT_TO_UP:
ecore_x_sync(); /* Workaround for crash seen with Absolute E (Imlib2?) */
imlib_context_set_drawable(win);
ii = imlib_create_image_from_drawable(0, y, x, h, w, 0);
imlib_context_set_image(ii);
imlib_image_orientate(1);
imlib_context_set_drawable(*drawable);
imlib_render_image_on_drawable_at_size(0, 0, w, h);
break;
case FONT_TO_DOWN:
XGetGeometry(disp, win, &rr, &win_x, &win_y, &win_w, &win_h,
&win_b, &win_d);
ecore_x_sync(); /* Workaround for crash seen with Absolute E (Imlib2?) */
imlib_context_set_drawable(win);
ii = imlib_create_image_from_drawable(0, win_w - y - h, x, h, w, 0);
imlib_context_set_image(ii);
imlib_image_orientate(3);
imlib_context_set_drawable(*drawable);
imlib_render_image_on_drawable_at_size(0, 0, w, h);
break;
case FONT_TO_LEFT: /* Holy carumba! That's for yoga addicts, maybe .... */
ecore_x_sync(); /* Workaround for crash seen with Absolute E (Imlib2?) */
imlib_context_set_drawable(win);
ii = imlib_create_image_from_drawable(0, x, y, w, h, 0);
imlib_context_set_image(ii);
imlib_image_orientate(2);
imlib_context_set_drawable(*drawable);
imlib_render_image_on_drawable_at_size(0, 0, w, h);
break;
default:
break;
}
if (ii)
imlib_free_image();
}
void
TextDrawRotBack(Window win, Pixmap drawable, int x, int y, int w, int h,
TextState * ts)
{
Imlib_Image *ii = NULL;
int win_x, win_y;
unsigned int win_w, win_h, win_b, win_d;
Window rr;
switch (ts->style.orientation)
{
case FONT_TO_UP:
imlib_context_set_drawable(drawable);
ii = imlib_create_image_from_drawable(0, 0, 0, w, h, 0);
imlib_context_set_image(ii);
imlib_image_orientate(3);
imlib_context_set_drawable(win);
imlib_render_image_on_drawable_at_size(y, x, h, w);
break;
case FONT_TO_DOWN:
imlib_context_set_drawable(drawable);
XGetGeometry(disp, win, &rr, &win_x, &win_y, &win_w, &win_h,
&win_b, &win_d);
ii = imlib_create_image_from_drawable(0, 0, 0, w, h, 0);
imlib_context_set_image(ii);
imlib_image_orientate(1);
imlib_context_set_drawable(win);
imlib_render_image_on_drawable_at_size(win_w - y - h, x, h, w);
break;
case FONT_TO_LEFT: /* Holy carumba! That's for yoga addicts, maybe .... */
imlib_context_set_drawable(drawable);
ii = imlib_create_image_from_drawable(0, 0, 0, w, h, 0);
imlib_context_set_image(ii);
imlib_image_orientate(2);
imlib_context_set_drawable(win);
imlib_render_image_on_drawable_at_size(x, y, w, h);
break;
default:
break;
}
if (ii)
imlib_free_image();
}