*** xftcore.c.orig	Mon Nov 24 16:18:10 2008
--- xftcore.c.new	Mon Nov 24 17:20:41 2008
***************
*** 392,398 ****
                         ((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000)))
  
  
! #define XftIntMult(a,b,t) ( (t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ) )
  #define XftIntDiv(a,b)   (((CARD16) (a) * 255) / (b))
  
  #define XftGet8(v,i)   ((CARD16) (CARD8) ((v) >> i))
--- 392,398 ----
                         ((((s) << 9) & 0xf80000) | (((s) << 4) & 0x70000)))
  
  
! #define XftIntMult(a,b,t) ( (b)==0xff?(a):(a)==0?0:((a)==0xff?(b):((t) = (a) * (b) + 0x80, ( ( ( (t)>>8 ) + (t) )>>8 ))) )
  #define XftIntDiv(a,b)   (((CARD16) (a) * 255) / (b))
  
  #define XftGet8(v,i)   ((CARD16) (CARD8) ((v) >> i))
***************
*** 488,498 ****
      x -= xftg->metrics.x;
      y -= xftg->metrics.y;
  
!     dstLine = (CARD32 *) (image->data + image->bytes_per_line * y + (x << 2));
      dstStride = image->bytes_per_line >> 2;
-     maskLine = (unsigned char *) xftg->bitmap;
      maskStride = (width + 3) & ~3;
!     
      while (height--)
      {
        dst = dstLine;
--- 488,506 ----
      x -= xftg->metrics.x;
      y -= xftg->metrics.y;
  
!     dstLine = (CARD32 *) (image->data +		
! 			  image->bytes_per_line * (y<0?0:y) + 
! 			  ((x<0?0:x) << 2));
      dstStride = image->bytes_per_line >> 2;
      maskStride = (width + 3) & ~3;
!     maskLine = (unsigned char *) xftg->bitmap + maskStride * (y<0?-y:0);
!     height = height<image->height-y ? height + (y<0?y:0)
!                                   : image->height - (y>0?y:0);
!     width = width<image->width-x ? width + (x<0?x:0)
!                                : image->width - (x>0?x:0);
!     if (width<=0 || height<=0)
!         goto bail1;
! 
      while (height--)
      {
        dst = dstLine;
***************
*** 519,524 ****
--- 527,534 ----
            dst++;
        }
      }
+ bail1:
+     return;
  }
  
  static void
***************
*** 949,955 ****
--- 959,984 ----
      int               nmissing;
      int               n;
      XErrorHandler   prev_error;
+     static Drawable last_drawable;
+     struct geometry {
+         Window  root;
+         int     x;
+         int     y;
+         int     width;
+         int     height;
+         int     border;
+         int     depth;
+     };
+     static struct geometry geom;
+     struct geometry inter;
  
+     if (draw->drawable != last_drawable) {
+         /* cache the geometry */
+         XGetGeometry(dpy, draw->drawable, &geom.root,
+ 		     &geom.x, &geom.y, &geom.width, &geom.height,
+ 		     &geom.border, &geom.depth);
+ 	last_drawable = draw->drawable;
+     }
      /*
       * Load missing glyphs
       */
***************
*** 973,985 ****
          unsigned int    depth;
        int         ox, oy;
        XftSmoothGlyph    smooth = _XftSmoothGlyphFind (draw, public);
!       
        XftGlyphExtents (dpy, public, glyphs, nglyphs, &gi);
