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

Comparing rxvt-unicode/src/rxvtfont.C (file contents):
Revision 1.41 by root, Wed Aug 25 02:33:09 2004 UTC vs.
Revision 1.64 by root, Tue Jan 11 05:45:57 2005 UTC

88 { CS_JIS0201_1976_0, "-*-*-*-r-*--*-*-*-*-c-*-jisx0201*-0" }, 88 { CS_JIS0201_1976_0, "-*-*-*-r-*--*-*-*-*-c-*-jisx0201*-0" },
89 { CS_JIS0208_1990_0, "-*-*-*-r-*--*-*-*-*-c-*-jisx0208*-0" }, 89 { CS_JIS0208_1990_0, "-*-*-*-r-*--*-*-*-*-c-*-jisx0208*-0" },
90 { CS_JIS0212_1990_0, "-*-*-*-r-*--*-*-*-*-c-*-jisx0212*-0" }, 90 { CS_JIS0212_1990_0, "-*-*-*-r-*--*-*-*-*-c-*-jisx0212*-0" },
91#endif 91#endif
92 92
93#if ENCODING_CN || ENCODING_CN_EXT 93#if ENCODING_ZH || ENCODING_ZH_EXT
94# if XFT 94# if XFT
95 { CS_GBK_0, "xft:AR PL KaitiM GB" },
96 { CS_GBK_0, "xft:AR PL SungtiL GB" },
97 { CS_GBK_0, "xft::spacing=100:lang=zh" },
95 { CS_BIG5_EXT, "xft:AR PL Mingti2L Big5" }, 98 { CS_BIG5_EXT, "xft:AR PL Mingti2L Big5" },
96 { CS_BIG5_EXT, "xft:AR PL KaitiM Big5" }, 99 { CS_BIG5_EXT, "xft:AR PL KaitiM Big5" },
97 { CS_GB2312_1980_0, "xft:AR PL KaitiM GB" }, 100 { CS_GB2312_1980_0, "xft:AR PL KaitiM GB" },
98 { CS_GB2312_1980_0, "xft:AR PL SungtiL GB" }, 101 { CS_GB2312_1980_0, "xft:AR PL SungtiL GB" },
99 { CS_GB2312_1980_0, "xft::spacing=100:lang=zh" }, 102 { CS_GB2312_1980_0, "xft::spacing=100:lang=zh" },
100# endif 103# endif
104 { CS_GBK_0, "-*-*-*-*-*-*-*-*-*-*-c-*-gbk*-0" },
101 { CS_BIG5, "-*-*-*-*-*-*-*-*-*-*-c-*-big5-0" }, 105 { CS_BIG5, "-*-*-*-*-*-*-*-*-*-*-c-*-big5-0" },
102 { CS_BIG5_PLUS, "-*-*-*-*-*-*-*-*-*-*-c-*-big5p-0" }, 106 { CS_BIG5_PLUS, "-*-*-*-*-*-*-*-*-*-*-c-*-big5p-0" },
103 { CS_BIG5_EXT, "-*-*-*-*-*-*-*-*-*-*-c-*-big5.eten-0" }, 107 { CS_BIG5_EXT, "-*-*-*-*-*-*-*-*-*-*-c-*-big5.eten-0" },
108 { CS_GB2312_1980_0, "-*-*-*-*-*-*-*-*-*-*-c-*-gb2312*-0" },
104 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-gb2312*-0" }, 109 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-gb2312*-0" },
105 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-1" }, 110 { CS_CNS11643_1992_1, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-1" },
106 { CS_CNS11643_1992_2, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-2" }, 111 { CS_CNS11643_1992_2, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-2" },
107 { CS_CNS11643_1992_3, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-3" }, 112 { CS_CNS11643_1992_3, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-3" },
108 { CS_CNS11643_1992_4, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-4" }, 113 { CS_CNS11643_1992_4, "-*-*-*-*-*-*-*-*-*-*-c-*-cns11643*-4" },
125 { CS_UNICODE, "-*-lucidatypewriter-*-*-*-*-*-*-*-*-m-*-iso10646-1" }, 130 { CS_UNICODE, "-*-lucidatypewriter-*-*-*-*-*-*-*-*-m-*-iso10646-1" },
126 { CS_UNICODE, "-*-unifont-*-*-*-*-*-*-*-*-c-*-iso10646-1" }, 131 { CS_UNICODE, "-*-unifont-*-*-*-*-*-*-*-*-c-*-iso10646-1" },
127 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-c-*-iso10646-1" }, 132 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-c-*-iso10646-1" },
128 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" }, 133 { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" },
129#if XFT 134#if XFT
130 { CS_UNICODE, "xft:Bitstream Vera Sans Mono:antialias=false"}, 135 { CS_UNICODE, "xft:Bitstream Vera Sans Mono:antialias=false:autohint=true"},
136 { CS_UNICODE, "xft:Courier New:antialias=false:autohint=true" },
131 { CS_UNICODE, "xft:Andale Mono:antialias=false" }, 137 { CS_UNICODE, "xft:Andale Mono:antialias=false" },
132 { CS_UNICODE, "xft:Arial Unicode MS:antialias=false" }, 138 { CS_UNICODE, "xft:Arial Unicode MS:antialias=false" },
133 { CS_UNICODE, "xft:Courier New:antialias=false" },
134 139
135 // FreeMono is usually uglier than x fonts, so try last only. 140 // FreeMono is usually uglier than x fonts, so try last only.
136 { CS_UNICODE, "xft:FreeMono" }, 141 { CS_UNICODE, "xft:FreeMono:autohint=true" },
137#endif 142#endif
138 143
139 { CS_UNKNOWN, 0 } 144 { CS_UNKNOWN, 0 }
140}; 145};
141 146
142// these characters are used to guess the font height and width 147// these characters are used to guess the font height and width
143// pango uses a similar algorithm and eosn't trust the font either. 148// pango uses a similar algorithm and doesn't trust the font either.
144static uint16_t extent_test_chars[] = { 149static uint16_t extent_test_chars[] = {
145 '0', '1', '8', 'a', 'd', 'x', 'm', 'y', 'g', 'W', 'X', '\'', '_', 150 '0', '1', '8', 'a', 'd', 'x', 'm', 'y', 'g', 'W', 'X', '\'', '_',
146 0x00cd, 0x00d5, 0x0114, 0x0177, 0x0643, // ÍÕĔŷﻙ 151 0x00cd, 0x00d5, 0x0114, 0x0177, 0x0643, // ÍÕĔŷﻙ
147 0x304c, 0x672c, // が本 152 0x304c, 0x672c, // が本
148}; 153};
330{ 335{
331 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg); 336 clear_rect (d, x, y, r->TermWin.fwidth * len, r->TermWin.fheight, bg);
332 337
333 XSetForeground (d.display->display, TGC, r->pix_colors[fg]); 338 XSetForeground (d.display->display, TGC, r->pix_colors[fg]);
334 339
335 while (len--) 340 while (len)
336 { 341 {
337#if ENABLE_COMBINING 342#if ENABLE_COMBINING
338 compose_char *cc; 343 compose_char *cc;
339#endif 344#endif
345 const text_t *tp = text;
340 text_t t = *text++; 346 text_t t = *tp;
347
348 while (++text, --len && *text == NOCHAR)
349 ;
350
351 int width = text - tp;
352 int fwidth = r->TermWin.fwidth * width;
341 353
342 if (0x2500 <= t && t <= 0x259f) 354 if (0x2500 <= t && t <= 0x259f)
343 { 355 {
344 uint16_t offs = linedraw_offs[t - 0x2500]; 356 uint16_t offs = linedraw_offs[t - 0x2500];
345 uint32_t *a = linedraw_command + (offs >> 4); 357 uint32_t *a = linedraw_command + (offs >> 4);
346 uint32_t *b = a + (offs & 15); 358 uint32_t *b = a + (offs & 15);
347 359
348 int W = r->TermWin.fwidth; 360 int W = fwidth;
349 int H = r->TermWin.fheight; 361 int H = r->TermWin.fheight;
350 362
351 int x_[16]; 363 int x_[16];
352 int y_[16]; 364 int y_[16];
353 365
418 } 430 }
419 } 431 }
420#if ENABLE_COMBINING 432#if ENABLE_COMBINING
421 else if (IS_COMPOSE (t) && (cc = rxvt_composite[t])) 433 else if (IS_COMPOSE (t) && (cc = rxvt_composite[t]))
422 { 434 {
435 text_t chrs[2];
436 width = min (2, width);
437 chrs [1] = NOCHAR;
438
439 *chrs = cc->c1;
423 rxvt_font *f1 = (*fs)[fs->find_font (cc->c1)]; 440 rxvt_font *f1 = (*fs)[fs->find_font (cc->c1)];
424 f1->draw (d, x, y, &(t = cc->c1), 1, fg, bg); 441 f1->draw (d, x, y, chrs, width, fg, bg);
442
425 if (cc->c2 != NOCHAR) 443 if (cc->c2 != NOCHAR)
426 { 444 {
445 bool careful;
446
427 // prefer font of first character, for no good reasons 447 // prefer font of first character, for no good reasons
428 bool careful; 448 *chrs = cc->c2;
429 rxvt_font *f2 = f1->has_char (cc->c2, 0, careful) 449 rxvt_font *f2 = (f1->has_char (cc->c2, 0, careful) && !careful)
430 ? f1 450 ? f1
431 : (*fs)[fs->find_font (cc->c2)]; 451 : (*fs)[fs->find_font (cc->c2)];
432 452
433 f2->draw (d, x, y, &(t = cc->c2), 1, fg, -1); 453 f2->draw (d, x, y, chrs, width, fg, -1);
434 } 454 }
435 } 455 }
436#endif 456#endif
437 else 457 else
438 switch (t) 458 switch (t)
441 case ZERO_WIDTH_CHAR: 461 case ZERO_WIDTH_CHAR:
442 case NOCHAR: 462 case NOCHAR:
443 break; 463 break;
444 464
445 default: 465 default:
446 int w = 0;
447 while (len > 0 && *text == NOCHAR)
448 {
449 ++text;
450 --len;
451 w += r->TermWin.fwidth;
452 }
453
454 XDrawRectangle (d.display->display, d, TGC, x + 2, y + 2, 466 XDrawRectangle (d.display->display, d, TGC, x + 2, y + 2,
455 w + r->TermWin.fwidth - 4, r->TermWin.fheight - 4); 467 fwidth - 4, r->TermWin.fheight - 4);
456 x += w;
457 } 468 }
458 469
459 x += r->TermWin.fwidth; 470 x += fwidth;
460 } 471 }
461} 472}
462 473
463///////////////////////////////////////////////////////////////////////////// 474/////////////////////////////////////////////////////////////////////////////
464 475
520 531
521bool 532bool
522rxvt_font_x11::set_properties (rxvt_fontprop &p, XFontStruct *f) 533rxvt_font_x11::set_properties (rxvt_fontprop &p, XFontStruct *f)
523{ 534{
524 unsigned long height; 535 unsigned long height;
536
537#if 0
525 if (!XGetFontProperty (f, XInternAtom (DISPLAY, "PIXEL_SIZE", 0), &height)) 538 if (!XGetFontProperty (f, XInternAtom (DISPLAY, "PIXEL_SIZE", 0), &height))
526 return false; 539 return false;
540#else
541 height = f->ascent + f->descent;
542#endif
527 543
528 unsigned long avgwidth; 544 unsigned long avgwidth;
529 if (!XGetFontProperty (f, XInternAtom (DISPLAY, "AVERAGE_WIDTH", 0), &avgwidth)) 545 if (!XGetFontProperty (f, XInternAtom (DISPLAY, "AVERAGE_WIDTH", 0), &avgwidth))
530 avgwidth = 0; 546 avgwidth = 0;
531 547
659 ? "r" : "i"); // TODO: handle "o"blique, too 675 ? "r" : "i"); // TODO: handle "o"blique, too
660 set_name (strdup (fname)); 676 set_name (strdup (fname));
661 } 677 }
662 } 678 }
663 679
680 sprintf (field_str, "%d", prop.height == rxvt_fontprop::unset
681 ? 0 : prop.height);
682
683 struct font_weight {
684 char *name;
685 int diff;
686
687 void clear ()
688 {
689 name = 0;
690 diff = 0x7fffffff;
691 }
692
693 font_weight () { clear (); }
694 ~font_weight () { free (name); }
695 };
696
664 char **list; 697 char **list;
665 int count; 698 int count;
666 list = XListFonts (DISPLAY, name, 1024, &count); 699 list = XListFonts (DISPLAY, name, 4000, &count);
667 700
668 set_name (0); 701 set_name (0);
669 702
670 if (!list) 703 if (!list)
671 return false; 704 return false;
672 705
673 sprintf (field_str, "%d", prop.height == rxvt_fontprop::unset 706 font_weight *fonts = new font_weight[count];
674 ? 0 : prop.height);
675 707
676 int bestdiff = 0x7fffffff;
677 for (int i = 0; i < count; i++) 708 for (int i = 0; i < count; i++)
678 { 709 {
679 rxvt_fontprop p; 710 rxvt_fontprop p;
680 char fname[1024]; 711 char fname[1024];
681 712
682 int diff = 0; 713 int diff = 0;
683 714
684 if (replace_field (fname, list[i], 6, '0', field_str)) 715 if (replace_field (fname, list[i], 6, '0', field_str))
685 diff += 10; // slightly penalize scalable fonts 716 diff += 10; // slightly penalize scalable fonts
686 717
687 if (!set_properties (p, fname)) 718 if (!set_properties (p, fname))
688 continue; 719 continue;
694 if (prop.height != rxvt_fontprop::unset) diff += (prop.height - p.height) * 128; 725 if (prop.height != rxvt_fontprop::unset) diff += (prop.height - p.height) * 128;
695 if (prop.weight != rxvt_fontprop::unset) diff += abs (prop.weight - p.weight); 726 if (prop.weight != rxvt_fontprop::unset) diff += abs (prop.weight - p.weight);
696 if (prop.slant != rxvt_fontprop::unset) diff += abs (prop.slant - p.slant); 727 if (prop.slant != rxvt_fontprop::unset) diff += abs (prop.slant - p.slant);
697 //if (prop.width != rxvt_fontprop::unset) diff += abs (prop.width - p.width); 728 //if (prop.width != rxvt_fontprop::unset) diff += abs (prop.width - p.width);
698 729
699 if (!name // compare against best found so far 730 fonts[i].name = strdup (fname);
700 || diff < bestdiff) 731 fonts[i].diff = diff;
701 {
702 set_name (strdup (fname));
703 bestdiff = diff;
704 }
705 } 732 }
706 733
707 XFreeFontNames (list); 734 XFreeFontNames (list);
708 735
709 if (!name) 736 // this loop only iterates when the guessed font-size is too small
710 return false; 737 for (;;)
738 {
739 font_weight *best = fonts + count - 1;
711 740
741 for (font_weight *w = best; w-- > fonts; )
742 if (w->diff < best->diff)
743 best = w;
744
745 if (!best->name
712 f = XLoadQueryFont (DISPLAY, name); 746 || !(f = XLoadQueryFont (DISPLAY, best->name)))
747 break;
748
749 set_name (best->name);
750 best->clear ();
751
752 ascent = f->ascent;
753 descent = f->descent;
754 height = ascent + descent;
755
756 if (prop.height == rxvt_fontprop::unset
757 || height <= prop.height)
758 break; // font is ready for use
759
760 // PIXEL_SIZE small enough, but real height too large
761 clear ();
762 }
763
764 delete [] fonts;
713 765
714 if (!f) 766 if (!f)
715 return false; 767 return false;
716 768
717 char *registry = get_property (f, "CHARSET_REGISTRY", 0); 769 char *registry = get_property (f, "CHARSET_REGISTRY", 0);
745 if (cs == CS_UNICODE) 797 if (cs == CS_UNICODE)
746 cs = CS_UNICODE_16; // X11 can have a max. of 65536 chars per font 798 cs = CS_UNICODE_16; // X11 can have a max. of 65536 chars per font
747 799
748 encm = f->min_byte1 != 0 || f->max_byte1 != 0; 800 encm = f->min_byte1 != 0 || f->max_byte1 != 0;
749 enc2b = encm || f->max_char_or_byte2 > 255; 801 enc2b = encm || f->max_char_or_byte2 > 255;
750
751 ascent = f->ascent;
752 descent = f->descent;
753 height = ascent + descent;
754 802
755 slow = false; 803 slow = false;
756 804
757#if 1 // only used for slow detection, TODO optimize 805#if 1 // only used for slow detection, TODO optimize
758 if (f->min_bounds.width == f->max_bounds.width) 806 if (f->min_bounds.width == f->max_bounds.width)
1042 return false; 1090 return false;
1043 1091
1044 FcValue v; 1092 FcValue v;
1045 1093
1046 if (prop.height != rxvt_fontprop::unset 1094 if (prop.height != rxvt_fontprop::unset
1047 && FcPatternGet (p, FC_PIXEL_SIZE, 0, &v) != FcResultMatch) 1095 || (FcPatternGet (p, FC_PIXEL_SIZE, 0, &v) != FcResultMatch
1096 && FcPatternGet (p, FC_SIZE, 0, &v) != FcResultMatch))
1048 FcPatternAddInteger (p, FC_PIXEL_SIZE, prop.height); 1097 FcPatternAddInteger (p, FC_PIXEL_SIZE, prop.height);
1049 1098
1050 if (prop.weight != rxvt_fontprop::unset 1099 if (prop.weight != rxvt_fontprop::unset
1051 && FcPatternGet (p, FC_WEIGHT, 0, &v) != FcResultMatch) 1100 && FcPatternGet (p, FC_WEIGHT, 0, &v) != FcResultMatch)
1052 FcPatternAddInteger (p, FC_WEIGHT, prop.weight); 1101 FcPatternAddInteger (p, FC_WEIGHT, prop.weight);
1264} 1313}
1265 1314
1266void 1315void
1267rxvt_fontset::clear () 1316rxvt_fontset::clear ()
1268{ 1317{
1318 prop.width = prop.height = prop.weight = prop.slant
1319 = rxvt_fontprop::unset;
1320
1269 for (rxvt_font **i = fonts.begin (); i != fonts.end (); i++) 1321 for (rxvt_font **i = fonts.begin (); i != fonts.end (); i++)
1270 FONT_UNREF (*i); 1322 FONT_UNREF (*i);
1271 1323
1272 for (pagemap **p = fmap.begin (); p != fmap.end (); p++) 1324 for (pagemap **p = fmap.begin (); p != fmap.end (); p++)
1273 delete *p; 1325 delete *p;
1393 1445
1394 return true; 1446 return true;
1395} 1447}
1396 1448
1397bool 1449bool
1398rxvt_fontset::populate (const char *desc, const rxvt_fontprop &prop) 1450rxvt_fontset::populate (const char *desc)
1399{ 1451{
1400 clear (); 1452 clear ();
1401 1453
1402 fontdesc = strdup (desc); 1454 fontdesc = strdup (desc);
1403 1455
1404 fonts.push_back (new_font (0, CS_UNICODE)); 1456 fonts.push_back (new_font (0, CS_UNICODE));
1405 realize_font (0); 1457 realize_font (0);
1406
1407 this->prop = prop;
1408 1458
1409 add_fonts (desc); 1459 add_fonts (desc);
1410 1460
1411 return true; 1461 return true;
1412} 1462}

Diff Legend

Removed lines
+ Added lines
< Changed lines
> Changed lines