/////////////////////////////////////////////////////////////////////////////
-#if XFT
-rxvt_drawable::~rxvt_drawable ()
-{
- if (xftdrawable)
- XftDrawDestroy (xftdrawable);
-}
-
-rxvt_drawable::operator XftDraw *()
-{
- if (!xftdrawable)
- xftdrawable = XftDrawCreate (screen->dpy, drawable, screen->visual, screen->cmap);
-
- return xftdrawable;
-}
-#endif
-
-/////////////////////////////////////////////////////////////////////////////
-
static const char *
enc_char (const text_t *text, uint32_t len, codeset cs, bool &zero)
{
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 *)rxvt_temp_buf (len * sizeof (XftGlyphSpec));
XftGlyphSpec *ep = enc;
dTermDisplay;
dTermGC;
+ int w = term->fwidth * len;
+ int h = term->fheight;
+
+ bool buffered = false;
+
// cut trailing spaces
while (len && text [len - 1] == ' ')
len--;
+ int x_ = buffered ? 0 : x;
+ int y_ = buffered ? 0 : y;
+
while (len)
{
int cwidth = term->fwidth;
XftGlyphExtents (disp, f, &glyph, 1, &extents);
ep->glyph = glyph;
- ep->x = x + (cwidth - extents.xOff >> 1);
- ep->y = y + ascent;
+ ep->x = x_ + (cwidth - extents.xOff >> 1);
+ ep->y = y_ + ascent;
if (extents.xOff == 0)
- ep->x = x + cwidth;
+ ep->x = x_ + cwidth;
ep++;
}
- x += cwidth;
+ x_ += cwidth;
}
- if (ep != enc)
- XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, enc, ep - enc);
+ if (buffered)
+ {
+ if (ep != enc)
+ {
+ rxvt_drawable &d2 = d.screen->scratch_drawable (w, h);
+
+ XftDrawRect (d2, &term->pix_colors[bg].c, 0, 0, w, h);
+
+ XftDrawGlyphSpec (d2, &term->pix_colors[fg].c, f, enc, ep - enc);
+ XCopyArea (disp, d2, d, gc, 0, 0, w, h, x, y);
+ }
+ else
+ clear_rect (d, x, y, w, h, bg);
+ }
+ else
+ {
+ clear_rect (d, x, y, w, h, bg);
+ XftDrawGlyphSpec (d, &term->pix_colors[fg].c, f, enc, ep - enc);
+ }
}
+
#endif
/////////////////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
+#if XFT
+rxvt_drawable::~rxvt_drawable ()
+{
+ if (xftdrawable)
+ XftDrawDestroy (xftdrawable);
+}
+
+rxvt_drawable::operator XftDraw *()
+{
+ if (!xftdrawable)
+ xftdrawable = XftDrawCreate (screen->dpy, drawable, screen->visual, screen->cmap);
+
+ return xftdrawable;
+}
+#endif
+
+/////////////////////////////////////////////////////////////////////////////
+
+#if XFT
+
+// not strictly necessary as it is only used with superclass of zero_initialised
+rxvt_screen::rxvt_screen ()
+: scratch_area (0)
+{
+}
+
+rxvt_drawable &rxvt_screen::scratch_drawable (int w, int h)
+{
+ // it's actually faster to re-allocate every time. don't ask me
+ // why, but its likely no big deal there are no roundtrips
+ // (I think/hope).
+ if (!scratch_area || w > scratch_w || h > scratch_h || 1/*D*/)
+ {
+ if (scratch_area)
+ {
+ XFreePixmap (dpy, scratch_area->drawable);
+ delete scratch_area;
+ }
+
+ Pixmap pm = XCreatePixmap (dpy, RootWindowOfScreen (ScreenOfDisplay (dpy, display->screen)),
+ scratch_w = w, scratch_h = h, depth);
+
+ scratch_area = new rxvt_drawable (this, pm);
+ }
+
+ return *scratch_area;
+}
+
+#endif
+
void
rxvt_screen::set (rxvt_display *disp)
{
void
rxvt_screen::clear ()
{
+#if XFT
+ if (scratch_area)
+ {
+ XFreePixmap (dpy, scratch_area->drawable);
+ delete scratch_area;
+ }
+#endif
+
if (cmap != DefaultColormapOfScreen (ScreenOfDisplay (dpy, display->screen)))
XFreeColormap (dpy, cmap);
}
/////////////////////////////////////////////////////////////////////////////
+struct rxvt_screen;
+
+struct rxvt_drawable {
+ rxvt_screen *screen;
+ Drawable drawable;
+ operator Drawable() { return drawable; }
+
+#if XFT
+ XftDraw *xftdrawable;
+ operator XftDraw *();
+#endif
+
+ rxvt_drawable (rxvt_screen *screen, Drawable drawable)
+ : screen(screen),
+#if XFT
+ xftdrawable(0),
+#endif
+ drawable(drawable)
+ { }
+
+#if XFT
+ ~rxvt_drawable ();
+#endif
+};
+
+/////////////////////////////////////////////////////////////////////////////
+
#ifdef USE_XIM
struct rxvt_xim : refcounted {
void destroy ();
Visual *visual;
Colormap cmap;
+#if XFT
+ // scratch pixmap
+ rxvt_drawable *scratch_area;
+ int scratch_w, scratch_h;
+
+ rxvt_drawable &scratch_drawable (int w, int h);
+
+ rxvt_screen ();
+#endif
+
void set (rxvt_display *disp);
void set (rxvt_display *disp, int bitdepth);
void clear ();