-       if (!gi.width || !gi.height)
-           goto bail1;
        ox = x - gi.x;
        oy = y - gi.y;
        /*
         * Try to get bits directly from the drawable; if that fails,
         * use a temporary pixmap.  When it does fail, assume it
         * will probably fail for a while and keep using temporary
--- 1002,1021 ----
          unsigned int    depth;
        int         ox, oy;
        XftSmoothGlyph    smooth = _XftSmoothGlyphFind (draw, public);
! 
        XftGlyphExtents (dpy, public, glyphs, nglyphs, &gi);
        ox = x - gi.x;
        oy = y - gi.y;
        /*
+        * Now obtain the intersection between geom and the area to be covered by
+        * the glyphs
+        */
+        inter.x = max(ox,0); inter.y = max(oy,0);
+        inter.width = min(gi.width - (inter.x-ox), geom.width - inter.x);
+        inter.height = min(gi.height - (inter.y-oy), geom.height - inter.y);
+        if (inter.width<=0 || inter.height<=0)
+          goto  bail1;
+       /*
         * Try to get bits directly from the drawable; if that fails,
         * use a temporary pixmap.  When it does fail, assume it
         * will probably fail for a while and keep using temporary
***************
*** 989,996 ****
        {
            prev_error = XSetErrorHandler (XftGetImageErrorHandler);
            image = XGetImage (dpy, draw->drawable,
!                          ox, oy,
!                          gi.width, gi.height, AllPlanes,
                           ZPixmap);
            XSetErrorHandler (prev_error);
            if (!image)
--- 1025,1032 ----
        {
            prev_error = XSetErrorHandler (XftGetImageErrorHandler);
            image = XGetImage (dpy, draw->drawable,
!                          inter.x, inter.y,
!                          inter.width, inter.height, AllPlanes,
                           ZPixmap);
            XSetErrorHandler (prev_error);
            if (!image)
***************
*** 1008,1020 ****
            XGCValues     gcv;
  
            pix = XCreatePixmap (dpy, draw->drawable,
!                          gi.width, gi.height, depth);
            gcv.graphics_exposures = False;
            gc = XCreateGC (dpy, pix, GCGraphicsExposures, &gcv);
!           XCopyArea (dpy, draw->drawable, pix, gc, ox, oy,
!                    gi.width, gi.height, 0, 0);
            XFreeGC (dpy, gc);
!           image = XGetImage (dpy, pix, 0, 0, gi.width, gi.height, AllPlanes,
                           ZPixmap);
            XFreePixmap (dpy, pix);
        }
--- 1044,1056 ----
            XGCValues     gcv;
  
            pix = XCreatePixmap (dpy, draw->drawable,
!                          inter.width, inter.height, depth);
            gcv.graphics_exposures = False;
            gc = XCreateGC (dpy, pix, GCGraphicsExposures, &gcv);
!           XCopyArea (dpy, draw->drawable, pix, gc, inter.x, inter.y,
!                    inter.width, inter.height, 0, 0);
            XFreeGC (dpy, gc);
!           image = XGetImage (dpy, pix, 0, 0, inter.width, inter.height, AllPlanes,
                           ZPixmap);
            XFreePixmap (dpy, pix);
        }
***************
*** 1032,1038 ****
              xftg = _XftGlyphDefault (dpy, public);
            if (xftg)
            {
!             (*smooth) (image, xftg, x - ox, y - oy, color);
              x += xftg->metrics.xOff;
              y += xftg->metrics.yOff;
            }
--- 1068,1074 ----
              xftg = _XftGlyphDefault (dpy, public);
            if (xftg)
            {
!             (*smooth) (image, xftg, x - inter.x, y - inter.y, color);
              x += xftg->metrics.xOff;
              y += xftg->metrics.yOff;
            }
***************
*** 1039,1051 ****
        }
        if (image->byte_order != XftNativeByteOrder ())
            XftSwapImage (image);
!       XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, ox, oy,
!                gi.width, gi.height);
        XDestroyImage (image);
      }
      else
      {
        XftSharpGlyph     sharp = _XftSharpGlyphFind (draw, public);
        while (n--)
        {
            glyph = *g++;
--- 1075,1099 ----
        }
        if (image->byte_order != XftNativeByteOrder ())
            XftSwapImage (image);
!       XPutImage (dpy, draw->drawable, draw->core.gc, image, 0, 0, inter.x, inter.y,
!                inter.width, inter.height);
        XDestroyImage (image);
      }
      else
      {
        XftSharpGlyph     sharp = _XftSharpGlyphFind (draw, public);
+       XGlyphInfo  gi;
+       XftGlyphExtents (dpy, public, glyphs, nglyphs, &gi);
+       /*
+        * Now obtain the intersection between geom and the area to be covered by
+        * the glyphs
+        */
+        inter.x = max(x,0); inter.y = max(y,0);
+        inter.x = max(x,0); inter.y = max(y,0);
+        inter.width = min(gi.width - (inter.x-x), geom.width - inter.x);
+        inter.height = min(gi.height - (inter.y-y), geom.height - inter.y);
+        if (inter.width<=0 || inter.height<=0)
+          goto  bail1;
        while (n--)
        {
            glyph = *g++;
