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.8 by pcg, Thu Dec 18 04:27:36 2003 UTC vs.
Revision 1.43 by pcg, Mon Mar 15 07:10:47 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
23#include "rxvt.h" 23#include "rxvt.h"
24#include "defaultfont.h" 24#include "defaultfont.h"
25 25
26#include <cstdlib> 26#include <cstdlib>
27 27
28#define DISPLAY r->Xdisplay 28#define DISPLAY r->display->display
29#define DRAWABLE r->TermWin.vt
30#define GC r->TermWin.gc 29#define TGC 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;
35} fallback_fonts[] = { 34} fallback_fonts[] = {
59 58
60 // japanese 59 // japanese
61#if ENCODING_JP || ENCODING_JP_EXT 60#if ENCODING_JP || ENCODING_JP_EXT
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" },
80 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-gb2312*-0" },
78 { CS_CNS11643_1992_1, "-*-*-*-r-*-*-*-*-*-*-c-*-cns11643.1992-1" }, 81 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-1" },
79 { CS_CNS11643_1992_2, "-*-*-*-r-*-*-*-*-*-*-c-*-cns11643.1992-2" }, 82 { CS_CNS11643_1992_2, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-2" },
80 { CS_CNS11643_1992_3, "-*-*-*-r-*-*-*-*-*-*-c-*-cns11643.1992-3" }, 83 { CS_CNS11643_1992_3, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-3" },
81 { CS_CNS11643_1992_4, "-*-*-*-r-*-*-*-*-*-*-c-*-cns11643.1992-4" }, 84 { CS_CNS11643_1992_4, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-4" },
82 { CS_CNS11643_1992_5, "-*-*-*-r-*-*-*-*-*-*-c-*-cns11643.1992-5" }, 85 { CS_CNS11643_1992_5, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-5" },
83 { CS_CNS11643_1992_6, "-*-*-*-r-*-*-*-*-*-*-c-*-cns11643.1992-6" }, 86 { CS_CNS11643_1992_6, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-6" },
84 { CS_CNS11643_1992_7, "-*-*-*-r-*-*-*-*-*-*-c-*-cns11643.1992-7" }, 87 { CS_CNS11643_1992_7, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-7" },
85 { CS_CNS11643_1992_F, "-*-*-*-r-*-*-*-*-*-*-c-*-cns11643.1992-f" }, 88 { CS_CNS11643_1992_F, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-f" },
86#endif 89#endif
87 90
88#if XFT 91#if XFT
89 { CS_UNICODE, "xft:Andale Mono" }, 92 { CS_UNICODE, "xft:Andale Mono" },
90 { CS_UNICODE, "xft:Arial Unicode MS" }, 93 { CS_UNICODE, "xft:Arial Unicode MS" },
91#endif 94#endif
92 { CS_UNICODE, "-*-lucidatypewriter-*-r-*-*-*-*-*-*-m-*-iso10646-1" }, 95 { CS_UNICODE, "-*-lucidatypewriter-*-*-*-*-*-*-*-*-m-*-iso10646-1" },
96 { CS_UNICODE, "xft:FreeMono" },
97 { CS_UNICODE, "-*-unifont-*-*-*-*-*-*-*-*-c-*-iso10646-1" },
98 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-c-*-iso10646-1" },
93 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" }, 99 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" },
94 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" }, 100
95 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" }, 101#if UNICODE_3 && XFT
102 { CS_UNICODE, "xft:Code2001" }, // contains many plane-1 characters
103#endif
96 104
97 { CS_UNKNOWN, 0 } 105 { CS_UNKNOWN, 0 }
98}; 106};
99 107
100///////////////////////////////////////////////////////////////////////////// 108/////////////////////////////////////////////////////////////////////////////
101 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
125
126/////////////////////////////////////////////////////////////////////////////
127
102static void *enc_buf; 128static void *enc_buf;
103static uint32_t enc_len; 129static uint32_t enc_len;
104 130
105static inline void * 131static inline void *
106get_enc_buf (int len) 132get_enc_buf (uint32_t len)
107{ 133{
108 if (len > enc_len) 134 if (len > enc_len)
109 { 135 {
110 free (enc_buf); 136 free (enc_buf);
111 enc_buf = malloc (len); 137 enc_buf = malloc (len);
113 139
114 return enc_buf; 140 return enc_buf;
115} 141}
116 142
117static const char * 143static const char *
118enc_char (const text_t *text, int len, codeset cs, bool &zero) 144enc_char (const text_t *text, uint32_t len, codeset cs, bool &zero)
119{ 145{
120 uint8_t *buf = (uint8_t *)get_enc_buf (len); 146 uint8_t *buf = (uint8_t *)get_enc_buf (len);
121 147
122 while (len--) 148 while (len--)
123 { 149 {
134 160
135 return (const char *)enc_buf; 161 return (const char *)enc_buf;
136} 162}
137 163
138static const XChar2b * 164static const XChar2b *
139enc_xchar2b (const text_t *text, int len, codeset cs, bool &zero) 165enc_xchar2b (const text_t *text, uint32_t len, codeset cs, bool &zero)
140{ 166{
141 XChar2b *buf = (XChar2b *)get_enc_buf (len * sizeof (XChar2b)); 167 XChar2b *buf = (XChar2b *)get_enc_buf (len * sizeof (XChar2b));
142 168
143 while (len--) 169 while (len--)
144 { 170 {
159} 185}
160 186
161///////////////////////////////////////////////////////////////////////////// 187/////////////////////////////////////////////////////////////////////////////
162 188
163void 189void
164rxvt_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)
165{ 191{
166 if (color == Color_bg) 192 if (color == Color_bg)
167 XClearArea (DISPLAY, DRAWABLE, x, y, w, h, FALSE); 193 XClearArea (d.display->display, d, x, y, w, h, FALSE);
168 else if (color >= 0) 194 else if (color >= 0)
169 { 195 {
196#if XFT
197 XftDrawRect (d, &r->PixColors[color].c, x, y, w, h);
198#else
170 XSetForeground (DISPLAY, GC, r->PixColors[color]); 199 XSetForeground (d.display->display, TGC, r->PixColors[color]);
171 XFillRectangle (DISPLAY, DRAWABLE, GC, x, y, w, h); 200 XFillRectangle (d.display->display, d, TGC, x, y, w, h);
201#endif
172 } 202 }
173} 203}
174 204
175static const char *linedraw_cmds[128] = { 205static const char *linedraw_cmds[128 + 32] = {
176 "1hH", "2hH", "1vV", "2vV", 206 "1-", "2-", "1|", "2|",
177 0, 0, 0, 0, 207 0, 0, 0, 0,
178 0, 0, 0, 0, 208 0, 0, 0, 0,
179 "1HV", "2H1V", "1H2V", "2HV", 209 "1HV", "2H1V", "1H2V", "2HV",
180 210
181 // 2510 211 // 2510
182 "1hV", "2h1V", "1h2V", "2hV", 212 "1hV", "2h1V", "1h2V", "2hV",
183 "1Hv", "2H1v", "1H2v", "2Hv", 213 "1Hv", "2H1v", "1H2v", "2Hv",
184 "1hv", "2h1v", "1h2v", "2hv", 214 "1hv", "2h1v", "1h2v", "2hv",
185 "1HvV", "2H1vV", "1HV2v", "1Hv2V", 215 "1H|", "2H1|", "1HV2v", "1Hv2V",
186 216
187 // 2520 217 // 2520
188 "1H2vV", "2Hv1V", "2HV1v", "2HvV", 218 "1H2|", "2Hv1V", "2HV1v", "2H|",
189 "1hvV", "2h1vV", "1hV2v", "1hv2V", 219 "1h|", "2h1|", "1hV2v", "1hv2V",
190 "1h2vV", "2hv1V", "1v2hV", "2hvV", 220 "1h2|", "2hv1V", "1v2hV", "2h|",
191 "1hHV", "2h1HV", "2H1hV", "2hH1V", 221 "1-V", "2h1HV", "2H1hV", "2-1V",
192 222
193 // 2530 223 // 2530
194 "1hH2V", "2hV1H", "1h2HV", "2hHV", 224 "1-2V", "2hV1H", "1h2HV", "2-V",
195 "1hHv", "1vH2h", "1hv2H", "1v2hH", 225 "1-v", "1vH2h", "1hv2H", "1v2-",
196 "1hH2v", "1H2hv", "1h2Hv", "2hHv", 226 "1-2v", "1H2hv", "1h2Hv", "2-v",
197 "1hHvV", "1vVH2h", "1hvV2H", "1vV2hH", 227 "1-|", "1|H2h", "1h|2H", "1|2-",
198 228
199 // 2540 229 // 2540
200 "1hHV2v", "1hHv2V", "1hH2vV", "1HV2hv", 230 "1-V2v", "1-v2V", "1-2|", "1HV2hv",
201 "1hV2Hv", "1Hv2hV", "1hv2HV", "1V2hHv", 231 "1hV2Hv", "1Hv2hV", "1hv2HV", "1V2-v",
202 "1v2hHV", "1H2hvV", "1h2HvV", "2hHvV", 232 "1v2-V", "1H2h|", "1h2H|", "2-|",
203 0, 0, 0, 0, 233 0, 0, 0, 0,
204 234
205 // 2550 235 // 2550
206 0, 0, 0, 0, 236 0, 0, 0, 0,
207 0, 0, 0, 0, 237 0, 0, 0, 0,
210 240
211 // 2560 241 // 2560
212 0, 0, 0, 0, 242 0, 0, 0, 0,
213 0, 0, 0, 0, 243 0, 0, 0, 0,
214 0, 0, 0, 0, 244 0, 0, 0, 0,
215 0, 0, 0, 0, 245 0, "A", "B", "C",
216 246
217 // 2570 247 // 2570
218 0, "1a", "1b", "1ab", 248 "D", "1/", "1\\", "1/\\",
219 "1h", "1v", "1H", "1V", 249 "1h", "1v", "1H", "1V",
220 "2h", "2v", "2H", "2V", 250 "2h", "2v", "2H", "2V",
221 "1h2H", "1v2V", "1H2h", "1V2v" 251 "1h2H", "1v2V", "1H2h", "1V2v",
252
253 // 2580
254 0, 0, 0, 0,
255 0, 0, 0, 0,
256 0, 0, 0, 0,
257 0, 0, 0, 0,
258
259 // 2590
260 0, 0, 0, 0,
261 0, 0, "k", "l",
262 "i", "ikl", "il", "ijk",
263 "ijl", "j", "jk", "jkl",
222 264
223 // to be done 265 // to be done
224}; 266};
225 267
226struct rxvt_font_default : rxvt_font { 268struct rxvt_font_default : rxvt_font {
227 rxvt_fontprop properties () 269 rxvt_fontprop properties ()
228 { 270 {
229 rxvt_fontprop p; 271 rxvt_fontprop p;
230 272
231 p.height = 1; 273 p.width = p.height = 1;
232 p.weight = rxvt_fontprop::medium; 274 p.weight = rxvt_fontprop::medium;
233 p.slant = rxvt_fontprop::roman; 275 p.slant = rxvt_fontprop::roman;
234 276
235 return p; 277 return p;
236 } 278 }
238 bool load (const rxvt_fontprop &prop) 280 bool load (const rxvt_fontprop &prop)
239 { 281 {
240 width = 1; height = 1; 282 width = 1; height = 1;
241 ascent = 1; descent = 0; 283 ascent = 1; descent = 0;
242 284
285 set_name ("built-in pseudofont");
286
243 return true; 287 return true;
244 } 288 }
245 289
246 bool has_codepoint (uint32_t unicode) 290 bool has_codepoint (unicode_t unicode)
247 { 291 {
248 if (unicode <= 0x001f) 292 if (unicode <= 0x001f)
249 return true; 293 return true;
294
250 if (unicode >= 0x0080 && unicode <= 0x009f) 295 if (unicode >= 0x0080 && unicode <= 0x009f)
251 return true; 296 return true;
252 297
253 if (unicode >= 0x2500 && unicode <= 0x257f 298 if (unicode >= 0x2500 && unicode <= 0x257f
254 && linedraw_cmds[unicode - 0x2500]) 299 && linedraw_cmds[unicode - 0x2500])
300 return true;
301
302 if (unicode >= 0x2580 && unicode <= 0x259f)
303 return true;
304
305 if (IS_COMPOSE (unicode))
255 return true; 306 return true;
256 307
257 switch (unicode) 308 switch (unicode)
258 { 309 {
259 case ZERO_WIDTH_CHAR: 310 case ZERO_WIDTH_CHAR:
261 } 312 }
262 313
263 return false; 314 return false;
264 } 315 }
265 316
266 void draw (int x, int y, 317 void draw (rxvt_drawable &d, int x, int y,
267 const text_t *text, int len, 318 const text_t *text, int len,
268 int fg, int bg); 319 int fg, int bg);
269}; 320};
270 321
322static void rect_stipple (Display *display, Drawable d, GC gc, int s1, int s2, int x, int y, int w, int h)
323{
324 XGCValues gcv;
325 char bm[2] = { s1, s2 };
326
327 gcv.fill_style = FillStippled;
328 gcv.stipple = XCreateBitmapFromData (display, d, bm, 2, 2);
329 gcv.ts_x_origin = x;
330 gcv.ts_y_origin = y;
331
332 if (!gcv.stipple)
333 return;
334
335 XChangeGC (display, gc, GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, &gcv);
336 XFillRectangle (display, d, gc, x, y, w, h);
337
338 XFreePixmap (display, gcv.stipple);
339
340 gcv.fill_style = FillSolid;
341 XChangeGC (display, gc, GCFillStyle, &gcv);
342}
343
271void 344void
272rxvt_font_default::draw (int x, int y, 345rxvt_font_default::draw (rxvt_drawable &d, int x, int y,
273 const text_t *text, int len, 346 const text_t *text, int len,
274 int fg, int bg) 347 int fg, int bg)
275{ 348{
276 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 349 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
277 350
278 XSetForeground (DISPLAY, GC, r->PixColors[fg]); 351 XSetForeground (d.display->display, TGC, r->PixColors[fg]);
279 352
280 while (len--) 353 while (len--)
281 { 354 {
355#if ENABLE_COMBINING
356 compose_char *cc;
357#endif
282 text_t t = *text++; 358 text_t t = *text++;
283 359
360 int W = r->TermWin.fwidth , w = (W - 1) / 2;
361 int H = r->TermWin.fheight, h = (H - 1) / 2;
362 int x0 = x, x1 = x + w, x2 = x + r->TermWin.fwidth ;
363 int y0 = y, y1 = y + h, y2 = y + r->TermWin.fheight;
364
365 // is it in our linedrawing table?
284 if (t >= 0x2500 & t <= 0x2580 && linedraw_cmds[t - 0x2500]) 366 if (t >= 0x2500 & t <= 0x259f && linedraw_cmds[t - 0x2500])
285 { 367 {
286 const char *p = linedraw_cmds[t - 0x2500]; 368 const char *p = linedraw_cmds[t - 0x2500];
287 369
288 int x0 = x, x1 = x + r->TermWin.fwidth / 2, x2 = x + r->TermWin.fwidth ;
289 int y0 = y, y1 = y + r->TermWin.fheight / 2, y2 = y + r->TermWin.fheight;
290
291 XGCValues gcv; 370 XGCValues gcv;
371
372 gcv.cap_style = CapNotLast;
373 XChangeGC (d.display->display, TGC, GCCapStyle, &gcv);
292 374
293 while (*p) 375 while (*p)
294 { 376 {
295 switch (*p++) 377 switch (*p++)
296 { 378 {
297 case '1': 379 case '1':
298 gcv.line_width = 0; 380 gcv.line_width = 0;
299 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv); 381 XChangeGC (d.display->display, TGC, GCLineWidth, &gcv);
300 break; 382 break;
301 383
302 case '2': 384 case '2':
303 gcv.line_width = 2; 385 gcv.line_width = 3;
304 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv); 386 XChangeGC (d.display->display, TGC, GCLineWidth, &gcv);
305 break; 387 break;
306 388
307 case 'h': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y1, x1, y1); break; 389 case 'h': XDrawLine (d.display->display, d, TGC, x0, y1, x1+1, y1 ); break;
308 case 'H': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y1, x2, y1); break; 390 case 'H': XDrawLine (d.display->display, d, TGC, x1, y1, x2 , y1 ); break;
391 case '-': XDrawLine (d.display->display, d, TGC, x0, y1, x2 , y1 ); break;
309 case 'v': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y0, x1, y1); break; 392 case 'v': XDrawLine (d.display->display, d, TGC, x1, y0, x1 , y1+1); break;
310 case 'V': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y1, x1, y2); break; 393 case 'V': XDrawLine (d.display->display, d, TGC, x1, y1, x1 , y2 ); break;
394 case '|': XDrawLine (d.display->display, d, TGC, x1, y0, x1 , y2 ); break;
395
311 case 'a': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y2, x2, y0); break; 396 case '/' : XDrawLine (d.display->display, d, TGC, x0, y2, x2 , y0 ); break;
312 case 'b': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y0, x2, y2); break; 397 case '\\': XDrawLine (d.display->display, d, TGC, x0, y0, x2 , y2 ); break;
398
399 case 'A': XDrawArc (d.display->display, d, TGC, x1 , y1 , W-1, H-1, 90*64, 90*64); break;
400 case 'B': XDrawArc (d.display->display, d, TGC, x1-W+1, y1 , W-1, H-1, 0*64, 90*64); break;
401 case 'C': XDrawArc (d.display->display, d, TGC, x1-W+1, y1-H+1, W-1, H-1, 0*64, -90*64); break;
402 case 'D': XDrawArc (d.display->display, d, TGC, x1 , y1-H+1, W-1, H-1, -90*64, -90*64); break;
403
404 case 'i': XFillRectangle (d.display->display, d, TGC, x0, y0, x1 - x0 + 1, y1 - y0 + 1); break;
405 case 'j': XFillRectangle (d.display->display, d, TGC, x1, y0, x2 - x1, y1 - y0 + 1); break;
406 case 'k': XFillRectangle (d.display->display, d, TGC, x0, y1, x1 - x0 + 1, y2 - y1); break;
407 case 'l': XFillRectangle (d.display->display, d, TGC, x1, y1, x2 - x1, y2 - y1); break;
313 } 408 }
314 } 409 }
315 410
316 gcv.line_width = 0; 411 gcv.line_width = 0;
317 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv); 412 XChangeGC (d.display->display, TGC, GCLineWidth, &gcv);
413 }
414
415#if ENABLE_COMBINING
416 else if (IS_COMPOSE (t) && (cc = rxvt_composite[t]))
318 } 417 {
418 rxvt_font *f1 = (*fs)[fs->find_font (cc->c1)];
419 f1->draw (d, x, y, &(t = cc->c1), 1, fg, bg);
420 if (cc->c2 != NOCHAR)
421 {
422 // prefer font of first character, for no good reasons
423 rxvt_font *f2 = f1->has_codepoint (cc->c2)
424 ? f1
425 : (*fs)[fs->find_font (cc->c2)];
426
427 f2->draw (d, x, y, &(t = cc->c2), 1, fg, -1);
428 }
429 }
430#endif
319 else 431 else
320 switch (*text++) 432 switch (t)
321 { 433 {
322 case NOCHAR:
323 case ZERO_WIDTH_CHAR: 434 case ZERO_WIDTH_CHAR:
324 break; 435 break;
436
437 case 0x2580: XFillRectangle (d.display->display, d, TGC, x0, y0, W, y1 - y0 + 1); break;
438 case 0x2581: XFillRectangle (d.display->display, d, TGC, x0, y0 + (H * 7 - 1) / 8, W, H - (H * 7 - 1) / 8); break;
439 case 0x2582: XFillRectangle (d.display->display, d, TGC, x0, y0 + (H * 6 - 2) / 8, W, H - (H * 6 - 2) / 8); break;
440 case 0x2583: XFillRectangle (d.display->display, d, TGC, x0, y0 + (H * 5 - 3) / 8, W, H - (H * 5 - 3) / 8); break;
441 case 0x2584: XFillRectangle (d.display->display, d, TGC, x0, y0 + (H * 4 - 4) / 8, W, H - (H * 4 - 4) / 8); break;
442 case 0x2585: XFillRectangle (d.display->display, d, TGC, x0, y0 + (H * 3 - 5) / 8, W, H - (H * 3 - 5) / 8); break;
443 case 0x2586: XFillRectangle (d.display->display, d, TGC, x0, y0 + (H * 2 - 6) / 8, W, H - (H * 2 - 6) / 8); break;
444 case 0x2587: XFillRectangle (d.display->display, d, TGC, x0, y0 + (H * 1 - 7) / 8, W, H - (H * 1 - 7) / 8); break;
445 case 0x2588: XFillRectangle (d.display->display, d, TGC, x0, y0, W, H); break;
446 case 0x2589: XFillRectangle (d.display->display, d, TGC, x0, y0, (W * 7 - 1) / 8, H); break;
447 case 0x258a: XFillRectangle (d.display->display, d, TGC, x0, y0, (W * 6 - 2) / 8, H); break;
448 case 0x258b: XFillRectangle (d.display->display, d, TGC, x0, y0, (W * 5 - 3) / 8, H); break;
449 case 0x258c: XFillRectangle (d.display->display, d, TGC, x0, y0, (W * 4 - 4) / 8, H); break;
450 case 0x258d: XFillRectangle (d.display->display, d, TGC, x0, y0, (W * 3 - 5) / 8, H); break;
451 case 0x258e: XFillRectangle (d.display->display, d, TGC, x0, y0, (W * 2 - 6) / 8, H); break;
452 case 0x258f: XFillRectangle (d.display->display, d, TGC, x0, y0, (W * 1 - 7) / 8, H); break;
453 case 0x2590: XFillRectangle (d.display->display, d, TGC, x1, y0, x2 - x1, H); break;
454
455 case 0x2591: rect_stipple (d.display->display, d, TGC, 0x00, 0x01, x0, y0, W, H); break;
456 case 0x2592: rect_stipple (d.display->display, d, TGC, 0x02, 0x01, x0, y0, W, H); break;
457 case 0x2593: rect_stipple (d.display->display, d, TGC, 0x01, 0x03, x0, y0, W, H); break;
458
459 case 0x2594: XFillRectangle (d.display->display, d, TGC, x0, y0, W, (H * 1 - 7) / 8); break;
460 case 0x2595: XFillRectangle (d.display->display, d, TGC, x0 + (W * 7 - 1) / 8, y0, W - (W * 7 - 1) / 8, H); break;
461
325 default: 462 default:
326 XDrawRectangle (DISPLAY, DRAWABLE, GC, x + 2, y + 2, r->TermWin.fwidth - 5, r->TermWin.fheight - 5); 463 int w = 0;
464 while (len > 0 && *text == NOCHAR)
465 {
466 ++text;
467 --len;
468 w += r->TermWin.fwidth;
469 }
470
471 XDrawRectangle (d.display->display, d, TGC, x + 2, y + 2,
472 w + r->TermWin.fwidth - 4, r->TermWin.fheight - 4);
473 x += w;
327 } 474 }
328 475
329 x += r->TermWin.fwidth; 476 x += r->TermWin.fwidth;
330 } 477 }
331} 478}
336 rxvt_font_x11 () { f = 0; } 483 rxvt_font_x11 () { f = 0; }
337 484
338 void clear (); 485 void clear ();
339 486
340 rxvt_fontprop properties (); 487 rxvt_fontprop properties ();
341 rxvt_fontprop properties (XFontStruct *f);
342 488
343 bool load (const rxvt_fontprop &prop); 489 bool load (const rxvt_fontprop &prop);
344 490
345 bool has_codepoint (uint32_t unicode); 491 bool has_codepoint (unicode_t unicode);
346 492
347 void draw (int x, int y, 493 void draw (rxvt_drawable &d, int x, int y,
348 const text_t *text, int len, 494 const text_t *text, int len,
349 int fg, int bg); 495 int fg, int bg);
350 496
351 XFontStruct *f; 497 XFontStruct *f;
352 codeset cs; 498 codeset cs;
353 bool enc2b, encm; 499 bool enc2b, encm;
354 500
355 const char *get_property (XFontStruct *f, const char *property, const char *repl) const; 501 const char *get_property (XFontStruct *f, const char *property, const char *repl) const;
502 bool set_properties (rxvt_fontprop &p, int height, const char *weight, const char *slant, int avgwidth);
503 bool set_properties (rxvt_fontprop &p, XFontStruct *f);
504 bool set_properties (rxvt_fontprop &p, const char *name);
356}; 505};
357 506
358const char * 507const char *
359rxvt_font_x11::get_property (XFontStruct *f, const char *property, const char *repl) const 508rxvt_font_x11::get_property (XFontStruct *f, const char *property, const char *repl) const
360{ 509{
367} 516}
368 517
369rxvt_fontprop 518rxvt_fontprop
370rxvt_font_x11::properties () 519rxvt_font_x11::properties ()
371{ 520{
372 return properties (f);
373}
374
375rxvt_fontprop
376rxvt_font_x11::properties (XFontStruct *f)
377{
378 rxvt_fontprop p; 521 rxvt_fontprop p;
522 set_properties (p, f);
523 return p;
524}
379 525
526bool
527rxvt_font_x11::set_properties (rxvt_fontprop &p, int height, const char *weight, const char *slant, int avgwidth)
528{
529 p.width = avgwidth ? (avgwidth + 1) / 10 : (height + 1) / 2;
530 p.height = height;
531 p.weight = *weight == 'B' || *weight == 'b' ? rxvt_fontprop::bold : rxvt_fontprop::medium;
532 p.slant = *slant == 'r' || *slant == 'R' ? rxvt_fontprop::roman : rxvt_fontprop::italic;
533
534 return true;
535}
536
537bool
538rxvt_font_x11::set_properties (rxvt_fontprop &p, XFontStruct *f)
539{
380 const char *weight = get_property (f, "WEIGHT_NAME", "medium"); 540 const char *weight = get_property (f, "WEIGHT_NAME", "medium");
381 const char *slant = get_property (f, "SLANT", "r"); 541 const char *slant = get_property (f, "SLANT", "r");
382 542
383 p.height = height; 543 unsigned long height;
384 p.weight = *weight == 'B' || *weight == 'b' ? rxvt_fontprop::bold : rxvt_fontprop::medium; 544 if (!XGetFontProperty (f, XInternAtom (DISPLAY, "PIXEL_SIZE", 0), &height))
385 p.slant = *slant == 'r' || *slant == 'R' ? rxvt_fontprop::roman : rxvt_fontprop::italic; 545 return false;
386 546
387 return p; 547 unsigned long avgwidth;
548 if (!XGetFontProperty (f, XInternAtom (DISPLAY, "AVERAGE_WIDTH", 0), &avgwidth))
549 avgwidth = 0;
550
551 return set_properties (p, height, weight, slant, avgwidth);
552}
553
554bool
555rxvt_font_x11::set_properties (rxvt_fontprop &p, const char *name)
556{
557 int slashes = 0;
558 const char *comp[13];
559
560 for (const char *c = name; *c; c++)
561 if (*c == '-')
562 {
563 comp[slashes++] = c + 1;
564 if (slashes >= 13)
565 break;
566 }
567
568 /* can we short-circuit the costly XLoadQueryFont? */
569 if (slashes >= 13
570 && (*comp[ 6] >= '1' && *comp[ 6] <= '9')
571 && (*comp[11] >= '0' && *comp[11] <= '9'))
572 return set_properties (p, atoi (comp[6]), comp[2], comp[3], atoi (comp[11]));
573
574 XFontStruct *f = XLoadQueryFont (DISPLAY, name);
575
576 if (f)
577 {
578 // the font should really exist now. if not, we have a problem
579 // (e.g. if the user did xset fp rehash just when we were searching fonts).
580 // in that case, just return garbage.
581 bool ret = set_properties (p, f);
582 XFreeFont (DISPLAY, f);
583 return ret;
584 }
585 else
586 return false;
587}
588
589// fix the size of scalable fonts
590static void
591fix_scalable (char *buf, const char *name, const rxvt_fontprop &prop)
592{
593 int slashes = 0;
594 const char *size;
595
596 for (const char *c = name; *c; c++)
597 if (*c == '-')
598 {
599 if (slashes == 6)
600 size = c + 1;
601
602 if (++slashes >= 13)
603 break;
604 }
605
606 if (slashes >= 13 && size[0] == '0')
607 {
608 strncpy (buf, name, size - name);
609 buf += size - name;
610 buf += sprintf (buf, "%d", prop.height);
611 strcpy (buf, size + 1);
612 }
613 else
614 strcpy (buf, name);
388} 615}
389 616
390bool 617bool
391rxvt_font_x11::load (const rxvt_fontprop &prop) 618rxvt_font_x11::load (const rxvt_fontprop &prop)
392{ 619{
393 clear (); 620 clear ();
394 621
395 char **list; 622 char **list;
396 int count; 623 int count;
397 XFontStruct *info;
398 list = XListFontsWithInfo (DISPLAY, name, 128, &count, &info); 624 list = XListFonts (DISPLAY, name, 512, &count);
625 set_name (0);
399 626
400 if (!list) 627 if (!list)
401 return false; 628 return false;
402 629
403 int bestdiff = 0x7fffffff; 630 int bestdiff = 0x7fffffff;
404 XFontStruct *best = 0;
405 for (int i = 0; i < count; i++) 631 for (int i = 0; i < count; i++)
406 { 632 {
407 XFontStruct *f = info + i; 633 rxvt_fontprop p;
634 char fname[1024];
635 fix_scalable (fname, list[i], prop);
408 636
637 if (!set_properties (p, fname))
638 continue;
639
409 if (f->ascent + f->descent <= prop.height) // weed out too large fonts 640 if (p.height > prop.height) // weed out too large fonts
410 { 641 continue;
411 rxvt_fontprop p = properties (f); 642
412 int diff = (prop.height - f->ascent + f->descent) * 32 643 int diff = (prop.height - p.height) * 32
413 + abs (prop.weight - p.weight) 644 + abs (prop.weight - p.weight)
414 + abs (prop.slant - p.slant ); 645 + abs (prop.slant - p.slant );
415 646
416 if (!best // compare against best found so far 647 if (!name // compare against best found so far
417 || diff < bestdiff) 648 || diff < bestdiff)
418 { 649 {
419 best = f; 650 set_name (strdup (fname));
420 bestdiff = diff; 651 bestdiff = diff;
421 } 652 }
422 }
423 } 653 }
424 654
425 set_name (strdup (list[best - info])); 655 XFreeFontNames (list);
426 656
427 XFreeFontInfo (list, info, count); 657 if (!name)
658 return false;
428 659
429 f = XLoadQueryFont (DISPLAY, name); 660 f = XLoadQueryFont (DISPLAY, name);
430 661
431 if (!f) 662 if (!f)
432 return false; 663 return false;
433
434 unsigned long value;
435 664
436 const char *registry = get_property (f, "CHARSET_REGISTRY", 0); 665 const char *registry = get_property (f, "CHARSET_REGISTRY", 0);
437 const char *encoding = get_property (f, "CHARSET_ENCODING", 0); 666 const char *encoding = get_property (f, "CHARSET_ENCODING", 0);
438 667
439 if (registry && encoding) 668 if (registry && encoding)
514 f = 0; 743 f = 0;
515 } 744 }
516} 745}
517 746
518bool 747bool
519rxvt_font_x11::has_codepoint (uint32_t unicode) 748rxvt_font_x11::has_codepoint (unicode_t unicode)
520{ 749{
521 uint32_t ch = FROM_UNICODE (cs, unicode); 750 uint32_t ch = FROM_UNICODE (cs, unicode);
522 751
523 if (ch == NOCHAR) 752 if (ch == NOCHAR)
524 return false; 753 return false;
526 /* check wether the character exists in _this_ font. horrible. */ 755 /* check wether the character exists in _this_ font. horrible. */
527 XCharStruct *xcs; 756 XCharStruct *xcs;
528 757
529 if (encm) 758 if (encm)
530 { 759 {
531 int byte1 = ch >> 8; 760 unsigned char byte1 = ch >> 8;
532 int byte2 = ch & 255; 761 unsigned char byte2 = ch & 255;
533 762
534 if (byte1 < f->min_byte1 || byte1 > f->max_byte1 763 if (byte1 < f->min_byte1 || byte1 > f->max_byte1
535 || byte2 < f->min_char_or_byte2 || byte2 > f->max_char_or_byte2) 764 || byte2 < f->min_char_or_byte2 || byte2 > f->max_char_or_byte2)
536 return false; 765 return false;
537 766
560 789
561 return true; 790 return true;
562} 791}
563 792
564void 793void
565rxvt_font_x11::draw (int x, int y, 794rxvt_font_x11::draw (rxvt_drawable &d, int x, int y,
566 const text_t *text, int len, 795 const text_t *text, int len,
567 int fg, int bg) 796 int fg, int bg)
568{ 797{
569 // this looks like a mess /. 798 // this looks like a mess /.
570 // and it is a mess /. 799 // and it is a mess /.
586 { 815 {
587 const XChar2b *xc = enc_xchar2b (text, len, cs, slow); 816 const XChar2b *xc = enc_xchar2b (text, len, cs, slow);
588 817
589 if (bg == Color_bg && !slow) 818 if (bg == Color_bg && !slow)
590 { 819 {
591 XChangeGC (DISPLAY, GC, GCForeground | GCBackground | GCFont, &v); 820 XChangeGC (d.display->display, TGC, GCForeground | GCBackground | GCFont, &v);
592 XDrawImageString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 821 XDrawImageString16 (d.display->display, d, TGC, x, y + base, xc, len);
593 } 822 }
594 else 823 else
595 { 824 {
596 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 825 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
597 826
598 XChangeGC (DISPLAY, GC, GCForeground | GCFont, &v); 827 XChangeGC (d.display->display, TGC, GCForeground | GCFont, &v);
599 828
600 if (slow) 829 if (slow)
601 { 830 {
602 do 831 do
603 { 832 {
604 if (xc->byte1 || xc->byte2) 833 if (xc->byte1 || xc->byte2)
605 XDrawString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, 1); 834 XDrawString16 (d.display->display, d, TGC, x, y + base, xc, 1);
606 835
607 x += r->TermWin.fwidth; 836 x += r->TermWin.fwidth;
608 xc++; len--; 837 xc++; len--;
609 } 838 }
610 while (len); 839 while (len);
611 } 840 }
612 else 841 else
613 XDrawString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 842 XDrawString16 (d.display->display, d, TGC, x, y + base, xc, len);
614 } 843 }
615 } 844 }
616 else 845 else
617 { 846 {
618 const char *xc = enc_char (text, len, cs, slow); 847 const char *xc = enc_char (text, len, cs, slow);
619 848
620 if (bg == Color_bg && !slow) 849 if (bg == Color_bg && !slow)
621 { 850 {
622 XChangeGC (DISPLAY, GC, GCForeground | GCBackground | GCFont, &v); 851 XChangeGC (d.display->display, TGC, GCForeground | GCBackground | GCFont, &v);
623 XDrawImageString (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 852 XDrawImageString (d.display->display, d, TGC, x, y + base, xc, len);
624 } 853 }
625 else 854 else
626 { 855 {
627 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 856 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
628 857
629 XChangeGC (DISPLAY, GC, GCForeground | GCFont, &v); 858 XChangeGC (d.display->display, TGC, GCForeground | GCFont, &v);
630 859
631 if (slow) 860 if (slow)
632 { 861 {
633 do 862 do
634 { 863 {
635 if (*xc) 864 if (*xc)
636 XDrawString (DISPLAY, DRAWABLE, GC, x, y + base, xc, 1); 865 XDrawString (d.display->display, d, TGC, x, y + base, xc, 1);
637 866
638 x += r->TermWin.fwidth; 867 x += r->TermWin.fwidth;
639 xc++; len--; 868 xc++; len--;
640 } 869 }
641 while (len); 870 while (len);
642 } 871 }
643 else 872 else
644 XDrawString (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 873 XDrawString (d.display->display, d, TGC, x, y + base, xc, len);
645 } 874 }
646 } 875 }
647} 876}
648 877
649///////////////////////////////////////////////////////////////////////////// 878/////////////////////////////////////////////////////////////////////////////
654//#define SWATHBITS (UNIBITS / 2 + 3) // minimum size for "full" tables 883//#define SWATHBITS (UNIBITS / 2 + 3) // minimum size for "full" tables
655#define SWATHBITS 8 884#define SWATHBITS 8
656#endif 885#endif
657 886
658struct rxvt_font_xft : rxvt_font { 887struct rxvt_font_xft : rxvt_font {
659#if 0
660 enum {
661 SWATHCOUNT = 1 << (21 - UNIBITS),
662 SWATHSIZE = 1 << (SWATHBITS - 5)
663 };
664 typedef uint32_t swath[SWATHSIZE];
665
666 swath *cvr[SWATHCOUNT];
667#endif
668
669#if 0
670 void gen_coverage_swath (unsigned int page);
671
672 bool has_char (uint32_t ch)
673 {
674 unsigned int page = ch >> SWATHBITS;
675 unsigned int idx = ch & ((1 << SWATHBITS) - 1);
676
677 if (page >= SWATHCOUNT)
678 return false;
679
680 if (!cvr[page]) gen_coverage_swath (page);
681
682 return cvr[page][idx >> 5] & (1 << (idx & 31));
683 }
684#endif
685 rxvt_font_xft () { f = 0; d = 0; } 888 rxvt_font_xft () { f = 0; }
686 889
687 void clear (); 890 void clear ();
688 891
689 rxvt_fontprop properties (); 892 rxvt_fontprop properties ();
690 893
691 bool load (const rxvt_fontprop &prop); 894 bool load (const rxvt_fontprop &prop);
692 895
693 void draw (int x, int y, 896 void draw (rxvt_drawable &d, int x, int y,
694 const text_t *text, int len, 897 const text_t *text, int len,
695 int fg, int bg); 898 int fg, int bg);
696 899
697 bool has_codepoint (uint32_t unicode); 900 bool has_codepoint (unicode_t unicode);
698 901
699protected: 902protected:
700 XftFont *f; 903 XftFont *f;
701 XftDraw *d;
702
703#if 0
704 virtual void populate_coverage_swath (uint32_t lo, uint32_t hi) = 0;
705 void set_swath (uint32_t ch)
706 {
707 cvr[ch >> SWATHBITS] |= 1 << (ch & ((1 << SWATHBITS) - 1));
708 }
709#endif
710}; 904};
711 905
712void 906void
713rxvt_font_xft::clear () 907rxvt_font_xft::clear ()
714{ 908{
715 if (f) 909 if (f)
716 { 910 {
717 XftFontClose (DISPLAY, f); 911 XftFontClose (DISPLAY, f);
718 f = 0; 912 f = 0;
719 } 913 }
720
721 if (d)
722 {
723 XftDrawDestroy (d);
724 d = 0;
725 }
726
727#if 0
728 for (int i = 0; i < SWATHCOUNT; i++)
729 delete cvr[i];
730#endif
731} 914}
732 915
733rxvt_fontprop 916rxvt_fontprop
734rxvt_font_xft::properties () 917rxvt_font_xft::properties ()
735{ 918{
736 rxvt_fontprop p; 919 rxvt_fontprop p;
737 920
738 FT_Face face = XftLockFace (f); 921 FT_Face face = XftLockFace (f);
739 922
740 p.height = height; 923 p.width = width; p.height = height;
741 p.weight = face->style_flags & FT_STYLE_FLAG_BOLD ? rxvt_fontprop::bold : rxvt_fontprop::medium; 924 p.weight = face->style_flags & FT_STYLE_FLAG_BOLD ? rxvt_fontprop::bold : rxvt_fontprop::medium;
742 p.slant = face->style_flags & FT_STYLE_FLAG_ITALIC ? rxvt_fontprop::italic : rxvt_fontprop::roman; 925 p.slant = face->style_flags & FT_STYLE_FLAG_ITALIC ? rxvt_fontprop::italic : rxvt_fontprop::roman;
743 926
744 XftUnlockFace (f); 927 XftUnlockFace (f);
745 928
766 if (FcPatternGet (p, FC_WEIGHT, 0, &v) != FcResultMatch) 949 if (FcPatternGet (p, FC_WEIGHT, 0, &v) != FcResultMatch)
767 FcPatternAddInteger (p, FC_WEIGHT, prop.weight); 950 FcPatternAddInteger (p, FC_WEIGHT, prop.weight);
768 951
769 if (FcPatternGet (p, FC_SLANT, 0, &v) != FcResultMatch) 952 if (FcPatternGet (p, FC_SLANT, 0, &v) != FcResultMatch)
770 FcPatternAddInteger (p, FC_SLANT, prop.slant); 953 FcPatternAddInteger (p, FC_SLANT, prop.slant);
954
955#if 0 // clipping unfortunately destroys our precious double-width-characters
956 // clip width, we can't do better, or can we?
957 if (FcPatternGet (p, FC_CHAR_WIDTH, 0, &v) != FcResultMatch)
958 FcPatternAddInteger (p, FC_CHAR_WIDTH, prop.width);
959#endif
771 960
772 //FcPatternAddBool (p, FC_MINSPACE, 1); 961 //FcPatternAddBool (p, FC_MINSPACE, 1);
773 962
774 XftResult result; 963 XftResult result;
775 FcPattern *match = XftFontMatch (DISPLAY, DefaultScreen (DISPLAY), p, &result); 964 FcPattern *match = XftFontMatch (DISPLAY, DefaultScreen (DISPLAY), p, &result);
828 XftUnlockFace (f); 1017 XftUnlockFace (f);
829 1018
830 return true; 1019 return true;
831} 1020}
832 1021
833#if 0
834void rxvt_font::gen_coverage_swath (unsigned int page)
835{
836 cvr[page] = new swath;
837
838 for (int i = 0; i < SWATHSIZE; i++)
839 cvr[page][i] = 0;
840
841 populate_coverage_swath (cvr[page], page << SWATHBITS, ((page + 1) << SWATHBITS) - 1);
842}
843#endif
844
845bool 1022bool
846rxvt_font_xft::has_codepoint (uint32_t unicode) 1023rxvt_font_xft::has_codepoint (unicode_t unicode)
847{ 1024{
848 return XftCharExists (DISPLAY, f, unicode); 1025 return XftCharExists (DISPLAY, f, unicode);
849} 1026}
850 1027
851void 1028void
852rxvt_font_xft::draw (int x, int y, 1029rxvt_font_xft::draw (rxvt_drawable &d, int x, int y,
853 const text_t *text, int len, 1030 const text_t *text, int len,
854 int fg, int bg) 1031 int fg, int bg)
855{ 1032{
856 if (!d)
857 {
858 dR;
859 d = XftDrawCreate (DISPLAY, DRAWABLE, XVISUAL, XCMAP);
860 }
861
862 if (bg >= 0 && bg != Color_bg)
863 XftDrawRect (d, &r->PixColors[bg].c, x, y, r->TermWin.fwidth * len, r->TermWin.fheight);
864 else
865 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 1033 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
866 1034
867 if (!slow && width == r->TermWin.fwidth) 1035 if (!slow && width == r->TermWin.fwidth && 0)
868 { 1036 {
869 if (sizeof (text_t) == sizeof (FcChar16)) 1037 if (sizeof (text_t) == sizeof (FcChar16))
870 XftDrawString16 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar16 *)text, len); 1038 XftDrawString16 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar16 *)text, len);
871 else 1039 else
872 XftDrawString32 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar32 *)text, len); 1040 XftDrawString32 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar32 *)text, len);
875 { 1043 {
876 while (len) 1044 while (len)
877 { 1045 {
878 if (*text != NOCHAR && *text != ' ') 1046 if (*text != NOCHAR && *text != ' ')
879 { 1047 {
1048 int fwidth = r->TermWin.fwidth;
1049 if (len >= 2 && text[1] == NOCHAR)
1050 fwidth *= 2;
1051
1052 XGlyphInfo extents;
880 if (sizeof (text_t) == sizeof (FcChar16)) 1053 if (sizeof (text_t) == sizeof (FcChar16))
881 XftDrawString16 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar16 *)text, 1); 1054 {
1055 XftTextExtents16 (d.display->display, f, (const FcChar16 *)text, 1, &extents);
1056 XftDrawString16 (d, &r->PixColors[fg].c, f, x + extents.x + (fwidth - extents.width) / 2,
1057 y + r->TermWin.fbase, (const FcChar16 *)text, 1);
1058 }
882 else 1059 else
883 XftDrawString32 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar32 *)text, 1); 1060 {
1061 XGlyphInfo extents;
1062 XftTextExtents32 (d.display->display, f, (const FcChar32 *)text, 1, &extents);
1063 XftDrawString32 (d, &r->PixColors[fg].c, f, x + extents.x + (fwidth - extents.width) / 2,
1064 y + r->TermWin.fbase, (const FcChar32 *)text, 1);
1065 }
884 } 1066 }
885 1067
886 x += r->TermWin.fwidth; 1068 x += r->TermWin.fwidth;
887 text++; 1069 text++;
888 len--; 1070 len--;
892#endif 1074#endif
893 1075
894///////////////////////////////////////////////////////////////////////////// 1076/////////////////////////////////////////////////////////////////////////////
895 1077
896rxvt_fontset::rxvt_fontset (rxvt_t r) 1078rxvt_fontset::rxvt_fontset (rxvt_t r)
897#ifdef EXPLICIT_CONTEXT
898: r(r) 1079: r (r)
899#endif
900{ 1080{
901 clear (); 1081 clear ();
902} 1082}
903 1083
904rxvt_fontset::~rxvt_fontset () 1084rxvt_fontset::~rxvt_fontset ()
907} 1087}
908 1088
909void 1089void
910rxvt_fontset::clear () 1090rxvt_fontset::clear ()
911{ 1091{
912 for (rxvt_font **i = fonts.begin (); i != fonts.end(); i++) 1092 for (rxvt_font **i = fonts.begin (); i != fonts.end (); i++)
913 FONT_UNREF (*i); 1093 FONT_UNREF (*i);
914 1094
915 fonts.clear (); 1095 fonts.clear ();
916 base_id = 0; 1096 base_id = 0;
917 base_prop.height = 0x7fffffff; 1097 base_prop.height = 0x7fffffff;
944 f = new rxvt_font_x11; 1124 f = new rxvt_font_x11;
945 } 1125 }
946 else 1126 else
947 f = new rxvt_font_x11; 1127 f = new rxvt_font_x11;
948 1128
1129 f->fs = this;
949 f->set_term (r); 1130 f->set_term (r);
950 f->set_name (strdup (name)); 1131 f->set_name (strdup (name));
951 1132
952 f->cs = cs; 1133 f->cs = cs;
953 f->loaded = false; 1134 f->loaded = false;
971 1152
972 if (*desc == '[') 1153 if (*desc == '[')
973 { 1154 {
974 fprintf (stderr, "extra font parameters not yet supported, skipping.\n"); 1155 fprintf (stderr, "extra font parameters not yet supported, skipping.\n");
975 1156
976 const char *extra = desc++; 1157 //const char *extra = desc++; // not yet used
977 1158
978 desc = strchr (desc, ']'); 1159 desc = strchr (desc, ']');
979 1160
980 if (!desc) 1161 if (!desc)
981 { 1162 {
1020 } 1201 }
1021 1202
1022 return true; 1203 return true;
1023} 1204}
1024 1205
1025void 1206bool
1026rxvt_fontset::populate (const char *desc) 1207rxvt_fontset::populate (const char *desc)
1027{ 1208{
1028 clear (); 1209 clear ();
1029 1210
1030 fonts.push_back (new_font (0, CS_UNICODE)); 1211 fonts.push_back (new_font (0, CS_UNICODE));
1034 1215
1035 if (!base_id) 1216 if (!base_id)
1036 base_id = 1; 1217 base_id = 1;
1037 1218
1038 // we currently need a base-font, no matter what 1219 // we currently need a base-font, no matter what
1039 if (fonts.size () <= base_id || !realize_font (base_id)) 1220 if ((int)fonts.size () <= base_id || !realize_font (base_id))
1040 { 1221 {
1222 puts ("unable to load specified font (s), falling back to 'fixed'\n");
1041 add_fonts ("fixed"); 1223 add_fonts ("fixed");
1042 base_id = fonts.size () - 1; 1224 base_id = fonts.size () - 1;
1043 } 1225 }
1044 1226
1045 if (fonts.size () <= base_id || !realize_font (base_id)) 1227 if ((int)fonts.size () <= base_id || !realize_font (base_id))
1046 { 1228 return false;
1047 fprintf (stderr, "unable to load a base font, please provide one using -fn fontname\n");
1048 exit (1);
1049 }
1050 1229
1051 base_prop = fonts[base_id]->properties (); 1230 base_prop = fonts[base_id]->properties ();
1231
1232 return true;
1052} 1233}
1053 1234
1054int 1235int
1055rxvt_fontset::find_font (uint32_t unicode) 1236rxvt_fontset::find_font (unicode_t unicode)
1056{ 1237{
1057 for (int i = 0; i < fonts.size (); i++) 1238 for (unsigned int i = 0; i < fonts.size (); i++)
1058 { 1239 {
1059 rxvt_font *f = fonts[i]; 1240 rxvt_font *f = fonts[i];
1060 1241
1061 if (!f->loaded) 1242 if (!f->loaded)
1062 { 1243 {

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines