chiark / gitweb /
Imported Upstream version 1.0.0
[e16] / src / ttfont.c
1 /*
2  * Copyright (C) 2000-2007 Carsten Haitzler, Geoff Harrison and various contributors
3  * Copyright (C) 2004-2009 Kim Woelders
4  *
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:
11  *
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.
16  *
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.
23  */
24 #include "E.h"
25 #include "tclass.h"
26
27 #if FONT_TYPE_IFT
28 #include "eimage.h"
29 #include <Imlib2.h>
30
31 /*
32  * Imlib2/FreeType
33  */
34 __EXPORT__ extern const FontOps FontOps_ift;
35
36 typedef void        EFont;
37
38 static void
39 EFonts_Init(void)
40 {
41 #if !TEST_TTFONT
42    char                s[4096];
43
44    Esnprintf(s, sizeof(s), "%s/ttfonts", Mode.theme.path);
45    imlib_add_path_to_font_path(s);
46    Esnprintf(s, sizeof(s), "%s/fonts", EDirRoot());
47    imlib_add_path_to_font_path(s);
48 #endif
49 }
50
51 static EFont       *
52 Efont_load(const char *file, int size)
53 {
54    static char         ttfont_path_set = 0;
55    char                s[4096];
56    EFont              *f;
57
58    if (!ttfont_path_set)
59      {
60         EFonts_Init();
61         ttfont_path_set = 1;
62      }
63
64    Esnprintf(s, sizeof(s), "%s/%d", file, size);
65    f = imlib_load_font(s);
66
67    return f;
68 }
69
70 static void
71 Efont_free(EFont * f)
72 {
73    imlib_context_set_font(f);
74    imlib_free_font();
75 }
76
77 static void
78 Efont_extents(EFont * f, const char *text, int len __UNUSED__,
79               int *width, int *height, int *ascent)
80 {
81    int                 h, asc, dsc;
82
83    imlib_context_set_font(f);
84    imlib_get_text_advance(text, width, &h);
85    asc = imlib_get_font_ascent();
86    dsc = imlib_get_font_descent();
87    *height = asc + dsc;
88    *ascent = asc;
89 }
90
91 static void
92 EFont_draw_string(EImage * im, EFont * f, int x, int y,
93                   int r, int g, int b, const char *text)
94 {
95    imlib_context_set_image(im);
96    imlib_context_set_color(r, g, b, 255);
97    imlib_context_set_font(f);
98    imlib_text_draw(x, y - imlib_get_maximum_font_ascent(), text);
99 }
100
101 typedef struct {
102    EFont              *font;
103    EImage             *im;
104    int                 r, g, b;
105 } FontCtxIft;
106
107 static int
108 _ift_Load(TextState * ts, const char *name __UNUSED__)
109 {
110    EFont              *font;
111    FontCtxIft         *fdc;
112    char                s[1024], *ss;
113    int                 len;
114
115    ss = strchr(ts->fontname, '/');
116    if (!ss)
117       return -1;
118    len = ss - ts->fontname;
119    if (len > 1000)
120       return -1;
121
122    memcpy(s, ts->fontname, len);
123    s[len] = '\0';
124    font = Efont_load(s, atoi(ss + 1));
125    if (!font)
126       return -1;
127
128    fdc = EMALLOC(FontCtxIft, 1);
129    if (!fdc)
130       return -1;
131    fdc->font = font;
132    ts->fdc = fdc;
133    ts->need_utf8 = 1;
134    ts->type = FONT_TYPE_IFT;
135    ts->ops = &FontOps_ift;
136    return 0;
137 }
138
139 static void
140 _ift_Unload(TextState * ts)
141 {
142    FontCtxIft         *fdc = (FontCtxIft *) ts->fdc;
143
144    Efont_free(fdc->font);
145 }
146
147 static void
148 _ift_TextSize(TextState * ts, const char *text, int len,
149               int *width, int *height, int *ascent)
150 {
151    FontCtxIft         *fdc = (FontCtxIft *) ts->fdc;
152
153    Efont_extents(fdc->font, text, len, width, height, ascent);
154 }
155
156 static void
157 _ift_TextDraw(TextState * ts, int x, int y, const char *text,
158               int len __UNUSED__)
159 {
160    FontCtxIft         *fdc = (FontCtxIft *) ts->fdc;
161
162    EFont_draw_string(fdc->im, fdc->font, x, y, fdc->r, fdc->g, fdc->b, text);
163 }
164
165 static int
166 _ift_FdcInit(TextState * ts __UNUSED__, Win win __UNUSED__,
167              Drawable draw __UNUSED__)
168 {
169    return 0;
170 }
171
172 static void
173 _ift_FdcSetDrawable(TextState * ts, unsigned long draw)
174 {
175    FontCtxIft         *fdc = (FontCtxIft *) ts->fdc;
176
177    fdc->im = (EImage *) draw;
178 }
179
180 static void
181 _ift_FdcSetColor(TextState * ts __UNUSED__, EColor * ec)
182 {
183    FontCtxIft         *fdc = (FontCtxIft *) ts->fdc;
184
185    GET_COLOR(ec, fdc->r, fdc->g, fdc->b);
186 }
187
188 const FontOps       FontOps_ift = {
189    _ift_Load, _ift_Unload, _ift_TextSize, TextstateTextFit, _ift_TextDraw,
190    _ift_FdcInit, NULL, _ift_FdcSetDrawable, _ift_FdcSetColor
191 };
192
193 #if TEST_TTFONT
194 #include <time.h>
195
196 Display            *disp;
197
198 int
199 main(int argc, char **argv)
200 {
201    Efont              *f;
202    GC                  gc;
203    XGCValues           gcv;
204    Window              win;
205    int                 i, j;
206
207    disp = XOpenDisplay(NULL);
208
209    imlib_context_set_display(disp);
210    imlib_context_set_visual(DefaultVisual(disp, DefaultScreen(disp)));
211    imlib_context_set_colormap(DefaultColormap(disp, DefaultScreen(disp)));
212
213    srand(time(NULL));
214    win = XCreateSimpleWindow(disp, DefaultRootWindow(disp), 0, 0, 640, 480, 0,
215                              0, 0);
216    XMapWindow(disp, win);
217    XSync(disp, False);
218
219    gcv.subwindow_mode = IncludeInferiors;
220    gc = XCreateGC(disp, win, GCSubwindowMode, &gcv);
221    for (;; j++)
222      {
223         for (i = 3; i < argc; i++)
224           {
225              XSetForeground(disp, gc, (rand() << 16 | rand()) & 0xffffff);
226              f = Efont_load(argv[i], atoi(argv[1]));
227              if (f)
228                 EFont_draw_string(win, gc, 20, atoi(argv[1]) * (i - 2),
229                                   argv[2], f,
230                                   DefaultVisual(disp, DefaultScreen(disp)),
231                                   DefaultColormap(disp, DefaultScreen(disp)));
232              Efont_free(f);
233              f = NULL;
234           }
235      }
236    return 0;
237 }
238
239 #endif
240
241 #endif /* FONT_TYPE_IFT */