--- rxvt-unicode/src/rxvtfont.C 2006/01/09 07:35:23 1.83 +++ rxvt-unicode/src/rxvtfont.C 2006/01/25 21:03:04 1.87 @@ -29,10 +29,14 @@ #include #include -#define DISPLAY r->display->display -#define TGC r->gc +#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 MAX_OVERLAP (4 + 1) // max. character width in 4ths of the base width +#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 \ + ) const struct rxvt_fallback_font { codeset cs; @@ -155,6 +159,9 @@ #define NUM_EXTENT_TEST_CHARS (sizeof (extent_test_chars) / sizeof (extent_test_chars[0])) +#define dTermDisplay Display *disp = term->display->display +#define dTermGC GC gc = term->gc + ///////////////////////////////////////////////////////////////////////////// #if XFT @@ -167,7 +174,7 @@ rxvt_drawable::operator XftDraw *() { if (!xftdrawable) - xftdrawable = XftDrawCreate (display->display, drawable, display->visual, display->cmap); + xftdrawable = XftDrawCreate (screen->xdisp, drawable, screen->visual, screen->cmap); return xftdrawable; } @@ -175,26 +182,11 @@ ///////////////////////////////////////////////////////////////////////////// -static void *enc_buf; -static uint32_t enc_len; - -static inline void * -get_enc_buf (uint32_t len) -{ - if (len > enc_len) - { - free (enc_buf); - enc_buf = malloc (len); - enc_len = len; - } - - return enc_buf; -} - static const char * enc_char (const text_t *text, uint32_t len, codeset cs, bool &zero) { - uint8_t *buf = (uint8_t *)get_enc_buf (len); + uint8_t *buf = rxvt_temp_buf (len); + uint8_t *res = buf; while (len--) { @@ -209,13 +201,14 @@ *buf++ = c; } - return (const char *)enc_buf; + return (const char *)res; } static const XChar2b * enc_xchar2b (const text_t *text, uint32_t len, codeset cs, bool &zero) { - XChar2b *buf = (XChar2b *)get_enc_buf (len * sizeof (XChar2b)); + XChar2b *buf = rxvt_temp_buf (len); + XChar2b *res = buf; while (len--) { @@ -232,7 +225,7 @@ buf++; } - return (XChar2b *)enc_buf; + return res; } ///////////////////////////////////////////////////////////////////////////// @@ -248,17 +241,20 @@ } void -rxvt_font::clear_rect (rxvt_drawable &d, int x, int y, int w, int h, int color) +rxvt_font::clear_rect (rxvt_drawable &d, int x, int y, int w, int h, int color) const { + dTermDisplay; + dTermGC; + if (color == Color_bg) - XClearArea (d.display->display, d, x, y, w, h, FALSE); + XClearArea (disp, d, x, y, w, h, FALSE); else if (color >= 0) { #if XFT - XftDrawRect (d, &r->pix_colors[color].c, x, y, w, h); + XftDrawRect (d, &term->pix_colors[color].c, x, y, w, h); #else - XSetForeground (d.display->display, TGC, r->pix_colors[color]); - XFillRectangle (d.display->display, d, TGC, x, y, w, h); + XSetForeground (disp, gc, term->pix_colors[color]); + XFillRectangle (disp, d, gc, x, y, w, h); #endif } } @@ -296,7 +292,7 @@ return true; } - bool has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) + bool has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) const { careful = false; @@ -310,7 +306,7 @@ return true; if (unicode >= 0x2500 && unicode <= 0x259f && - !r->option (Opt_skipBuiltinGlyphs)) + !term->option (Opt_skipBuiltinGlyphs)) return true; if (IS_COMPOSE (unicode)) @@ -336,11 +332,12 @@ const text_t *text, int len, int fg, int bg) { - Display *disp = d.display->display; + dTermDisplay; + dTermGC; - clear_rect (d, x, y, r->fwidth * len, r->fheight, bg); + clear_rect (d, x, y, term->fwidth * len, term->fheight, bg); - XSetForeground (disp, TGC, r->pix_colors[fg]); + XSetForeground (disp, gc, term->pix_colors[fg]); while (len) { @@ -354,7 +351,7 @@ ; int width = text - tp; - int fwidth = r->fwidth * width; + int fwidth = term->fwidth * width; if (0x2500 <= t && t <= 0x259f) { @@ -363,7 +360,7 @@ uint32_t *b = a + (offs & 15); int W = fwidth; - int H = r->fheight; + int H = term->fheight; int x_[16]; int y_[16]; @@ -381,7 +378,7 @@ gcv.cap_style = CapButt; gcv.line_width = 0; - XChangeGC (disp, TGC, GCLineWidth | GCCapStyle, &gcv); + XChangeGC (disp, gc, GCLineWidth | GCCapStyle, &gcv); while (a < b) { @@ -398,7 +395,7 @@ switch (op) { case 0: // line - XDrawLine (disp, d, TGC, x1, y1, x2, y2); + XDrawLine (disp, d, gc, x1, y1, x2, y2); break; case 1: // rectangle, possibly stippled @@ -411,23 +408,23 @@ gcv.ts_x_origin = x; gcv.ts_y_origin = y; - XChangeGC (disp, TGC, + XChangeGC (disp, gc, GCFillStyle | GCStipple | GCTileStipXOrigin | GCTileStipYOrigin, &gcv); } - XFillRectangle (disp, d, TGC, x1, y1, x2 - x1 + 1, y2 - y1 + 1); + XFillRectangle (disp, d, gc, x1, y1, x2 - x1 + 1, y2 - y1 + 1); if (a) { XFreePixmap (disp, gcv.stipple); gcv.stipple = 0; gcv.fill_style = FillSolid; - XChangeGC (disp, TGC, GCFillStyle, &gcv); + XChangeGC (disp, gc, GCFillStyle, &gcv); } break; case 2: // arc - XDrawArc (disp, d, TGC, + XDrawArc (disp, d, gc, x1 - W/2, y1 - H/2, W-1, H-1, (a - 1) * 90*64, (b - 1) * 90*64); break; @@ -468,8 +465,8 @@ break; default: - XDrawRectangle (disp, d, TGC, x + 2, y + 2, - fwidth - 4, r->fheight - 4); + XDrawRectangle (disp, d, gc, x + 2, y + 2, + fwidth - 4, term->fheight - 4); } x += fwidth; @@ -487,7 +484,7 @@ bool load (const rxvt_fontprop &prop); - bool has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful); + bool has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) const; void draw (rxvt_drawable &d, int x, int y, const text_t *text, int len, @@ -509,8 +506,8 @@ { unsigned long value; - if (XGetFontProperty (f, XInternAtom (DISPLAY, property, 0), &value)) - return XGetAtomName (DISPLAY, value); + if (XGetFontProperty (f, XInternAtom (term->display->display, property, 0), &value)) + return XGetAtomName (term->display->display, value); else return rxvt_strdup (repl); } @@ -541,14 +538,14 @@ unsigned long height; #if 0 - if (!XGetFontProperty (f, XInternAtom (DISPLAY, "PIXEL_SIZE", 0), &height)) + if (!XGetFontProperty (f, XInternAtom (term->display->display, "PIXEL_SIZE", 0), &height)) return false; #else height = f->ascent + f->descent; #endif unsigned long avgwidth; - if (!XGetFontProperty (f, XInternAtom (DISPLAY, "AVERAGE_WIDTH", 0), &avgwidth)) + if (!XGetFontProperty (f, XInternAtom (term->display->display, "AVERAGE_WIDTH", 0), &avgwidth)) avgwidth = 0; char *weight = get_property (f, "WEIGHT_NAME", "medium"); @@ -567,6 +564,7 @@ bool rxvt_font_x11::set_properties (rxvt_fontprop &p, const char *name) { + dTermDisplay; int slashes = 0; const char *comp[13]; @@ -584,7 +582,7 @@ && (*comp[11] >= '0' && *comp[11] <= '9')) return set_properties (p, atoi (comp[6]), comp[2], comp[3], atoi (comp[11])); - XFontStruct *f = XLoadQueryFont (DISPLAY, name); + XFontStruct *f = XLoadQueryFont (disp, name); if (f) { @@ -592,7 +590,7 @@ // (e.g. if the user did xset fp rehash just when we were searching fonts). // in that case, just return garbage. bool ret = set_properties (p, f); - XFreeFont (DISPLAY, f); + XFreeFont (disp, f); return ret; } else @@ -640,7 +638,7 @@ bool rxvt_font_x11::load (const rxvt_fontprop &prop) { - Display *disp = DISPLAY; + dTermDisplay; clear (); @@ -725,7 +723,7 @@ 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 + diff += 300; // more heavily penalize what looks like scaled bitmap fonts if (!set_properties (p, fname)) continue; @@ -859,7 +857,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 - 1) / wcw; + int wcw = WCWIDTH (*t); if (wcw > 0) g.width = (g.width + wcw - 1) / wcw; if (width < g.width) width = g.width; } @@ -888,13 +886,13 @@ { if (f) { - XFreeFont (DISPLAY, f); + XFreeFont (term->display->display, f); f = 0; } } bool -rxvt_font_x11::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) +rxvt_font_x11::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) const { uint32_t ch = FROM_UNICODE (cs, unicode); @@ -942,12 +940,12 @@ return true; // check character against base font bounding box - int w = xcs->width; - int wcw = wcwidth (unicode); + int w = xcs->rbearing - xcs->lbearing; + int wcw = WCWIDTH (unicode); if (wcw > 0) w = (w + wcw - 1) / wcw; careful = w > prop->width; - if (careful && w > prop->width * MAX_OVERLAP >> 2) + if (careful && OVERLAP_OK (w, prop)) return false; return true; @@ -963,14 +961,17 @@ // yet we are trying to be perfect /. // but the result still isn't perfect /. + dTermDisplay; + dTermGC; + bool slow = this->slow - || width != r->fwidth - || height != r->fheight; + || width != term->fwidth + || height != term->fheight; - int base = ascent; // sorry, incorrect: r->fbase; + int base = ascent; // sorry, incorrect: term->fbase; XGCValues v; - v.foreground = r->pix_colors[fg]; + v.foreground = term->pix_colors[fg]; v.font = f->fid; if (enc2b) @@ -979,30 +980,30 @@ if (bg == Color_bg && !slow) { - v.background = r->pix_colors[bg]; - XChangeGC (d.display->display, TGC, GCForeground | GCBackground | GCFont, &v); - XDrawImageString16 (d.display->display, d, TGC, x, y + base, xc, len); + v.background = term->pix_colors[bg]; + XChangeGC (disp, gc, GCForeground | GCBackground | GCFont, &v); + XDrawImageString16 (disp, d, gc, x, y + base, xc, len); } else { - clear_rect (d, x, y, r->fwidth * len, r->fheight, bg); + clear_rect (d, x, y, term->fwidth * len, term->fheight, bg); - XChangeGC (d.display->display, TGC, GCForeground | GCFont, &v); + XChangeGC (disp, gc, GCForeground | GCFont, &v); if (slow) { do { if (xc->byte1 || xc->byte2) - XDrawString16 (d.display->display, d, TGC, x, y + base, xc, 1); + XDrawString16 (disp, d, gc, x, y + base, xc, 1); - x += r->fwidth; + x += term->fwidth; xc++; len--; } while (len); } else - XDrawString16 (d.display->display, d, TGC, x, y + base, xc, len); + XDrawString16 (disp, d, gc, x, y + base, xc, len); } } else @@ -1011,30 +1012,30 @@ if (bg == Color_bg && !slow) { - v.background = r->pix_colors[bg]; - XChangeGC (d.display->display, TGC, GCForeground | GCBackground | GCFont, &v); - XDrawImageString (d.display->display, d, TGC, x, y + base, xc, len); + v.background = term->pix_colors[bg]; + XChangeGC (disp, gc, GCForeground | GCBackground | GCFont, &v); + XDrawImageString (disp, d, gc, x, y + base, xc, len); } else { - clear_rect (d, x, y, r->fwidth * len, r->fheight, bg); + clear_rect (d, x, y, term->fwidth * len, term->fheight, bg); - XChangeGC (d.display->display, TGC, GCForeground | GCFont, &v); + XChangeGC (disp, gc, GCForeground | GCFont, &v); if (slow) { do { if (*xc) - XDrawString (d.display->display, d, TGC, x, y + base, xc, 1); + XDrawString (disp, d, gc, x, y + base, xc, 1); - x += r->fwidth; + x += term->fwidth; xc++; len--; } while (len); } else - XDrawString (d.display->display, d, TGC, x, y + base, xc, len); + XDrawString (disp, d, gc, x, y + base, xc, len); } } } @@ -1056,7 +1057,7 @@ const text_t *text, int len, int fg, int bg); - bool has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &carefull); + bool has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &carefull) const; protected: XftFont *f; @@ -1067,7 +1068,7 @@ { if (f) { - XftFontClose (DISPLAY, f); + XftFontClose (term->display->display, f); f = 0; } } @@ -1095,7 +1096,7 @@ bool rxvt_font_xft::load (const rxvt_fontprop &prop) { - Display *disp = DISPLAY; + dTermDisplay; clear (); @@ -1132,7 +1133,7 @@ set_name ((char *)FcNameUnparse (p)); XftResult result; - FcPattern *match = XftFontMatch (disp, r->display->screen, p, &result); + FcPattern *match = XftFontMatch (disp, term->display->screen, p, &result); FcPatternDestroy (p); @@ -1184,7 +1185,7 @@ g.width -= g.x; - int wcw = wcwidth (ch); + int wcw = WCWIDTH (ch); if (wcw > 0) g.width = (g.width + wcw - 1) / wcw; if (width < g.width ) width = g.width; @@ -1240,11 +1241,11 @@ } bool -rxvt_font_xft::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) +rxvt_font_xft::has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) const { careful = false; - if (!XftCharExists (DISPLAY, f, unicode)) + if (!XftCharExists (term->display->display, f, unicode)) return false; if (!prop || prop->width == rxvt_fontprop::unset) @@ -1253,14 +1254,14 @@ // check character against base font bounding box FcChar32 ch = unicode; XGlyphInfo g; - XftTextExtents32 (DISPLAY, f, &ch, 1, &g); + XftTextExtents32 (term->display->display, f, &ch, 1, &g); int w = g.width - g.x; - int wcw = wcwidth (unicode); + int wcw = WCWIDTH (unicode); if (wcw > 0) w = (w + wcw - 1) / wcw; careful = w > prop->width; - if (careful && w > prop->width * MAX_OVERLAP >> 2) + if (careful && OVERLAP_OK (w, prop)) return false; return true; @@ -1271,11 +1272,14 @@ const text_t *text, int len, int fg, int bg) { + clear_rect (d, x, y, term->fwidth * len, term->fheight, bg); + XGlyphInfo extents; - XftGlyphSpec *enc = (XftGlyphSpec *)get_enc_buf (len * sizeof (XftGlyphSpec)); + XftGlyphSpec *enc = (XftGlyphSpec *)rxvt_temp_buf (len * sizeof (XftGlyphSpec)); XftGlyphSpec *ep = enc; - clear_rect (d, x, y, r->fwidth * len, r->fheight, bg); + dTermDisplay; + dTermGC; // cut trailing spaces while (len && text [len - 1] == ' ') @@ -1283,16 +1287,16 @@ while (len) { - int cwidth = r->fwidth; + int cwidth = term->fwidth; FcChar32 fc = *text++; len--; while (len && *text == NOCHAR) - text++, len--, cwidth += r->fwidth; + text++, len--, cwidth += term->fwidth; if (fc != ' ') // skip spaces { - FT_UInt glyph = XftCharIndex (d.display->display, f, fc); - XftGlyphExtents (d.display->display, f, &glyph, 1, &extents); + FT_UInt glyph = XftCharIndex (disp, f, fc); + XftGlyphExtents (disp, f, &glyph, 1, &extents); ep->glyph = glyph; ep->x = x + (cwidth - extents.xOff >> 1); @@ -1304,14 +1308,14 @@ } if (ep != enc) - XftDrawGlyphSpec (d, &r->pix_colors[fg].c, f, enc, ep - enc); + XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, enc, ep - enc); } #endif ///////////////////////////////////////////////////////////////////////////// -rxvt_fontset::rxvt_fontset (rxvt_t r) -: fontdesc (0), r (r) +rxvt_fontset::rxvt_fontset (rxvt_term *term) +: fontdesc (0), term (term) { clear (); } @@ -1365,7 +1369,7 @@ else f = new rxvt_font_x11; - f->set_term (r); + f->set_term (term); f->set_name (strdup (name)); f->cs = cs; @@ -1558,7 +1562,7 @@ //FcPatternAddBool (p, FC_ANTIALIAS, 1); XftResult result; - FcPattern *match = XftFontMatch (DISPLAY, r->display->screen, p, &result); + FcPattern *match = XftFontMatch (term->display->display, term->display->screen, p, &result); FcPatternDestroy (p);