--- rxvt-unicode/src/rxvtfont.C 2006/01/25 21:03:04 1.87 +++ rxvt-unicode/src/rxvtfont.C 2006/01/30 04:27:17 1.91 @@ -26,17 +26,17 @@ #include "rxvtfont.h" #include -#include + #include #define MAX_OVERLAP_ROMAN (8 + 2) // max. character width in 8ths of the base width #define MAX_OVERLAP_ITALIC (8 + 3) // max. overlap for italic fonts -#define OVERLAP_OK(w,prop) (w) > ( \ - prop->slant >= rxvt_fontprop::italic \ - ? (prop->width * MAX_OVERLAP_ITALIC + 7) >> 3 \ - : (prop->width * MAX_OVERLAP_ROMAN + 7) >> 3 \ - ) +#define OVERLAP_OK(w,wcw,prop) ((w) <= ( \ + (prop)->slant >= rxvt_fontprop::italic \ + ? ((prop)->width * (wcw) * MAX_OVERLAP_ITALIC + 7) >> 3 \ + : ((prop)->width * (wcw) * MAX_OVERLAP_ROMAN + 7) >> 3 \ + )) const struct rxvt_fallback_font { codeset cs; @@ -66,15 +66,15 @@ { CS_ISO8859_16, "-*-*-*-r-*--*-*-*-*-c-*-iso8859-16" }, # if XFT - { CS_KOI8_U, "xft::spacing=100:lang=ru:antialias=false" }, - - { CS_ISO8859_5, "xft::spacing=100:lang=ru:antialias=false" }, - { CS_ISO8859_6, "xft::spacing=100:lang=ar:antialias=false" }, - { CS_ISO8859_7, "xft::spacing=100:lang=el:antialias=false" }, - { CS_ISO8859_8, "xft::spacing=100:lang=he:antialias=false" }, - { CS_ISO8859_9, "xft::spacing=100:lang=tr:antialias=false" }, - { CS_ISO8859_10, "xft::spacing=100:lang=se:antialias=false" }, - { CS_ISO8859_11, "xft::spacing=100:lang=th:antialias=false" }, + { CS_KOI8_U, "xft::lang=ru" }, + + { CS_ISO8859_5, "xft::lang=ru" }, + { CS_ISO8859_6, "xft::lang=ar" }, + { CS_ISO8859_7, "xft::lang=el" }, + { CS_ISO8859_8, "xft::lang=he" }, + { CS_ISO8859_9, "xft::lang=tr" }, + { CS_ISO8859_10, "xft::lang=se" }, + { CS_ISO8859_11, "xft::lang=th" }, # endif #endif @@ -85,7 +85,7 @@ { CS_JIS0208_1990_0, "xft:Kochi Gothic:antialias=false" }, { CS_JIS0208_1990_0, "xft:Sazanami Mincho:antialias=false" }, { CS_JIS0208_1990_0, "xft:Mincho:antialias=false" }, - { CS_JIS0208_1990_0, "xft::lang=ja:spacing=100:antialias=false" }, + { CS_JIS0208_1990_0, "xft::lang=ja:antialias=false" }, # endif { CS_JIS0201_1976_0, "-*-mincho-*-r-*--*-*-*-*-c-*-jisx0201*-0" }, { CS_JIS0208_1990_0, "-*-mincho-*-r-*--*-*-*-*-c-*-jisx0208*-0" }, @@ -99,12 +99,12 @@ # if XFT { CS_GBK_0, "xft:AR PL KaitiM GB" }, { CS_GBK_0, "xft:AR PL SungtiL GB" }, - { CS_GBK_0, "xft::spacing=100:lang=zh" }, + { CS_GBK_0, "xft::lang=zh" }, { CS_BIG5_EXT, "xft:AR PL Mingti2L Big5" }, { CS_BIG5_EXT, "xft:AR PL KaitiM Big5" }, { CS_GB2312_1980_0, "xft:AR PL KaitiM GB" }, { CS_GB2312_1980_0, "xft:AR PL SungtiL GB" }, - { CS_GB2312_1980_0, "xft::spacing=100:lang=zh" }, + { CS_GB2312_1980_0, "xft::lang=zh" }, # endif { CS_GBK_0, "-*-*-*-*-*-*-*-*-*-*-c-*-gbk*-0" }, { CS_BIG5, "-*-*-*-*-*-*-*-*-*-*-c-*-big5-0" }, @@ -127,7 +127,7 @@ { CS_KSC5601_1987_0, "-*-*-*-*-*-*-*-*-*-*-c-*-ksc5601*" }, # if XFT { CS_KSC5601_1987_0, "xft:Baekmuk Gulim:antialias=false" }, - { CS_KSC5601_1987_0, "xft::spacing=100:lang=ko:antialias=false" }, + { CS_KSC5601_1987_0, "xft::lang=ko:antialias=false" }, # endif #endif @@ -159,7 +159,7 @@ #define NUM_EXTENT_TEST_CHARS (sizeof (extent_test_chars) / sizeof (extent_test_chars[0])) -#define dTermDisplay Display *disp = term->display->display +#define dTermDisplay Display *disp = term->xdisp #define dTermGC GC gc = term->gc ///////////////////////////////////////////////////////////////////////////// @@ -230,6 +230,11 @@ ///////////////////////////////////////////////////////////////////////////// +rxvt_font::rxvt_font () +: name(0), width(rxvt_fontprop::unset), height(rxvt_fontprop::unset) +{ +} + void rxvt_font::set_name (char *name) { @@ -247,7 +252,7 @@ dTermGC; if (color == Color_bg) - XClearArea (disp, d, x, y, w, h, FALSE); + XClearArea (disp, d, x, y, w, h, false); else if (color >= 0) { #if XFT @@ -259,6 +264,8 @@ } } +///////////////////////////////////////////////////////////////////////////// + #include "table/linedraw.h" struct rxvt_font_default : rxvt_font { @@ -434,8 +441,9 @@ #if ENABLE_COMBINING else if (IS_COMPOSE (t) && (cc = rxvt_composite[t])) { + min_it (width, 2); // we only support wcwidth up to 2 + text_t chrs[2]; - width = min (2, width); chrs [1] = NOCHAR; *chrs = cc->c1; @@ -495,19 +503,19 @@ codeset cs; bool enc2b, encm; - char *get_property (XFontStruct *f, const char *property, const char *repl) const; + char *get_property (XFontStruct *f, Atom property, const char *repl) const; bool set_properties (rxvt_fontprop &p, int height, const char *weight, const char *slant, int avgwidth); bool set_properties (rxvt_fontprop &p, XFontStruct *f); bool set_properties (rxvt_fontprop &p, const char *name); }; char * -rxvt_font_x11::get_property (XFontStruct *f, const char *property, const char *repl) const +rxvt_font_x11::get_property (XFontStruct *f, Atom property, const char *repl) const { unsigned long value; - if (XGetFontProperty (f, XInternAtom (term->display->display, property, 0), &value)) - return XGetAtomName (term->display->display, value); + if (XGetFontProperty (f, property, &value)) + return XGetAtomName (term->xdisp, value); else return rxvt_strdup (repl); } @@ -523,7 +531,9 @@ bool rxvt_font_x11::set_properties (rxvt_fontprop &p, int height, const char *weight, const char *slant, int avgwidth) { - p.width = avgwidth ? (avgwidth + 1) / 10 : (height + 1) / 2; + p.width = width != rxvt_fontprop::unset ? width + : avgwidth ? (avgwidth + 1) / 10 + : (height + 1) / 2; p.height = height; p.ascent = rxvt_fontprop::unset; p.weight = *weight == 'B' || *weight == 'b' ? rxvt_fontprop::bold : rxvt_fontprop::medium; @@ -538,18 +548,18 @@ unsigned long height; #if 0 - if (!XGetFontProperty (f, XInternAtom (term->display->display, "PIXEL_SIZE", 0), &height)) + if (!XGetFontProperty (f, XInternAtom (term->xdisp, "PIXEL_SIZE", 0), &height)) return false; #else height = f->ascent + f->descent; #endif unsigned long avgwidth; - if (!XGetFontProperty (f, XInternAtom (term->display->display, "AVERAGE_WIDTH", 0), &avgwidth)) + if (!XGetFontProperty (f, term->xa [XA_AVERAGE_WIDTH], &avgwidth)) avgwidth = 0; - char *weight = get_property (f, "WEIGHT_NAME", "medium"); - char *slant = get_property (f, "SLANT", "r"); + char *weight = get_property (f, term->xa [XA_WEIGHT_NAME], "medium"); + char *slant = get_property (f, term->xa [XA_SLANT], "r"); set_properties (p, height, weight, slant, avgwidth); @@ -657,7 +667,7 @@ if (!f) return false; - char *new_name = get_property (f, "FONT", name); + char *new_name = get_property (f, XA_FONT, name); if (new_name) set_name (new_name); @@ -776,8 +786,8 @@ if (!f) return false; - char *registry = get_property (f, "CHARSET_REGISTRY", 0); - char *encoding = get_property (f, "CHARSET_ENCODING", 0); + char *registry = get_property (f, term->xa [XA_CHARSET_REGISTRY], 0); + char *encoding = get_property (f, term->xa [XA_CHARSET_ENCODING], 0); if (registry && encoding) { @@ -788,7 +798,7 @@ } else { - const char *charset = get_property (f, "FONT", 0); + const char *charset = get_property (f, XA_FONT, 0); if (!charset) charset = name; @@ -813,9 +823,7 @@ slow = false; #if 1 // only used for slow detection, TODO optimize - if (f->min_bounds.width == f->max_bounds.width) - width = f->min_bounds.width; - else if (f->per_char == NULL) + if (f->min_bounds.width == f->max_bounds.width || !f->per_char) width = f->max_bounds.width; else { @@ -841,9 +849,7 @@ for (uint16_t *t = extent_test_chars + NUM_EXTENT_TEST_CHARS; t-- > extent_test_chars; ) { - if (cs != CS_UNICODE - && *t > 0x100 - && FROM_UNICODE (cs, *t) == NOCHAR) + if (FROM_UNICODE (cs, *t) == NOCHAR) continue; // ignore characters we wouldn't use anyways @@ -859,7 +865,7 @@ int wcw = WCWIDTH (*t); if (wcw > 0) g.width = (g.width + wcw - 1) / wcw; - if (width < g.width) width = g.width; + if (width < g.width) width = g.width; } if (cs == CS_UNKNOWN) @@ -886,7 +892,7 @@ { if (f) { - XFreeFont (term->display->display, f); + XFreeFont (term->xdisp, f); f = 0; } } @@ -939,13 +945,13 @@ if (!prop || prop->width == rxvt_fontprop::unset) return true; - // check character against base font bounding box + // check wether character overlaps previous/next character int w = xcs->rbearing - xcs->lbearing; int wcw = WCWIDTH (unicode); - if (wcw > 0) w = (w + wcw - 1) / wcw; - careful = w > prop->width; - if (careful && OVERLAP_OK (w, prop)) + careful = xcs->lbearing < 0 || xcs->rbearing > prop->width * wcw; + + if (careful && !OVERLAP_OK (w, wcw, prop)) return false; return true; @@ -1068,7 +1074,7 @@ { if (f) { - XftFontClose (term->display->display, f); + XftFontClose (term->xdisp, f); f = 0; } } @@ -1245,7 +1251,7 @@ { careful = false; - if (!XftCharExists (term->display->display, f, unicode)) + if (!XftCharExists (term->xdisp, f, unicode)) return false; if (!prop || prop->width == rxvt_fontprop::unset) @@ -1254,14 +1260,18 @@ // check character against base font bounding box FcChar32 ch = unicode; XGlyphInfo g; - XftTextExtents32 (term->display->display, f, &ch, 1, &g); + XftTextExtents32 (term->xdisp, f, &ch, 1, &g); int w = g.width - g.x; int wcw = WCWIDTH (unicode); - if (wcw > 0) w = (w + wcw - 1) / wcw; - careful = w > prop->width; - if (careful && OVERLAP_OK (w, prop)) + careful = g.x > 0 || w > prop->width * wcw; + + if (careful && !OVERLAP_OK (w, wcw, prop)) + return false; + + // this weeds out _totally_ broken fonts, or glyphs + if (!OVERLAP_OK (g.xOff, wcw, prop)) return false; return true; @@ -1298,9 +1308,14 @@ FT_UInt glyph = XftCharIndex (disp, f, fc); XftGlyphExtents (disp, f, &glyph, 1, &extents); + ep->glyph = glyph; ep->x = x + (cwidth - extents.xOff >> 1); ep->y = y + ascent; + + if (extents.xOff == 0) + ep->x = x + cwidth; + ep++; } @@ -1562,7 +1577,7 @@ //FcPatternAddBool (p, FC_ANTIALIAS, 1); XftResult result; - FcPattern *match = XftFontMatch (term->display->display, term->display->screen, p, &result); + FcPattern *match = XftFontMatch (term->xdisp, term->display->screen, p, &result); FcPatternDestroy (p);