ViewVC Help
View File | Revision Log | Show Annotations | Download File
/cvs/rxvt-unicode/src/defaultfont.C
(Generate patch)

Comparing rxvt-unicode/src/defaultfont.C (file contents):
Revision 1.17 by pcg, Mon Feb 9 07:11:49 2004 UTC vs.
Revision 1.42 by pcg, Mon Mar 15 06:13:35 2004 UTC

1/*--------------------------------*-C-*---------------------------------*; 1/*--------------------------------*-C-*---------------------------------*;
2 * File: defaultfont.C 2 * File: defaultfont.C
3 *----------------------------------------------------------------------* 3 *----------------------------------------------------------------------*
4 * Copyright (c) 2003 Marc Lehmann rxvt@plan9.de> 4 * Copyright (c) 2003-2004 Marc Lehmann <pcg@goof.com>
5 * - original version. 5 * - original version.
6 * 6 *
7 * This program is free software; you can redistribute it and/or modify 7 * This program is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License as published by 8 * it under the terms of the GNU General Public License as published by
9 * the Free Software Foundation; either version 2 of the License, or 9 * the Free Software Foundation; either version 2 of the License, or
24#include "defaultfont.h" 24#include "defaultfont.h"
25 25
26#include <cstdlib> 26#include <cstdlib>
27 27
28#define DISPLAY r->display->display 28#define DISPLAY r->display->display
29#define DRAWABLE r->TermWin.vt
30#define GC r->TermWin.gc 29#define GC r->TermWin.gc
31 30
32const struct rxvt_fallback_font { 31const struct rxvt_fallback_font {
33 codeset cs; 32 codeset cs;
34 const char *name; 33 const char *name;
62# if XFT 61# if XFT
63 // prefer xft for complex scripts 62 // prefer xft for complex scripts
64 { CS_UNICODE, "xft:Kochi Gothic:antialias=false" }, 63 { CS_UNICODE, "xft:Kochi Gothic:antialias=false" },
65# endif 64# endif
66 { CS_JIS0201_1976_0, "-*-mincho-*-r-*--*-*-*-*-c-*-jisx0201*-0" }, 65 { CS_JIS0201_1976_0, "-*-mincho-*-r-*--*-*-*-*-c-*-jisx0201*-0" },
67 { CS_JIS0208_1983_0, "-*-mincho-*-r-*--*-*-*-*-c-*-jisx0208*-0" }, 66 { CS_JIS0208_1990_0, "-*-mincho-*-r-*--*-*-*-*-c-*-jisx0208*-0" },
68 { CS_JIS0212_1990_0, "-*-mincho-*-r-*--*-*-*-*-c-*-jisx0212*-0" }, 67 { CS_JIS0212_1990_0, "-*-mincho-*-r-*--*-*-*-*-c-*-jisx0212*-0" },
69#endif 68#endif
70 69
71#if ENCODING_CN || ENCODING_CN_EXT 70#if ENCODING_CN || ENCODING_CN_EXT
72# if XFT 71# if XFT
73 { CS_BIG5_EXT, "xft:AR PL Mingti2L Big5" }, 72 { CS_BIG5_EXT, "xft:AR PL Mingti2L Big5" },
74 { CS_BIG5_EXT, "xft:AR PL KaitiM Big5" }, 73 { CS_BIG5_EXT, "xft:AR PL KaitiM Big5" },
75 { CS_GB2312_1980_0, "xft:AR PL KaitiM GB" }, 74 { CS_GB2312_1980_0, "xft:AR PL KaitiM GB" },
76 { CS_GB2312_1980_0, "xft:AR PL SungtiL GB" }, 75 { CS_GB2312_1980_0, "xft:AR PL SungtiL GB" },
77# endif 76# endif
77 { CS_BIG5, "-*-*-*-*-*-*-*-*-*-*-c-*-big5-0" },
78 { CS_BIG5_PLUS, "-*-*-*-*-*-*-*-*-*-*-c-*-big5p-0" },
79 { CS_BIG5_EXT, "-*-*-*-*-*-*-*-*-*-*-c-*-big5.eten-0" },
78 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-gb2312*-0" }, 80 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-gb2312*-0" },
79 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-1" }, 81 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-1" },
80 { CS_CNS11643_1992_2, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-2" }, 82 { CS_CNS11643_1992_2, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-2" },
81 { CS_CNS11643_1992_3, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-3" }, 83 { CS_CNS11643_1992_3, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-3" },
82 { CS_CNS11643_1992_4, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-4" }, 84 { CS_CNS11643_1992_4, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-4" },
83 { CS_CNS11643_1992_5, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-5" }, 85 { CS_CNS11643_1992_5, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-5" },
84 { CS_CNS11643_1992_6, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-6" }, 86 { CS_CNS11643_1992_6, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-6" },
85 { CS_CNS11643_1992_7, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-7" }, 87 { CS_CNS11643_1992_7, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-7" },
86 { CS_CNS11643_1992_F, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-f" }, 88 { CS_CNS11643_1992_F, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-f" },
87#endif 89#endif
88 90
89#if XFT 91#if XFT
90 { CS_UNICODE, "xft:Andale Mono" }, 92 { CS_UNICODE, "xft:Andale Mono" },
91 { CS_UNICODE, "xft:Arial Unicode MS" }, 93 { CS_UNICODE, "xft:Arial Unicode MS" },
94 { CS_UNICODE, "xft:FreeMono" }, 96 { CS_UNICODE, "xft:FreeMono" },
95 { CS_UNICODE, "-*-unifont-*-*-*-*-*-*-*-*-c-*-iso10646-1" }, 97 { CS_UNICODE, "-*-unifont-*-*-*-*-*-*-*-*-c-*-iso10646-1" },
96 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-c-*-iso10646-1" }, 98 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-c-*-iso10646-1" },
97 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" }, 99 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" },
98 100
101#if UNICODE_3 && XFT
102 { CS_UNICODE, "xft:Code2001" }, // contains many plane-1 characters
103#endif
104
99 { CS_UNKNOWN, 0 } 105 { CS_UNKNOWN, 0 }
100}; 106};
107
108/////////////////////////////////////////////////////////////////////////////
109
110#if XFT
111rxvt_drawable::~rxvt_drawable ()
112{
113 if (xftdrawable)
114 XftDrawDestroy (xftdrawable);
115}
116
117rxvt_drawable::operator XftDraw *()
118{
119 if (!xftdrawable)
120 xftdrawable = XftDrawCreate (display->display, drawable, display->visual, display->cmap);
121
122 return xftdrawable;
123}
124#endif
101 125
102///////////////////////////////////////////////////////////////////////////// 126/////////////////////////////////////////////////////////////////////////////
103 127
104static void *enc_buf; 128static void *enc_buf;
105static uint32_t enc_len; 129static uint32_t enc_len;
161} 185}
162 186
163///////////////////////////////////////////////////////////////////////////// 187/////////////////////////////////////////////////////////////////////////////
164 188
165void 189void
166rxvt_font::clear_rect (int x, int y, int w, int h, int color) 190rxvt_font::clear_rect (rxvt_drawable &d, int x, int y, int w, int h, int color)
167{ 191{
168 if (color == Color_bg) 192 if (color == Color_bg)
169 XClearArea (DISPLAY, DRAWABLE, x, y, w, h, FALSE); 193 XClearArea (d.display->display, d, x, y, w, h, FALSE);
170 else if (color >= 0) 194 else if (color >= 0)
171 { 195 {
196#if XFT
197 XftDrawRect (d, &r->PixColors[color].c, x, y, w, h);
198#else
172 XSetForeground (DISPLAY, GC, r->PixColors[color]); 199 XSetForeground (d.display->display, GC, r->PixColors[color]);
173 XFillRectangle (DISPLAY, DRAWABLE, GC, x, y, w, h); 200 XFillRectangle (d.display->display, d, GC, x, y, w, h);
201#endif
174 } 202 }
175} 203}
176 204
177static const char *linedraw_cmds[128] = { 205static const char *linedraw_cmds[128] = {
178 "1hH", "2hH", "1vV", "2vV", 206 "1-", "2-", "1|", "2|",
179 0, 0, 0, 0, 207 0, 0, 0, 0,
180 0, 0, 0, 0, 208 0, 0, 0, 0,
181 "1HV", "2H1V", "1H2V", "2HV", 209 "1HV", "2H1V", "1H2V", "2HV",
182 210
183 // 2510 211 // 2510
184 "1hV", "2h1V", "1h2V", "2hV", 212 "1hV", "2h1V", "1h2V", "2hV",
185 "1Hv", "2H1v", "1H2v", "2Hv", 213 "1Hv", "2H1v", "1H2v", "2Hv",
186 "1hv", "2h1v", "1h2v", "2hv", 214 "1hv", "2h1v", "1h2v", "2hv",
187 "1HvV", "2H1vV", "1HV2v", "1Hv2V", 215 "1H|", "2H1|", "1HV2v", "1Hv2V",
188 216
189 // 2520 217 // 2520
190 "1H2vV", "2Hv1V", "2HV1v", "2HvV", 218 "1H2|", "2Hv1V", "2HV1v", "2H|",
191 "1hvV", "2h1vV", "1hV2v", "1hv2V", 219 "1h|", "2h1|", "1hV2v", "1hv2V",
192 "1h2vV", "2hv1V", "1v2hV", "2hvV", 220 "1h2|", "2hv1V", "1v2hV", "2h|",
193 "1hHV", "2h1HV", "2H1hV", "2hH1V", 221 "1-V", "2h1HV", "2H1hV", "2-1V",
194 222
195 // 2530 223 // 2530
196 "1hH2V", "2hV1H", "1h2HV", "2hHV", 224 "1-2V", "2hV1H", "1h2HV", "2-V",
197 "1hHv", "1vH2h", "1hv2H", "1v2hH", 225 "1-v", "1vH2h", "1hv2H", "1v2-",
198 "1hH2v", "1H2hv", "1h2Hv", "2hHv", 226 "1-2v", "1H2hv", "1h2Hv", "2-v",
199 "1hHvV", "1vVH2h", "1hvV2H", "1vV2hH", 227 "1-|", "1|H2h", "1h|2H", "1|2-",
200 228
201 // 2540 229 // 2540
202 "1hHV2v", "1hHv2V", "1hH2vV", "1HV2hv", 230 "1-V2v", "1-v2V", "1-2|", "1HV2hv",
203 "1hV2Hv", "1Hv2hV", "1hv2HV", "1V2hHv", 231 "1hV2Hv", "1Hv2hV", "1hv2HV", "1V2-v",
204 "1v2hHV", "1H2hvV", "1h2HvV", "2hHvV", 232 "1v2-V", "1H2h|", "1h2H|", "2-|",
205 0, 0, 0, 0, 233 0, 0, 0, 0,
206 234
207 // 2550 235 // 2550
208 0, 0, 0, 0, 236 0, 0, 0, 0,
209 0, 0, 0, 0, 237 0, 0, 0, 0,
212 240
213 // 2560 241 // 2560
214 0, 0, 0, 0, 242 0, 0, 0, 0,
215 0, 0, 0, 0, 243 0, 0, 0, 0,
216 0, 0, 0, 0, 244 0, 0, 0, 0,
217 0, 0, 0, 0, 245 0, "A", "B", "C",
218 246
219 // 2570 247 // 2570
220 0, "1a", "1b", "1ab", 248 "D", "1/", "1\\", "1/\\",
221 "1h", "1v", "1H", "1V", 249 "1h", "1v", "1H", "1V",
222 "2h", "2v", "2H", "2V", 250 "2h", "2v", "2H", "2V",
223 "1h2H", "1v2V", "1H2h", "1V2v" 251 "1h2H", "1v2V", "1H2h", "1V2v"
224 252
225 // to be done 253 // to be done
240 bool load (const rxvt_fontprop &prop) 268 bool load (const rxvt_fontprop &prop)
241 { 269 {
242 width = 1; height = 1; 270 width = 1; height = 1;
243 ascent = 1; descent = 0; 271 ascent = 1; descent = 0;
244 272
273 set_name ("built-in pseudofont");
274
245 return true; 275 return true;
246 } 276 }
247 277
248 bool has_codepoint (uint32_t unicode) 278 bool has_codepoint (unicode_t unicode)
249 { 279 {
250 if (unicode <= 0x001f) 280 if (unicode <= 0x001f)
251 return true; 281 return true;
282
252 if (unicode >= 0x0080 && unicode <= 0x009f) 283 if (unicode >= 0x0080 && unicode <= 0x009f)
253 return true; 284 return true;
254 285
255 if (unicode >= 0x2500 && unicode <= 0x257f 286 if (unicode >= 0x2500 && unicode <= 0x257f
256 && linedraw_cmds[unicode - 0x2500]) 287 && linedraw_cmds[unicode - 0x2500])
288 return true;
289
290 if (IS_COMPOSE (unicode))
257 return true; 291 return true;
258 292
259 switch (unicode) 293 switch (unicode)
260 { 294 {
261 case ZERO_WIDTH_CHAR: 295 case ZERO_WIDTH_CHAR:
263 } 297 }
264 298
265 return false; 299 return false;
266 } 300 }
267 301
268 void draw (int x, int y, 302 void draw (rxvt_drawable &d, int x, int y,
269 const text_t *text, int len, 303 const text_t *text, int len,
270 int fg, int bg); 304 int fg, int bg);
271}; 305};
272 306
273void 307void
274rxvt_font_default::draw (int x, int y, 308rxvt_font_default::draw (rxvt_drawable &d, int x, int y,
275 const text_t *text, int len, 309 const text_t *text, int len,
276 int fg, int bg) 310 int fg, int bg)
277{ 311{
278 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 312 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
279 313
280 XSetForeground (DISPLAY, GC, r->PixColors[fg]); 314 XSetForeground (d.display->display, GC, r->PixColors[fg]);
281 315
282 while (len--) 316 while (len--)
283 { 317 {
318#if ENABLE_COMBINING
319 compose_char *cc;
320#endif
284 text_t t = *text++; 321 text_t t = *text++;
285 322
323 // is it in our linedrawing table?
286 if (t >= 0x2500 & t <= 0x2580 && linedraw_cmds[t - 0x2500]) 324 if (t >= 0x2500 & t <= 0x2580 && linedraw_cmds[t - 0x2500])
287 { 325 {
288 const char *p = linedraw_cmds[t - 0x2500]; 326 const char *p = linedraw_cmds[t - 0x2500];
289 327
290 int x0 = x, x1 = x + r->TermWin.fwidth / 2, x2 = x + r->TermWin.fwidth ; 328 int W = r->TermWin.fwidth , w = (W - 1) / 2;
329 int H = r->TermWin.fheight, h = (H - 1) / 2;
330 int x0 = x, x1 = x + w, x2 = x + r->TermWin.fwidth ;
291 int y0 = y, y1 = y + r->TermWin.fheight / 2, y2 = y + r->TermWin.fheight; 331 int y0 = y, y1 = y + h, y2 = y + r->TermWin.fheight;
292 332
293 XGCValues gcv; 333 XGCValues gcv;
334
335 gcv.cap_style = CapNotLast;
336 XChangeGC (d.display->display, GC, GCCapStyle, &gcv);
294 337
295 while (*p) 338 while (*p)
296 { 339 {
297 switch (*p++) 340 switch (*p++)
298 { 341 {
299 case '1': 342 case '1':
300 gcv.line_width = 0; 343 gcv.line_width = 0;
301 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv); 344 XChangeGC (d.display->display, GC, GCLineWidth, &gcv);
302 break; 345 break;
303 346
304 case '2': 347 case '2':
305 gcv.line_width = 2; 348 gcv.line_width = 3;
306 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv); 349 XChangeGC (d.display->display, GC, GCLineWidth, &gcv);
307 break; 350 break;
308 351
309 case 'h': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y1, x1, y1); break; 352 case 'h': XDrawLine (d.display->display, d, GC, x0, y1, x1+1, y1 ); break;
310 case 'H': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y1, x2, y1); break; 353 case 'H': XDrawLine (d.display->display, d, GC, x2, y1, x1-1, y1 ); break;
354 case '-': XDrawLine (d.display->display, d, GC, x0, y1, x2 , y1 ); break;
311 case 'v': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y0, x1, y1); break; 355 case 'v': XDrawLine (d.display->display, d, GC, x1, y0, x1 , y1+1); break;
356 case 'V': XDrawLine (d.display->display, d, GC, x1, y2, x1 , y1-1); break;
312 case 'V': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y1, x1, y2); break; 357 case '|': XDrawLine (d.display->display, d, GC, x1, y0, x1 , y2 ); break;
358
313 case 'a': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y2, x2, y0); break; 359 case '/' : XDrawLine (d.display->display, d, GC, x0, y2, x2 , y0 ); break;
314 case 'b': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y0, x2, y2); break; 360 case '\\': XDrawLine (d.display->display, d, GC, x0, y0, x2 , y2 ); break;
361
362 case 'A': XDrawArc (d.display->display, d, GC, x1 , y1 , W-1, H-1, 90*64, 90*64); break;
363 case 'B': XDrawArc (d.display->display, d, GC, x1-W+1, y1 , W-1, H-1, 0*64, 90*64); break;
364 case 'C': XDrawArc (d.display->display, d, GC, x1-W+1, y1-H+1, W-1, H-1, 0*64, -90*64); break;
365 case 'D': XDrawArc (d.display->display, d, GC, x1 , y1-H+1, W-1, H-1, -90*64, -90*64); break;
315 } 366 }
316 } 367 }
317 368
318 gcv.line_width = 0; 369 gcv.line_width = 0;
319 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv); 370 XChangeGC (d.display->display, GC, GCLineWidth, &gcv);
371 }
372
373#if ENABLE_COMBINING
374 else if (IS_COMPOSE (t) && (cc = rxvt_composite[t]))
320 } 375 {
376 rxvt_font *f1 = (*fs)[fs->find_font (cc->c1)];
377 f1->draw (d, x, y, &(t = cc->c1), 1, fg, bg);
378 if (cc->c2 != NOCHAR)
379 {
380 // prefer font of first character, for no good reasons
381 rxvt_font *f2 = f1->has_codepoint (cc->c2)
382 ? f1
383 : (*fs)[fs->find_font (cc->c2)];
384
385 f2->draw (d, x, y, &(t = cc->c2), 1, fg, -1);
386 }
387 }
388#endif
321 else 389 else
322 switch (*text++) 390 switch (t)
323 { 391 {
324 case NOCHAR:
325 case ZERO_WIDTH_CHAR: 392 case ZERO_WIDTH_CHAR:
326 break; 393 break;
327 default: 394 default:
328 XDrawRectangle (DISPLAY, DRAWABLE, GC, x + 2, y + 2, r->TermWin.fwidth - 5, r->TermWin.fheight - 5); 395 int w = 0;
396 while (len > 0 && *text == NOCHAR)
397 {
398 ++text;
399 --len;
400 w += r->TermWin.fwidth;
401 }
402
403 XDrawRectangle (d.display->display, d, GC, x + 2, y + 2,
404 w + r->TermWin.fwidth - 5, r->TermWin.fheight - 5);
405 x += w;
329 } 406 }
330 407
331 x += r->TermWin.fwidth; 408 x += r->TermWin.fwidth;
332 } 409 }
333} 410}
341 418
342 rxvt_fontprop properties (); 419 rxvt_fontprop properties ();
343 420
344 bool load (const rxvt_fontprop &prop); 421 bool load (const rxvt_fontprop &prop);
345 422
346 bool has_codepoint (uint32_t unicode); 423 bool has_codepoint (unicode_t unicode);
347 424
348 void draw (int x, int y, 425 void draw (rxvt_drawable &d, int x, int y,
349 const text_t *text, int len, 426 const text_t *text, int len,
350 int fg, int bg); 427 int fg, int bg);
351 428
352 XFontStruct *f; 429 XFontStruct *f;
353 codeset cs; 430 codeset cs;
408 485
409bool 486bool
410rxvt_font_x11::set_properties (rxvt_fontprop &p, const char *name) 487rxvt_font_x11::set_properties (rxvt_fontprop &p, const char *name)
411{ 488{
412 int slashes = 0; 489 int slashes = 0;
413 const char *comp[12]; 490 const char *comp[13];
414 491
415 for (const char *c = name; *c; c++) 492 for (const char *c = name; *c; c++)
416 if (*c == '-') 493 if (*c == '-')
417 { 494 {
418 comp[slashes++] = c + 1; 495 comp[slashes++] = c + 1;
428 505
429 XFontStruct *f = XLoadQueryFont (DISPLAY, name); 506 XFontStruct *f = XLoadQueryFont (DISPLAY, name);
430 507
431 if (f) 508 if (f)
432 { 509 {
433 // the font should really exists now. if not, we have a problem 510 // the font should really exist now. if not, we have a problem
434 // (e.g. if the user did xset fp rehash just when we were searching fonts). 511 // (e.g. if the user did xset fp rehash just when we were searching fonts).
435 // in that case, just return garbage. 512 // in that case, just return garbage.
436 bool ret = set_properties (p, f); 513 bool ret = set_properties (p, f);
437 XFreeFont (DISPLAY, f); 514 XFreeFont (DISPLAY, f);
438 return ret; 515 return ret;
598 f = 0; 675 f = 0;
599 } 676 }
600} 677}
601 678
602bool 679bool
603rxvt_font_x11::has_codepoint (uint32_t unicode) 680rxvt_font_x11::has_codepoint (unicode_t unicode)
604{ 681{
605 uint32_t ch = FROM_UNICODE (cs, unicode); 682 uint32_t ch = FROM_UNICODE (cs, unicode);
606 683
607 if (ch == NOCHAR) 684 if (ch == NOCHAR)
608 return false; 685 return false;
644 721
645 return true; 722 return true;
646} 723}
647 724
648void 725void
649rxvt_font_x11::draw (int x, int y, 726rxvt_font_x11::draw (rxvt_drawable &d, int x, int y,
650 const text_t *text, int len, 727 const text_t *text, int len,
651 int fg, int bg) 728 int fg, int bg)
652{ 729{
653 // this looks like a mess /. 730 // this looks like a mess /.
654 // and it is a mess /. 731 // and it is a mess /.
670 { 747 {
671 const XChar2b *xc = enc_xchar2b (text, len, cs, slow); 748 const XChar2b *xc = enc_xchar2b (text, len, cs, slow);
672 749
673 if (bg == Color_bg && !slow) 750 if (bg == Color_bg && !slow)
674 { 751 {
675 XChangeGC (DISPLAY, GC, GCForeground | GCBackground | GCFont, &v); 752 XChangeGC (d.display->display, GC, GCForeground | GCBackground | GCFont, &v);
676 XDrawImageString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 753 XDrawImageString16 (d.display->display, d, GC, x, y + base, xc, len);
677 } 754 }
678 else 755 else
679 { 756 {
680 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 757 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
681 758
682 XChangeGC (DISPLAY, GC, GCForeground | GCFont, &v); 759 XChangeGC (d.display->display, GC, GCForeground | GCFont, &v);
683 760
684 if (slow) 761 if (slow)
685 { 762 {
686 do 763 do
687 { 764 {
688 if (xc->byte1 || xc->byte2) 765 if (xc->byte1 || xc->byte2)
689 XDrawString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, 1); 766 XDrawString16 (d.display->display, d, GC, x, y + base, xc, 1);
690 767
691 x += r->TermWin.fwidth; 768 x += r->TermWin.fwidth;
692 xc++; len--; 769 xc++; len--;
693 } 770 }
694 while (len); 771 while (len);
695 } 772 }
696 else 773 else
697 XDrawString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 774 XDrawString16 (d.display->display, d, GC, x, y + base, xc, len);
698 } 775 }
699 } 776 }
700 else 777 else
701 { 778 {
702 const char *xc = enc_char (text, len, cs, slow); 779 const char *xc = enc_char (text, len, cs, slow);
703 780
704 if (bg == Color_bg && !slow) 781 if (bg == Color_bg && !slow)
705 { 782 {
706 XChangeGC (DISPLAY, GC, GCForeground | GCBackground | GCFont, &v); 783 XChangeGC (d.display->display, GC, GCForeground | GCBackground | GCFont, &v);
707 XDrawImageString (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 784 XDrawImageString (d.display->display, d, GC, x, y + base, xc, len);
708 } 785 }
709 else 786 else
710 { 787 {
711 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 788 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
712 789
713 XChangeGC (DISPLAY, GC, GCForeground | GCFont, &v); 790 XChangeGC (d.display->display, GC, GCForeground | GCFont, &v);
714 791
715 if (slow) 792 if (slow)
716 { 793 {
717 do 794 do
718 { 795 {
719 if (*xc) 796 if (*xc)
720 XDrawString (DISPLAY, DRAWABLE, GC, x, y + base, xc, 1); 797 XDrawString (d.display->display, d, GC, x, y + base, xc, 1);
721 798
722 x += r->TermWin.fwidth; 799 x += r->TermWin.fwidth;
723 xc++; len--; 800 xc++; len--;
724 } 801 }
725 while (len); 802 while (len);
726 } 803 }
727 else 804 else
728 XDrawString (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 805 XDrawString (d.display->display, d, GC, x, y + base, xc, len);
729 } 806 }
730 } 807 }
731} 808}
732 809
733///////////////////////////////////////////////////////////////////////////// 810/////////////////////////////////////////////////////////////////////////////
738//#define SWATHBITS (UNIBITS / 2 + 3) // minimum size for "full" tables 815//#define SWATHBITS (UNIBITS / 2 + 3) // minimum size for "full" tables
739#define SWATHBITS 8 816#define SWATHBITS 8
740#endif 817#endif
741 818
742struct rxvt_font_xft : rxvt_font { 819struct rxvt_font_xft : rxvt_font {
743 rxvt_font_xft () { f = 0; d = 0; } 820 rxvt_font_xft () { f = 0; }
744 821
745 void clear (); 822 void clear ();
746 823
747 rxvt_fontprop properties (); 824 rxvt_fontprop properties ();
748 825
749 bool load (const rxvt_fontprop &prop); 826 bool load (const rxvt_fontprop &prop);
750 827
751 void draw (int x, int y, 828 void draw (rxvt_drawable &d, int x, int y,
752 const text_t *text, int len, 829 const text_t *text, int len,
753 int fg, int bg); 830 int fg, int bg);
754 831
755 bool has_codepoint (uint32_t unicode); 832 bool has_codepoint (unicode_t unicode);
756 833
757protected: 834protected:
758 XftFont *f; 835 XftFont *f;
759 XftDraw *d;
760}; 836};
761 837
762void 838void
763rxvt_font_xft::clear () 839rxvt_font_xft::clear ()
764{ 840{
765 if (f) 841 if (f)
766 { 842 {
767 XftFontClose (DISPLAY, f); 843 XftFontClose (DISPLAY, f);
768 f = 0; 844 f = 0;
769 }
770
771 if (d)
772 {
773 XftDrawDestroy (d);
774 d = 0;
775 } 845 }
776} 846}
777 847
778rxvt_fontprop 848rxvt_fontprop
779rxvt_font_xft::properties () 849rxvt_font_xft::properties ()
880 950
881 return true; 951 return true;
882} 952}
883 953
884bool 954bool
885rxvt_font_xft::has_codepoint (uint32_t unicode) 955rxvt_font_xft::has_codepoint (unicode_t unicode)
886{ 956{
887 return XftCharExists (DISPLAY, f, unicode); 957 return XftCharExists (DISPLAY, f, unicode);
888} 958}
889 959
890void 960void
891rxvt_font_xft::draw (int x, int y, 961rxvt_font_xft::draw (rxvt_drawable &d, int x, int y,
892 const text_t *text, int len, 962 const text_t *text, int len,
893 int fg, int bg) 963 int fg, int bg)
894{ 964{
895 if (!d)
896 d = XftDrawCreate (DISPLAY, DRAWABLE, r->display->visual, r->display->cmap);
897
898 if (bg >= 0 && bg != Color_bg)
899 XftDrawRect (d, &r->PixColors[bg].c, x, y, r->TermWin.fwidth * len, r->TermWin.fheight);
900 else
901 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 965 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
902 966
903 if (!slow && width == r->TermWin.fwidth && 0) 967 if (!slow && width == r->TermWin.fwidth && 0)
904 { 968 {
905 if (sizeof (text_t) == sizeof (FcChar16)) 969 if (sizeof (text_t) == sizeof (FcChar16))
906 XftDrawString16 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar16 *)text, len); 970 XftDrawString16 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar16 *)text, len);
918 fwidth *= 2; 982 fwidth *= 2;
919 983
920 XGlyphInfo extents; 984 XGlyphInfo extents;
921 if (sizeof (text_t) == sizeof (FcChar16)) 985 if (sizeof (text_t) == sizeof (FcChar16))
922 { 986 {
923 XftTextExtents16 (DISPLAY, f, (const FcChar16 *)text, 1, &extents); 987 XftTextExtents16 (d.display->display, f, (const FcChar16 *)text, 1, &extents);
924 XftDrawString16 (d, &r->PixColors[fg].c, f, x + extents.x + (fwidth - extents.width) / 2, 988 XftDrawString16 (d, &r->PixColors[fg].c, f, x + extents.x + (fwidth - extents.width) / 2,
925 y + r->TermWin.fbase, (const FcChar16 *)text, 1); 989 y + r->TermWin.fbase, (const FcChar16 *)text, 1);
926 } 990 }
927 else 991 else
928 { 992 {
929 XGlyphInfo extents; 993 XGlyphInfo extents;
930 XftTextExtents32 (DISPLAY, f, (const FcChar32 *)text, 1, &extents); 994 XftTextExtents32 (d.display->display, f, (const FcChar32 *)text, 1, &extents);
931 XftDrawString32 (d, &r->PixColors[fg].c, f, x + extents.x + (fwidth - extents.width) / 2, 995 XftDrawString32 (d, &r->PixColors[fg].c, f, x + extents.x + (fwidth - extents.width) / 2,
932 y + r->TermWin.fbase, (const FcChar32 *)text, 1); 996 y + r->TermWin.fbase, (const FcChar32 *)text, 1);
933 } 997 }
934 } 998 }
935 999
942#endif 1006#endif
943 1007
944///////////////////////////////////////////////////////////////////////////// 1008/////////////////////////////////////////////////////////////////////////////
945 1009
946rxvt_fontset::rxvt_fontset (rxvt_t r) 1010rxvt_fontset::rxvt_fontset (rxvt_t r)
947: r(r) 1011: r (r)
948{ 1012{
949 clear (); 1013 clear ();
950} 1014}
951 1015
952rxvt_fontset::~rxvt_fontset () 1016rxvt_fontset::~rxvt_fontset ()
955} 1019}
956 1020
957void 1021void
958rxvt_fontset::clear () 1022rxvt_fontset::clear ()
959{ 1023{
960 for (rxvt_font **i = fonts.begin (); i != fonts.end(); i++) 1024 for (rxvt_font **i = fonts.begin (); i != fonts.end (); i++)
961 FONT_UNREF (*i); 1025 FONT_UNREF (*i);
962 1026
963 fonts.clear (); 1027 fonts.clear ();
964 base_id = 0; 1028 base_id = 0;
965 base_prop.height = 0x7fffffff; 1029 base_prop.height = 0x7fffffff;
992 f = new rxvt_font_x11; 1056 f = new rxvt_font_x11;
993 } 1057 }
994 else 1058 else
995 f = new rxvt_font_x11; 1059 f = new rxvt_font_x11;
996 1060
1061 f->fs = this;
997 f->set_term (r); 1062 f->set_term (r);
998 f->set_name (strdup (name)); 1063 f->set_name (strdup (name));
999 1064
1000 f->cs = cs; 1065 f->cs = cs;
1001 f->loaded = false; 1066 f->loaded = false;
1068 } 1133 }
1069 1134
1070 return true; 1135 return true;
1071} 1136}
1072 1137
1073void 1138bool
1074rxvt_fontset::populate (const char *desc) 1139rxvt_fontset::populate (const char *desc)
1075{ 1140{
1076 clear (); 1141 clear ();
1077 1142
1078 fonts.push_back (new_font (0, CS_UNICODE)); 1143 fonts.push_back (new_font (0, CS_UNICODE));
1084 base_id = 1; 1149 base_id = 1;
1085 1150
1086 // we currently need a base-font, no matter what 1151 // we currently need a base-font, no matter what
1087 if ((int)fonts.size () <= base_id || !realize_font (base_id)) 1152 if ((int)fonts.size () <= base_id || !realize_font (base_id))
1088 { 1153 {
1089 puts ("unable to load specified font(s), falling back to 'fixed'\n"); 1154 puts ("unable to load specified font (s), falling back to 'fixed'\n");
1090 add_fonts ("fixed"); 1155 add_fonts ("fixed");
1091 base_id = fonts.size () - 1; 1156 base_id = fonts.size () - 1;
1092 } 1157 }
1093 1158
1094 if ((int)fonts.size () <= base_id || !realize_font (base_id)) 1159 if ((int)fonts.size () <= base_id || !realize_font (base_id))
1095 { 1160 return false;
1096 fprintf (stderr, "unable to load a base font, please provide one using -fn fontname\n");
1097 exit (1);
1098 }
1099 1161
1100 base_prop = fonts[base_id]->properties (); 1162 base_prop = fonts[base_id]->properties ();
1163
1164 return true;
1101} 1165}
1102 1166
1103int 1167int
1104rxvt_fontset::find_font (uint32_t unicode) 1168rxvt_fontset::find_font (unicode_t unicode)
1105{ 1169{
1106 for (unsigned int i = 0; i < fonts.size (); i++) 1170 for (unsigned int i = 0; i < fonts.size (); i++)
1107 { 1171 {
1108 rxvt_font *f = fonts[i]; 1172 rxvt_font *f = fonts[i];
1109 1173

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines