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.1 by pcg, Mon Nov 24 17:28:08 2003 UTC vs.
Revision 1.6 by pcg, Wed Dec 17 22:29:03 2003 UTC

21 21
22#include "../config.h" 22#include "../config.h"
23#include "rxvt.h" 23#include "rxvt.h"
24#include "defaultfont.h" 24#include "defaultfont.h"
25 25
26#define DISPLAY R->Xdisplay 26#define DISPLAY r->Xdisplay
27#define DRAWABLE R->TermWin.vt 27#define DRAWABLE r->TermWin.vt
28#define GC R->TermWin.gc 28#define GC r->TermWin.gc
29 29
30const struct rxvt_fallback_font { 30const struct rxvt_fallback_font {
31 codeset cs; 31 codeset cs;
32 const char *name; 32 const char *name;
33} fallback_fonts[] = { 33} fallback_fonts[] = {
163{ 163{
164 if (color == Color_bg) 164 if (color == Color_bg)
165 XClearArea (DISPLAY, DRAWABLE, x, y, w, h, FALSE); 165 XClearArea (DISPLAY, DRAWABLE, x, y, w, h, FALSE);
166 else if (color >= 0) 166 else if (color >= 0)
167 { 167 {
168 XSetForeground (DISPLAY, GC, R->PixColors[color]); 168 XSetForeground (DISPLAY, GC, r->PixColors[color]);
169 XFillRectangle (DISPLAY, DRAWABLE, GC, x, y, w, h); 169 XFillRectangle (DISPLAY, DRAWABLE, GC, x, y, w, h);
170 } 170 }
171} 171}
172
173static const char *linedraw_cmds[128] = {
174 "1hH", "2hH", "1vV", "2vV",
175 0, 0, 0, 0,
176 0, 0, 0, 0,
177 "1HV", "2H1V", "1H2V", "2HV",
178
179 // 2510
180 "1hV", "2h1V", "1h2V", "2hV",
181 "1Hv", "2H1v", "1H2v", "2Hv",
182 "1hv", "2h1v", "1h2v", "2hv",
183 "1HvV", "2H1vV", "1HV2v", "1Hv2V",
184
185 // 2520
186 "1H2vV", "2Hv1V", "2HV1v", "2HvV",
187 "1hvV", "2h1vV", "1hV2v", "1hv2V",
188 "1h2vV", "2hv1V", "1v2hV", "2hvV",
189 "1hHV", "2h1HV", "2H1hV", "2hH1V",
190
191 // 2530
192 "1hH2V", "2hV1H", "1h2HV", "2hHV",
193 "1hHv", "1vH2h", "1hv2H", "1v2hH",
194 "1hH2v", "1H2hv", "1h2Hv", "2hHv",
195 "1hHvV", "1vVH2h", "1hvV2H", "1vV2hH",
196
197 // 2540
198 "1hHV2v", "1hHv2V", "1hH2vV", "1HV2hv",
199 "1hV2Hv", "1Hv2hV", "1hv2HV", "1V2hHv",
200 "1v2hHV", "1H2hvV", "1h2HvV", "2hHvV",
201 0, 0, 0, 0,
202
203 // 2550
204 0, 0, 0, 0,
205 0, 0, 0, 0,
206 0, 0, 0, 0,
207 0, 0, 0, 0,
208
209 // 2560
210 0, 0, 0, 0,
211 0, 0, 0, 0,
212 0, 0, 0, 0,
213 0, 0, 0, 0,
214
215 // 2570
216 0, "1a", "1b", "1ab",
217 "1h", "1v", "1H", "1V",
218 "2h", "2v", "2H", "2V",
219 "1h2H", "1v2V", "1H2h", "1V2v"
220
221 // to be done
222};
172 223
173struct rxvt_font_default : rxvt_font { 224struct rxvt_font_default : rxvt_font {
174 bool load (int maxheight) 225 bool load (int maxheight)
175 { 226 {
176 width = 1; height = 1; 227 width = 1; height = 1;
179 return true; 230 return true;
180 } 231 }
181 232
182 bool has_codepoint (uint32_t unicode) 233 bool has_codepoint (uint32_t unicode)
183 { 234 {
184 if (unicode <= 0x001f 235 if (unicode <= 0x001f)
236 return true;
185 || (unicode >= 0x80 && unicode <= 0x9f)) 237 if (unicode >= 0x0080 && unicode <= 0x009f)
238 return true;
239
240 if (unicode >= 0x2500 && unicode <= 0x257f
241 && linedraw_cmds[unicode - 0x2500])
186 return true; 242 return true;
187 243
188 switch (unicode) 244 switch (unicode)
189 { 245 {
190 case ZERO_WIDTH_CHAR: 246 case ZERO_WIDTH_CHAR:
202void 258void
203rxvt_font_default::draw (int x, int y, 259rxvt_font_default::draw (int x, int y,
204 const text_t *text, int len, 260 const text_t *text, int len,
205 int fg, int bg) 261 int fg, int bg)
206{ 262{
207 clear_rect (x, y, R->TermWin.fwidth * len, R->TermWin.fheight, bg); 263 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
264
265 XSetForeground (DISPLAY, GC, r->PixColors[fg]);
208 266
209 while (len--) 267 while (len--)
210 { 268 {
269 text_t t = *text++;
270
271 if (t >= 0x2500 & t <= 0x2580 && linedraw_cmds[t - 0x2500])
272 {
273 const char *p = linedraw_cmds[t - 0x2500];
274
275 int x0 = x, x1 = x + r->TermWin.fwidth / 2, x2 = x + r->TermWin.fwidth ;
276 int y0 = y, y1 = y + r->TermWin.fheight / 2, y2 = y + r->TermWin.fheight;
277
278 XGCValues gcv;
279
280 while (*p)
281 {
282 switch (*p++)
283 {
284 case '1':
285 gcv.line_width = 0;
286 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv);
287 break;
288
289 case '2':
290 gcv.line_width = 2;
291 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv);
292 break;
293
294 case 'h': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y1, x1, y1); break;
295 case 'H': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y1, x2, y1); break;
296 case 'v': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y0, x1, y1); break;
297 case 'V': XDrawLine (DISPLAY, DRAWABLE, GC, x1, y1, x1, y2); break;
298 case 'a': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y2, x2, y0); break;
299 case 'b': XDrawLine (DISPLAY, DRAWABLE, GC, x0, y0, x2, y2); break;
300 }
301 }
302
303 gcv.line_width = 0;
304 XChangeGC (DISPLAY, GC, GCLineWidth, &gcv);
305 }
306 else
211 switch (*text++) 307 switch (*text++)
212 { 308 {
213 case NOCHAR: 309 case NOCHAR:
214 case ZERO_WIDTH_CHAR: 310 case ZERO_WIDTH_CHAR:
215 break; 311 break;
216 default: 312 default:
217 XSetForeground (DISPLAY, GC, R->PixColors[fg]);
218 XDrawRectangle (DISPLAY, DRAWABLE, GC, x + 2, y + 2, R->TermWin.fwidth - 5, R->TermWin.fheight - 5); 313 XDrawRectangle (DISPLAY, DRAWABLE, GC, x + 2, y + 2, r->TermWin.fwidth - 5, r->TermWin.fheight - 5);
219 } 314 }
220 315
221 x += R->TermWin.fwidth; 316 x += r->TermWin.fwidth;
222 } 317 }
223} 318}
224 319
225///////////////////////////////////////////////////////////////////////////// 320/////////////////////////////////////////////////////////////////////////////
226 321
257 352
258bool 353bool
259rxvt_font_x11::load (int maxheight) 354rxvt_font_x11::load (int maxheight)
260{ 355{
261 clear (); 356 clear ();
357
358 char **list;
359 int count;
360 XFontStruct *info;
361 list = XListFontsWithInfo (DISPLAY, name, 128, &count, &info);
362
363 if (!list)
364 return false;
365
366 XFontStruct *best = 0;
367 for (int i = 0; i < count; i++)
368 {
369 XFontStruct *f = info + i;
370 if (f->ascent + f->descent <= maxheight) // weed out too large fonts
371 if (!best // compare against best found so far
372 || best->ascent + best->descent < f->ascent + f->descent)
373 best = f;
374 }
375
376 set_name (strdup (list[best - info]));
377
378 XFreeFontInfo (list, info, count);
262 379
263 f = XLoadQueryFont (DISPLAY, name); 380 f = XLoadQueryFont (DISPLAY, name);
264 381
265 if (!f) 382 if (!f)
266 return false; 383 return false;
404 // and it is a mess /. 521 // and it is a mess /.
405 // yet we are trying to be perfect /. 522 // yet we are trying to be perfect /.
406 // but the result still isn't perfect /. 523 // but the result still isn't perfect /.
407 524
408 bool slow = prop 525 bool slow = prop
409 || width != R->TermWin.fwidth 526 || width != r->TermWin.fwidth
410 || height != R->TermWin.fheight; 527 || height != r->TermWin.fheight;
411 528
412 int base = R->TermWin.fbase; 529 int base = r->TermWin.fbase;
413 530
414 XGCValues v; 531 XGCValues v;
415 v.foreground = R->PixColors[fg]; 532 v.foreground = r->PixColors[fg];
416 v.background = R->PixColors[bg]; 533 v.background = r->PixColors[bg];
417 v.font = f->fid; 534 v.font = f->fid;
418 535
419 if (enc2b) 536 if (enc2b)
420 { 537 {
421 const XChar2b *xc = enc_xchar2b (text, len, cs, slow); 538 const XChar2b *xc = enc_xchar2b (text, len, cs, slow);
425 XChangeGC (DISPLAY, GC, GCForeground | GCBackground | GCFont, &v); 542 XChangeGC (DISPLAY, GC, GCForeground | GCBackground | GCFont, &v);
426 XDrawImageString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 543 XDrawImageString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, len);
427 } 544 }
428 else 545 else
429 { 546 {
430 clear_rect (x, y, R->TermWin.fwidth * len, R->TermWin.fheight, bg); 547 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
431 548
432 XChangeGC (DISPLAY, GC, GCForeground | GCFont, &v); 549 XChangeGC (DISPLAY, GC, GCForeground | GCFont, &v);
433 550
434 if (slow) 551 if (slow)
435 { 552 {
436 do 553 do
437 { 554 {
438 if (xc->byte1 || xc->byte2) 555 if (xc->byte1 || xc->byte2)
439 XDrawString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, 1); 556 XDrawString16 (DISPLAY, DRAWABLE, GC, x, y + base, xc, 1);
440 557
441 x += R->TermWin.fwidth; 558 x += r->TermWin.fwidth;
442 xc++; len--; 559 xc++; len--;
443 } 560 }
444 while (len); 561 while (len);
445 } 562 }
446 else 563 else
456 XChangeGC (DISPLAY, GC, GCForeground | GCBackground | GCFont, &v); 573 XChangeGC (DISPLAY, GC, GCForeground | GCBackground | GCFont, &v);
457 XDrawImageString (DISPLAY, DRAWABLE, GC, x, y + base, xc, len); 574 XDrawImageString (DISPLAY, DRAWABLE, GC, x, y + base, xc, len);
458 } 575 }
459 else 576 else
460 { 577 {
461 clear_rect (x, y, R->TermWin.fwidth * len, R->TermWin.fheight, bg); 578 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
462 579
463 XChangeGC (DISPLAY, GC, GCForeground | GCFont, &v); 580 XChangeGC (DISPLAY, GC, GCForeground | GCFont, &v);
464 581
465 if (slow) 582 if (slow)
466 { 583 {
467 do 584 do
468 { 585 {
469 if (*xc) 586 if (*xc)
470 XDrawString (DISPLAY, DRAWABLE, GC, x, y + base, xc, 1); 587 XDrawString (DISPLAY, DRAWABLE, GC, x, y + base, xc, 1);
471 588
472 x += R->TermWin.fwidth; 589 x += r->TermWin.fwidth;
473 xc++; len--; 590 xc++; len--;
474 } 591 }
475 while (len); 592 while (len);
476 } 593 }
477 else 594 else
544void 661void
545rxvt_font_xft::clear () 662rxvt_font_xft::clear ()
546{ 663{
547 if (f) 664 if (f)
548 { 665 {
549 XftFontClose (R->Xdisplay, f); 666 XftFontClose (DISPLAY, f);
550 f = 0; 667 f = 0;
551 } 668 }
552 669
553 if (d) 670 if (d)
554 { 671 {
570 cvr[i] = 0; 687 cvr[i] = 0;
571#endif 688#endif
572 689
573 clear (); 690 clear ();
574 691
575 f = XftFontOpenName (R->Xdisplay, DefaultScreen (R->Xdisplay), name); 692 f = XftFontOpenName (DISPLAY, DefaultScreen (DISPLAY), name);
576 693
577 if (!f) 694 if (!f)
578 return false; 695 return false;
579 696
580 FT_Face face = XftLockFace (f); 697 FT_Face face = XftLockFace (f);
586 for (;;) 703 for (;;)
587 { 704 {
588 XGlyphInfo g1, g2; 705 XGlyphInfo g1, g2;
589 FcChar8 c; 706 FcChar8 c;
590 707
591 c = 'i'; XftTextExtents8 (R->Xdisplay, f, &c, 1, &g1); 708 c = 'i'; XftTextExtents8 (DISPLAY, f, &c, 1, &g1);
592 c = 'W'; XftTextExtents8 (R->Xdisplay, f, &c, 1, &g2); 709 c = 'W'; XftTextExtents8 (DISPLAY, f, &c, 1, &g2);
593 710
594 prop = prop || g1.xOff != g2.xOff; // don't simply trust the font 711 prop = prop || g1.xOff != g2.xOff; // don't simply trust the font
595 712
596 width = g2.xOff; 713 width = g2.xOff;
597 ascent = (face->size->metrics.ascender + 63) >> 6; 714 ascent = (face->size->metrics.ascender + 63) >> 6;
632#endif 749#endif
633 750
634bool 751bool
635rxvt_font_xft::has_codepoint (uint32_t unicode) 752rxvt_font_xft::has_codepoint (uint32_t unicode)
636{ 753{
637 return XftCharExists (R->Xdisplay, f, unicode); 754 return XftCharExists (DISPLAY, f, unicode);
638} 755}
639 756
640void 757void
641rxvt_font_xft::draw (int x, int y, 758rxvt_font_xft::draw (int x, int y,
642 const text_t *text, int len, 759 const text_t *text, int len,
643 int fg, int bg) 760 int fg, int bg)
644{ 761{
645 if (!d) 762 if (!d)
763 {
764 dR;
646 d = XftDrawCreate (R->Xdisplay, DRAWABLE, XVISUAL, XCMAP); 765 d = XftDrawCreate (DISPLAY, DRAWABLE, XVISUAL, XCMAP);
766 }
647 767
648 if (bg >= 0 && bg != Color_bg) 768 if (bg >= 0 && bg != Color_bg)
649 XftDrawRect (d, &R->PixColors[bg].c, x, y, R->TermWin.fwidth * len, R->TermWin.fheight); 769 XftDrawRect (d, &r->PixColors[bg].c, x, y, r->TermWin.fwidth * len, r->TermWin.fheight);
650 else 770 else
651 clear_rect (x, y, R->TermWin.fwidth * len, R->TermWin.fheight, bg); 771 clear_rect (x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
652 772
653 if (!prop && width == R->TermWin.fwidth) 773 if (!prop && width == r->TermWin.fwidth)
654 { 774 {
655 if (sizeof (text_t) == sizeof (FcChar16)) 775 if (sizeof (text_t) == sizeof (FcChar16))
656 XftDrawString16 (d, &R->PixColors[fg].c, f, x, y + R->TermWin.fbase, (const FcChar16 *)text, len); 776 XftDrawString16 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar16 *)text, len);
657 else 777 else
658 XftDrawString32 (d, &R->PixColors[fg].c, f, x, y + R->TermWin.fbase, (const FcChar32 *)text, len); 778 XftDrawString32 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar32 *)text, len);
659 } 779 }
660 else 780 else
661 { 781 {
662 while (len) 782 while (len)
663 { 783 {
664 if (*text != NOCHAR && *text != ' ') 784 if (*text != NOCHAR && *text != ' ')
665 { 785 {
666 if (sizeof (text_t) == sizeof (FcChar16)) 786 if (sizeof (text_t) == sizeof (FcChar16))
667 XftDrawString16 (d, &R->PixColors[fg].c, f, x, y + R->TermWin.fbase, (const FcChar16 *)text, 1); 787 XftDrawString16 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar16 *)text, 1);
668 else 788 else
669 XftDrawString32 (d, &R->PixColors[fg].c, f, x, y + R->TermWin.fbase, (const FcChar32 *)text, 1); 789 XftDrawString32 (d, &r->PixColors[fg].c, f, x, y + r->TermWin.fbase, (const FcChar32 *)text, 1);
670 } 790 }
671 791
672 x += R->TermWin.fwidth; 792 x += r->TermWin.fwidth;
673 text++; 793 text++;
674 len--; 794 len--;
675 } 795 }
676 } 796 }
677} 797}
678#endif 798#endif
679 799
680///////////////////////////////////////////////////////////////////////////// 800/////////////////////////////////////////////////////////////////////////////
681 801
682rxvt_fontset::rxvt_fontset (pR) 802rxvt_fontset::rxvt_fontset (rxvt_t r)
683#ifdef EXPLICIT_CONTEXT 803#ifdef EXPLICIT_CONTEXT
684: rxvt_term(R) 804: r(r)
685#endif 805#endif
686{ 806{
687 clear (); 807 clear ();
688} 808}
689 809
728 f = new rxvt_font_x11; 848 f = new rxvt_font_x11;
729 } 849 }
730 else 850 else
731 f = new rxvt_font_x11; 851 f = new rxvt_font_x11;
732 852
733 f->set_term (aR); 853 f->set_term (r);
734 f->set_name (strdup (name)); 854 f->set_name (strdup (name));
735 855
736 f->cs = cs; 856 f->cs = cs;
737 f->loaded = false; 857 f->loaded = false;
738 858
793rxvt_fontset::realize_font (int i) 913rxvt_fontset::realize_font (int i)
794{ 914{
795 if (fonts[i]->loaded) 915 if (fonts[i]->loaded)
796 return true; 916 return true;
797 917
918 fonts[i]->loaded = true;
919
798 if (fonts[i]->load (height)) 920 if (!fonts[i]->load (height))
799 return fonts[i]->loaded = true; 921 {
800 922 fonts[i]->cs = CS_UNKNOWN;
801 delete fonts[i];
802 fonts.erase (fonts.begin () + i);
803
804 return false; 923 return false;
924 }
925
926 return true;
805} 927}
806 928
807void 929void
808rxvt_fontset::populate (const char *desc) 930rxvt_fontset::populate (const char *desc)
809{ 931{
846 { 968 {
847 if (FROM_UNICODE (f->cs, unicode) == NOCHAR) 969 if (FROM_UNICODE (f->cs, unicode) == NOCHAR)
848 goto next_font; 970 goto next_font;
849 971
850 if (!realize_font (i)) 972 if (!realize_font (i))
851 {
852 --i;
853 goto next_font; 973 goto next_font;
854 } 974 }
855 975
856 //printf ("added font %s for %04lx\n", f->name, unicode);
857 }
858
859 if (f->has_codepoint (unicode)) 976 if (f->cs != CS_UNKNOWN && f->has_codepoint (unicode))
860 return i; 977 return i;
861 978
862 next_font: 979 next_font:
863 if (i == fonts.size () - 1 && fallback->name) 980 if (i == fonts.size () - 1 && fallback->name)
864 { 981 {
865 fonts.push_back (new_font (fallback->name, fallback->cs)); 982 fonts.push_back (new_font (fallback->name, fallback->cs));
866 fallback++; 983 fallback++;
984 i = 0;
867 } 985 }
868 } 986 }
869 987
870 return 0; /* we must return SOME font */ 988 return 0; /* we must return SOME font */
871} 989}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines