--- rxvt-unicode/src/rxvtfont.C 2006/11/02 17:23:50 1.106 +++ rxvt-unicode/src/rxvtfont.C 2007/11/25 11:23:18 1.125 @@ -45,12 +45,12 @@ { CS_ISO8859_1, "-*-*-*-r-*--*-*-*-*-c-*-iso8859-1" }, { CS_ISO8859_15, "-*-*-*-r-*--*-*-*-*-c-*-iso8859-15" }, { CS_ISO8859_15, "-*-*-*-r-*--*-*-*-*-c-*-fcd8859-15" }, - -#if ENCODING_EU - // cyrillic + +#if ENCODING_EU + // cyrillic { CS_KOI8_R, "-*-*-*-r-*--*-*-*-*-c-*-koi8-r" }, { CS_KOI8_U, "-*-*-*-r-*--*-*-*-*-c-*-koi8-u" }, - + { CS_ISO8859_2, "-*-*-*-r-*--*-*-*-*-c-*-iso8859-2" }, { CS_ISO8859_3, "-*-*-*-r-*--*-*-*-*-c-*-iso8859-3" }, { CS_ISO8859_4, "-*-*-*-r-*--*-*-*-*-c-*-iso8859-4" }, @@ -67,7 +67,7 @@ # if XFT { CS_KOI8_U, "xft::lang=ru" }, - + { CS_ISO8859_5, "xft::lang=ru" }, { CS_ISO8859_6, "xft::lang=ar" }, { CS_ISO8859_7, "xft::lang=el" }, @@ -233,13 +233,28 @@ { dTermDisplay; dTermGC; - + if (color == Color_bg || color == Color_transparent) XClearArea (disp, d, x, y, w, h, false); else if (color >= 0) { #if XFT - XftDrawRect (d, &term->pix_colors[color].c, x, y, w, h); + bool done = false; +#ifdef HAVE_BG_PIXMAP + if (term->bgPixmap.pixmap && color >= 0 && term->pix_colors[color].c.color.alpha < 0x0ff00) + { + Picture dst = XftDrawPicture (d); + if (dst != 0) + { + XClearArea (disp, d, x, y, w, h, false); + Picture solid_color_pict = XftDrawSrcPicture (d, &term->pix_colors[color].c); + XRenderComposite (disp, PictOpOver, solid_color_pict, None, dst, 0, 0, 0, 0, x, y, w, h); + done = true; + } + } +#endif + if (!done) + XftDrawRect (d, &term->pix_colors[color].c, x, y, w, h); #else XSetForeground (disp, gc, term->pix_colors[color]); XFillRectangle (disp, d, gc, x, y, w, h); @@ -249,8 +264,6 @@ ///////////////////////////////////////////////////////////////////////////// -#include "table/linedraw.h" - struct rxvt_font_default : rxvt_font { struct rxvt_fontset *fs; @@ -295,9 +308,11 @@ if (unicode <= 0x009f) return true; +#ifdef BUILTIN_GLYPHS if (unicode >= 0x2500 && unicode <= 0x259f && !term->option (Opt_skipBuiltinGlyphs)) return true; +#endif if (IS_COMPOSE (unicode)) return true; @@ -343,8 +358,10 @@ int width = text - tp; int fwidth = term->fwidth * width; +#ifdef BUILTIN_GLYPHS if (0x2500 <= t && t <= 0x259f) { +# include "table/linedraw.h" uint16_t offs = linedraw_offs[t - 0x2500]; uint32_t *a = linedraw_command + (offs >> 4); uint32_t *b = a + (offs & 15); @@ -392,7 +409,7 @@ if (a) { static char bm[] = { 0,0 , 3,1 , 1,2 , 1,0 }; - + gcv.fill_style = FillStippled; gcv.stipple = XCreateBitmapFromData (disp, d, bm + a * 2, 2, 2); gcv.ts_x_origin = x; @@ -421,6 +438,10 @@ } } } +#else + if (0) + ; +#endif #if ENABLE_COMBINING else if (IS_COMPOSE (t) && (cc = rxvt_composite[t])) { @@ -499,7 +520,7 @@ if (XGetFontProperty (f, property, &value)) return XGetAtomName (term->dpy, value); else - return rxvt_strdup (repl); + return repl ? strdup (repl) : 0; } rxvt_fontprop @@ -591,7 +612,7 @@ // fix the size of scalable fonts static bool -replace_field (char *buf, const char *name, int index, const char old, const char *replace) +replace_field (char **ptr, const char *name, int index, const char old, const char *replace) { int slashes = 0; const char *field, *end; @@ -611,17 +632,17 @@ if (slashes >= 13 && (!old || *field == old)) { - // TODO: check for overflow in font-name - strncpy (buf, name, field - name); - buf += field - name; - strcpy (buf, replace); - strcat (buf, end); + size_t len = field - name; + *ptr = (char *)malloc (len + strlen (replace) + strlen (end) + 1); + strncpy (*ptr, name, len); + strcpy (*ptr + len, replace); + strcat (*ptr, end); return true; } else { - strcpy (buf, name); + *ptr = strdup (name); return false; } @@ -639,7 +660,7 @@ // first morph the font if required if (force_prop) { - char fname[1024]; + char *fname; if (name[0] != '-') { @@ -661,18 +682,18 @@ if (prop.weight != rxvt_fontprop::unset) { - replace_field (fname, name, 2, 0, + replace_field (&fname, name, 2, 0, prop.weight < rxvt_fontprop::bold ? "medium" : "bold"); - set_name (strdup (fname)); + set_name (fname); } if (prop.slant != rxvt_fontprop::unset) { - replace_field (fname, name, 3, 0, + replace_field (&fname, name, 3, 0, prop.slant < rxvt_fontprop::italic ? "r" : "i"); // TODO: handle "o"blique, too - set_name (strdup (fname)); + set_name (fname); } } @@ -707,14 +728,18 @@ for (int i = 0; i < count; i++) { rxvt_fontprop p; - char fname[1024]; + char *fname; int diff = 0; - if (replace_field (fname, list[i], 6, '0', field_str)) + 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 fonts + else + { + free (fname); + if (replace_field (&fname, list[i], 11, '0', "0")) + diff += 300; // more heavily penalize what looks like scaled bitmap fonts + } if (!set_properties (p, fname)) continue; @@ -728,7 +753,7 @@ if (prop.slant != rxvt_fontprop::unset) diff += abs (prop.slant - p.slant); //if (prop.width != rxvt_fontprop::unset) diff += abs (prop.width - p.width); - fonts[i].name = strdup (fname); + fonts[i].name = fname; fonts[i].diff = diff; } @@ -815,7 +840,7 @@ if (encm) N += (f->max_byte1 - f->min_byte1) * (f->max_char_or_byte2 - f->min_char_or_byte2 + 1); - + while (N) { if (f->per_char[N].width > width) @@ -977,7 +1002,7 @@ clear_rect (d, x, y, term->fwidth * len, term->fheight, bg); XChangeGC (disp, gc, GCForeground | GCFont, &v); - + if (slow) { do @@ -1009,7 +1034,7 @@ clear_rect (d, x, y, term->fwidth * len, term->fheight, bg); XChangeGC (disp, gc, GCForeground | GCFont, &v); - + if (slow) { do @@ -1045,7 +1070,7 @@ const text_t *text, int len, int fg, int bg); - bool has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &carefull) const; + bool has_char (unicode_t unicode, const rxvt_fontprop *prop, bool &careful) const; protected: XftFont *f; @@ -1274,15 +1299,15 @@ int w = term->fwidth * len; int h = term->fheight; - bool buffered = bg >= 0 // we don't use a transparent bg -#ifndef FORCE_UNBUFFERED_XFT -# if defined(XPM_BACKGROUND) || defined(TRANSPARENT) - || !term->am_transparent // we aren't transparent - || term->am_pixmap_trans // we have a pixmap -# endif + /* TODO: this logic needs some more thinking, since we no longer do pseudo-transparency. + * Maybe make buffering into a resource flag? Compile time option doesn't seems like a + * good idea from the perspective of packaging for wide variety of user configs. + */ + bool buffered = true +#ifdef FORCE_UNBUFFERED_XFT + && bg >= 0 #endif ; - // cut trailing spaces while (len && text [len - 1] == ' ') len--; @@ -1297,7 +1322,7 @@ while (len && *text == NOCHAR) text++, len--, cwidth += term->fwidth; - + if (fc != ' ') // skip spaces { FT_UInt glyph = XftCharIndex (disp, f, fc); @@ -1318,38 +1343,66 @@ if (buffered) { + bool back_rendered = false; if (ep != enc) { rxvt_drawable &d2 = d.screen->scratch_drawable (w, h); - if (0) - ; -#ifdef TRANSPARENT - else if (bg < 0 && term->am_pixmap_trans) - XCopyArea (disp, term->pixmap, d2, gc, - x + term->window_vt_x, y + term->window_vt_y, - w, h, 0, 0); -#endif -#ifdef XPM_BACKGROUND - else if (bg < 0 && term->bgPixmap.pixmap) +#ifdef HAVE_BG_PIXMAP + if (term->bgPixmap.pixmap) { - XGCValues gcv; + Picture dst = 0; + + if (bg >= 0 && term->pix_colors[bg].c.color.alpha < 0x0ff00) + dst = XftDrawPicture (d2); + + if (bg < 0 || dst != 0) + { + int src_x = x, src_y = y ; + + if (term->bgPixmap.is_parentOrigin ()) + { + src_x += term->window_vt_x; + src_y += term->window_vt_y; + } + + if (term->bgPixmap.pmap_width >= src_x+w + && term->bgPixmap.pmap_height >= src_y+h) + { + XCopyArea (disp, term->bgPixmap.pixmap, d2, gc, + src_x, src_y, w, h, 0, 0); + } + else + { + XGCValues gcv; + + gcv.fill_style = FillTiled; + gcv.tile = term->bgPixmap.pixmap; + gcv.ts_x_origin = -src_x; + gcv.ts_y_origin = -src_y; - gcv.fill_style = FillTiled; - gcv.tile = term->pixmap; - gcv.ts_x_origin = -x; - gcv.ts_y_origin = -y; + XChangeGC (disp, gc, + GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle, + &gcv); - GC gc2 = XCreateGC (disp, d2, - GCTile | GCTileStipXOrigin | GCTileStipYOrigin | GCFillStyle, - &gcv); + XFillRectangle (disp, d2, gc, 0, 0, w, h); - XFillRectangle (disp, d2, gc2, 0, 0, w, h); + gcv.fill_style = FillSolid; + XChangeGC (disp, gc, GCFillStyle, &gcv); + } - XFreeGC (disp, gc2); + if (bg >= 0) + { + Picture solid_color_pict = XftDrawSrcPicture (d2, &term->pix_colors[bg].c); + XRenderComposite (disp, PictOpOver, solid_color_pict, None, dst, 0, 0, 0, 0, 0, 0, w, h); + } + + back_rendered = true; + } } #endif - else + + if (bg >= 0 && !back_rendered) XftDrawRect (d2, &term->pix_colors[bg].c, 0, 0, w, h); XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, enc, ep - enc); @@ -1404,7 +1457,7 @@ rxvt_fontset::new_font (const char *name, codeset cs) { rxvt_font *f; - + if (!name || !*name) { name = ""; @@ -1633,7 +1686,7 @@ char fontname[4096]; sprintf (fontname, "xft:%-.4090s", font); - fonts.push_back (new_font (fontname, CS_UNICODE)); + fonts.push_back (new_font (fontname, CS_UNICODE)); } free (font);