chiark / gitweb /
Imported Debian patch 1.0.0-6
[e16] / src / text_xft.c
1 /*
2  * Copyright (C) 2006-2008 Kim Woelders
3  *
4  * Permission is hereby granted, free of charge, to any person obtaining a copy
5  * of this software and associated documentation files (the "Software"), to
6  * deal in the Software without restriction, including without limitation the
7  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
8  * sell copies of the Software, and to permit persons to whom the Software is
9  * furnished to do so, subject to the following conditions:
10  *
11  * The above copyright notice and this permission notice shall be included in
12  * all copies of the Software, its documentation and marketing & publicity
13  * materials, and acknowledgment shall be given in the documentation, materials
14  * and software packages that this Software was used.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19  * THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
20  * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22  */
23 #include "E.h"
24 #include "tclass.h"
25
26 #ifdef USE_XFT
27 #include "xwin.h"
28 #include <X11/extensions/Xrender.h>
29 #include <X11/Xft/Xft.h>
30
31 /*
32  * Xft
33  */
34 __EXPORT__ extern const FontOps FontOps_xft;
35
36 typedef struct {
37    XftFont            *font;
38    Win                 win;
39    Drawable            draw;
40    XftDraw            *xftd;
41    XftColor            xftc;
42 } FontCtxXft;
43
44 static int
45 _xft_Load(TextState * ts, const char *name)
46 {
47    XftFont            *font;
48    FontCtxXft         *fdc;
49
50    if (name[0] == '-')
51       font = XftFontOpenXlfd(disp, Dpy.screen, name);
52    else
53       font = XftFontOpenName(disp, Dpy.screen, name);
54
55    if (!font)
56       return -1;
57
58 #if 0                           /* Debug */
59    {
60       FT_Face             ftf = XftLockFace(font);
61
62       if (ftf == NULL)
63          return -1;
64       Eprintf("Font %s family_name=%s style_name=%s\n", name,
65               ftf->family_name, ftf->style_name);
66       XftUnlockFace(font);
67    }
68 #endif
69
70    fdc = EMALLOC(FontCtxXft, 1);
71    if (!fdc)
72       return -1;
73    fdc->font = font;
74    ts->fdc = fdc;
75    ts->need_utf8 = 1;
76    ts->type = FONT_TYPE_XFT;
77    ts->ops = &FontOps_xft;
78    return 0;
79 }
80
81 static void
82 _xft_Unload(TextState * ts)
83 {
84    FontCtxXft         *fdc = (FontCtxXft *) ts->fdc;
85
86    XftFontClose(disp, fdc->font);
87 }
88
89 static void
90 _xft_TextSize(TextState * ts, const char *text, int len,
91               int *width, int *height, int *ascent)
92 {
93    FontCtxXft         *fdc = (FontCtxXft *) ts->fdc;
94    XGlyphInfo          gi;
95
96    if (len == 0)
97       len = strlen(text);
98    XftTextExtentsUtf8(disp, fdc->font, (const XftChar8 *)text, len, &gi);
99    *width = gi.xOff;
100    *height = fdc->font->height;
101    if (*height < fdc->font->ascent + fdc->font->descent)
102       *height = fdc->font->ascent + fdc->font->descent;
103    *ascent = fdc->font->ascent;
104 #if 0
105    Eprintf("asc/dsc/h=%d/%d/%d x,y=%2d,%d wxh=%dx%d ox,y=%3d,%d: (%d)%s\n",
106            fdc->font->ascent, fdc->font->descent, fdc->font->height, gi.x, gi.y,
107            gi.width, gi.height, gi.xOff, gi.yOff, len, text);
108 #endif
109 }
110
111 static void
112 _xft_TextDraw(TextState * ts, int x, int y, const char *text, int len)
113 {
114    FontCtxXft         *fdc = (FontCtxXft *) ts->fdc;
115
116    XftDrawStringUtf8(fdc->xftd, &(fdc->xftc), fdc->font, x, y,
117                      (const XftChar8 *)text, len);
118 }
119
120 int
121 _xft_FdcInit(TextState * ts, Win win, Drawable draw)
122 {
123    FontCtxXft         *fdc = (FontCtxXft *) ts->fdc;
124
125    fdc->win = win;
126    fdc->draw = draw;
127
128    fdc->xftd = XftDrawCreate(disp, draw, WinGetVisual(win), WinGetCmap(win));
129    if (!fdc->xftd)
130       return -1;
131    return 0;
132 }
133
134 void
135 _xft_FdcFini(TextState * ts)
136 {
137    FontCtxXft         *fdc = (FontCtxXft *) ts->fdc;
138
139    XftDrawDestroy(fdc->xftd);
140 }
141
142 void
143 _xft_FdcSetDrawable(TextState * ts, unsigned long draw)
144 {
145    FontCtxXft         *fdc = (FontCtxXft *) ts->fdc;
146
147    if (fdc->draw == draw)
148       return;
149    fdc->draw = draw;
150    XftDrawChange(fdc->xftd, draw);
151 }
152
153 void
154 _xft_FdcSetColor(TextState * ts, EColor * ec)
155 {
156    FontCtxXft         *fdc = (FontCtxXft *) ts->fdc;
157    XRenderColor        xrc;
158
159    xrc.red = ec->red << 8;
160    xrc.green = ec->green << 8;
161    xrc.blue = ec->blue << 8;
162    xrc.alpha = 65535;
163
164    XftColorAllocValue(disp, WinGetVisual(fdc->win), WinGetCmap(fdc->win),
165                       &xrc, &(fdc->xftc));
166 }
167
168 const FontOps       FontOps_xft = {
169    _xft_Load, _xft_Unload, _xft_TextSize, TextstateTextFit, _xft_TextDraw,
170    _xft_FdcInit, _xft_FdcFini, _xft_FdcSetDrawable, _xft_FdcSetColor
171 };
172
173 #endif /* FONT_TYPE_XFT */