--- rxvt-unicode/src/rxvtfont.C 2005/02/12 18:55:04 1.67 +++ rxvt-unicode/src/rxvtfont.C 2005/12/06 15:41:26 1.74 @@ -16,7 +16,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA *---------------------------------------------------------------------*/ #include "../config.h" @@ -132,10 +132,10 @@ { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-c-*-iso10646-1" }, { CS_UNICODE, "-*-*-*-r-*-*-*-*-*-*-m-*-iso10646-1" }, #if XFT - { CS_UNICODE, "xft:Bitstream Vera Sans Mono:antialias=false:autohint=true"}, - { CS_UNICODE, "xft:Courier New:antialias=false:autohint=true" }, - { CS_UNICODE, "xft:Andale Mono:antialias=false" }, - { CS_UNICODE, "xft:Arial Unicode MS:antialias=false" }, + { CS_UNICODE, "xft:Bitstream Vera Sans Mono:antialias=false:autohint=true" }, + { CS_UNICODE, "xft:Courier New:antialias=false:autohint=true" }, + { CS_UNICODE, "xft:Andale Mono:antialias=false:autohint=false" }, + { CS_UNICODE, "xft:Arial Unicode MS:antialias=false:autohint=false" }, // FreeMono is usually uglier than x fonts, so try last only. { CS_UNICODE, "xft:FreeMono:autohint=true" }, @@ -718,6 +718,8 @@ if (replace_field (fname, list[i], 6, '0', field_str)) diff += 10; // slightly penalize scalable fonts + else if (replace_field (fname, list[i], 11, '0', "0")) + diff += 300; // more heavily penalize what looks like scaled bitmap fotns if (!set_properties (p, fname)) continue; @@ -743,7 +745,7 @@ font_weight *best = fonts + count - 1; for (font_weight *w = best; w-- > fonts; ) - if (w->diff < best->diff) + if (w->diff <= best->diff) best = w; if (!best->name @@ -851,7 +853,7 @@ int dir_ret, asc_ret, des_ret; XTextExtents16 (f, &ch, 1, &dir_ret, &asc_ret, &des_ret, &g); - int wcw = wcwidth (*t); if (wcw > 0) g.width = g.width / wcw; + int wcw = wcwidth (*t); if (wcw > 0) g.width = (g.width + wcw - 1) / wcw; if (width < g.width) width = g.width; } @@ -936,7 +938,7 @@ // check character against base font bounding box int w = xcs->width; int wcw = wcwidth (unicode); - if (wcw > 0) w /= wcw; + if (wcw > 0) w = (w + wcw - 1) / wcw; careful = w > prop->width; if (careful && w > prop->width * MAX_OVERLAP >> 2) @@ -1098,7 +1100,7 @@ FcValue v; if (prop.height != rxvt_fontprop::unset - || (FcPatternGet (p, FC_PIXEL_SIZE, 0, &v) != FcResultMatch + && (FcPatternGet (p, FC_PIXEL_SIZE, 0, &v) != FcResultMatch && FcPatternGet (p, FC_SIZE, 0, &v) != FcResultMatch)) FcPatternAddInteger (p, FC_PIXEL_SIZE, prop.height); @@ -1154,6 +1156,8 @@ XftUnlockFace (f); + int glheight = height; + for (uint16_t *t = extent_test_chars + NUM_EXTENT_TEST_CHARS; t-- > extent_test_chars; ) { FcChar16 ch = *t; @@ -1171,15 +1175,29 @@ XGlyphInfo g; XftTextExtents16 (disp, f, &ch, 1, &g); + g.width -= g.x; + int wcw = wcwidth (ch); - if (wcw > 0) g.width = g.width / wcw; + if (wcw > 0) g.width = (g.width + wcw - 1) / wcw; - if (width < g.width) width = g.width; - if (height < g.height) height = g.height; + if (width < g.width ) width = g.width; + if (height < g.height ) height = g.height; + if (glheight < g.height - g.y) glheight = g.height - g.y; + } + + if (!width) + { + rxvt_warn ("unable to calculate font width for '%s', ignoring.\n", name); + + XftFontClose (disp, f); + f = 0; + + success = false; + break; } if (prop.height == rxvt_fontprop::unset - || height <= prop.height + || (height <= prop.height && glheight <= prop.height) || height <= 2 || !scalable) break; @@ -1196,9 +1214,9 @@ else ftheight = prop.height - 1; - XftFontClose (disp, f); - FcPatternDel (match, FC_PIXEL_SIZE); - FcPatternAddInteger (match, FC_PIXEL_SIZE, ftheight); + XftFontClose (disp, f); + FcPatternDel (match, FC_PIXEL_SIZE); + FcPatternAddInteger (match, FC_PIXEL_SIZE, ftheight); } FcPatternDestroy (match); @@ -1230,9 +1248,9 @@ XGlyphInfo g; XftTextExtents32 (DISPLAY, f, &ch, 1, &g); - int w = g.width; + int w = g.width - g.x; int wcw = wcwidth (unicode); - if (wcw > 0) w /= wcw; + if (wcw > 0) w = (w + wcw - 1) / wcw; careful = w > prop->width; if (careful && w > prop->width * MAX_OVERLAP >> 2) @@ -1254,61 +1272,60 @@ FcChar32 *enc = (FcChar32 *) get_enc_buf (len * sizeof (FcChar32)); FcChar32 *ep = enc; int ewidth = 0; - int xoff = 0; while (len) { int cwidth = r->TermWin.fwidth; FcChar32 fc = *text++; len--; - FT_UInt gl; while (len && *text == NOCHAR) text++, len--, cwidth += r->TermWin.fwidth; - gl = XftCharIndex (d.display->display, f, fc); - XftGlyphExtents (d.display->display, f, &gl, 1, &extents); - - if (extents.xOff != cwidth && ep != enc) - { - if (xoff > ewidth) xoff = ewidth; - XftDrawGlyphs (d, &r->pix_colors[fg].c, f, - x + (ewidth - xoff >> 1), - y + base, enc, ep - enc); - x += ewidth; - - ep = enc; - ewidth = 0; - xoff = 0; - } - if (fc == ' ' && ep == enc) // skip leading spaces - { - x += cwidth; - continue; - } - + x += cwidth; else { - *ep++ = gl; - ewidth += cwidth; - xoff += extents.xOff; + FT_UInt gl = XftCharIndex (d.display->display, f, fc); + XftGlyphExtents (d.display->display, f, &gl, 1, &extents); + + if (extents.xOff != cwidth) + { + if (ewidth) + { + XftDrawGlyphs (d, &r->pix_colors[fg].c, f, + x, y + base, enc, ep - enc); + x += ewidth; + + ep = enc; + ewidth = 0; + } + + if (extents.xOff > cwidth) + extents.xOff = cwidth; + + XftDrawGlyphs (d, &r->pix_colors[fg].c, f, + x + (cwidth - extents.xOff >> 1), + y + base, &gl, 1); + x += cwidth; + } + else + { + *ep++ = gl; + ewidth += cwidth; + } } } if (ep != enc) - { - if (xoff > ewidth) xoff = ewidth; - XftDrawGlyphs (d, &r->pix_colors[fg].c, f, - x + (ewidth - xoff >> 1), - y + base, enc, ep - enc); - } + XftDrawGlyphs (d, &r->pix_colors[fg].c, f, + x, y + base, enc, ep - enc); } #endif ///////////////////////////////////////////////////////////////////////////// rxvt_fontset::rxvt_fontset (rxvt_t r) -: r (r), fontdesc (0) +: fontdesc (0), r (r) { clear (); }