Bug 449959: gfxGdkNativeRenderer: look for GdkDrawable on group target,
authorVladimir Vukicevic <vladimir@pobox.com>, Karl Tomlinson <karlt+@karlt.net>
Tue, 19 Aug 2008 15:22:42 +1200
changeset 17025 d09ac8396f720afb6021a94d0c27fe1f26929938
parent 17024 ab84d935f37eaa0e3f7a35ef41270f6841b07dff
child 17026 85c82edb887a09ec61b36ba3945cb34dcba35e42
push idunknown
push userunknown
push dateunknown
bugs449959
milestone1.9.1a2pre
Bug 449959: gfxGdkNativeRenderer: look for GdkDrawable on group target, use default display for fallback. r=vlad/karlt
gfx/thebes/public/gfxGdkNativeRenderer.h
gfx/thebes/src/cairo-gdk-utils.c
gfx/thebes/src/cairo-gdk-utils.h
gfx/thebes/src/cairo-xlib-utils.c
gfx/thebes/src/gfxGdkNativeRenderer.cpp
gfx/thebes/src/gfxPlatformGtk.cpp
widget/src/gtk2/nsWindow.cpp
--- a/gfx/thebes/public/gfxGdkNativeRenderer.h
+++ b/gfx/thebes/public/gfxGdkNativeRenderer.h
@@ -76,17 +76,17 @@ public:
         DRAW_SUPPORTS_CLIP_RECT = 0x04,
         // If set, then numClipRects can be any value. If neither this
         // nor CLIP_RECT are set, then numClipRects will be zero
         DRAW_SUPPORTS_CLIP_LIST = 0x08,
         // If set, then the visual passed in can be any visual, otherwise the
         // visual passed in must be the default visual for dpy's default screen
         DRAW_SUPPORTS_NONDEFAULT_VISUAL = 0x10,
         // If set, then the Screen 'screen' in the callback can be different
-        // from the default Screen of the display passed to 'Draw' and can be
+        // from the default Screen of the default display and can be
         // on a different display.
         DRAW_SUPPORTS_ALTERNATE_SCREEN = 0x20
     };
 
     struct DrawOutput {
         nsRefPtr<gfxASurface> mSurface;
         PRPackedBool mUniformAlpha;
         PRPackedBool mUniformColor;
--- a/gfx/thebes/src/cairo-gdk-utils.c
+++ b/gfx/thebes/src/cairo-gdk-utils.c
@@ -75,17 +75,16 @@ static cairo_bool_t
 {
     *v = (unsigned short)coord;
     /* XXX allow some tolerance here? */
     return *v == coord;
 }
 
 
 void cairo_draw_with_gdk (cairo_t *cr,
-                           GdkDrawable * drawable,
                            cairo_gdk_drawing_callback callback,
                            void * closure,
                            unsigned int width, unsigned int height,
                            cairo_gdk_drawing_opacity_t is_opaque,
                            cairo_gdk_drawing_support_t capabilities,
                            cairo_gdk_drawing_result_t *result)
 {
     double device_offset_x, device_offset_y;
@@ -96,13 +95,13 @@ void cairo_draw_with_gdk (cairo_t *cr,
 
     cairo_surface_get_device_offset (target, &device_offset_x, &device_offset_y);
     cairo_get_matrix (cr, &matrix);
 
     _convert_coord_to_short (matrix.x0 + device_offset_x, &offset_x);
     _convert_coord_to_short (matrix.y0 + device_offset_y, &offset_y);
 
     cairo_surface_flush (target);
-    callback (closure, drawable, offset_x, offset_y, NULL, 0);
+    callback (closure, target, offset_x, offset_y, NULL, 0);
     cairo_surface_mark_dirty (target);
 }
 
 
--- a/gfx/thebes/src/cairo-gdk-utils.h
+++ b/gfx/thebes/src/cairo-gdk-utils.h
@@ -47,21 +47,21 @@ CAIRO_BEGIN_DECLS
  * This callback encapsulates GDK-based rendering. We assume that the
  * execution of the callback is equivalent to compositing some RGBA image of
  * size (bounds_width, bounds_height) onto the drawable at offset (offset_x,
  * offset_y), clipped to the union of the clip_rects if num_rects is greater
  * than zero. This includes the assumption that the same RGBA image
  * is composited if you call the callback multiple times with the same closure,
  * display and visual during a single cairo_draw_with_gdk call.
  * 
- * @return True on success, False on non-recoverable error
+ * @return True when able to draw, False otherwise
  */
 typedef cairo_bool_t (* cairo_gdk_drawing_callback)
     (void *closure,
-     GdkDrawable * drawable,
+     cairo_surface_t *surface,
      short offset_x, short offset_y,
      GdkRectangle * clip_rects, unsigned int num_rects);
 
 /**
  * This structure captures the result of the native drawing, in case the
  * caller may wish to reapply the drawing efficiently later.
  */
 typedef struct {
@@ -131,17 +131,16 @@ typedef enum {
  * the image, similar to the target of 'cr'. If 'uniform_alpha' is True then
  * every pixel of the image has the same alpha value 'alpha'. If
  * 'uniform_color' is True then every pixel of the image has the same RGB
  * color (r, g, b). If the image has uniform color and alpha (or alpha is zero,
  * in which case the color is always uniform) then we won't bother returning
  * a surface for it.
  */
 void cairo_draw_with_gdk (cairo_t *cr,
-                          GdkDrawable * drawable,
                           cairo_gdk_drawing_callback callback,
                           void * closure,
                           unsigned int width, unsigned int height,
                           cairo_gdk_drawing_opacity_t is_opaque,
                           cairo_gdk_drawing_support_t capabilities,
                           cairo_gdk_drawing_result_t *result);
 
 CAIRO_END_DECLS
--- a/gfx/thebes/src/cairo-xlib-utils.c
+++ b/gfx/thebes/src/cairo-xlib-utils.c
@@ -15,16 +15,18 @@
  * The Original Code is Novell code.
  *
  * The Initial Developer of the Original Code is Novell.
  * Portions created by the Initial Developer are Copyright (C) 2006
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   rocallahan@novell.com
+ *   Vladimir Vukicevic <vladimir@pobox.com>
+ *   Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -199,16 +201,17 @@ static cairo_bool_t
     cairo_bool_t needs_clip;
     GdkRectangle rectangles[MAX_STATIC_CLIP_RECTANGLES];
     int rect_count;
     double device_offset_x, device_offset_y;
     int max_rectangles;
     Screen *screen;
     Visual *visual;
     cairo_bool_t have_rectangular_clip;
+    cairo_bool_t ret;
 
     target = cairo_get_group_target (cr);
     cairo_surface_get_device_offset (target, &device_offset_x, &device_offset_y);
     d = cairo_xlib_surface_get_drawable (target);
 
     cairo_get_matrix (cr, &matrix);
     
     /* Check that the matrix is a pure translation */
@@ -296,21 +299,22 @@ static cairo_bool_t
         DefaultVisualOfScreen (screen) != visual) {
         CAIRO_GDK_DRAWING_NOTE("TAKING SLOW PATH: non-default visual\n");
         return False;
     }
   
     /* we're good to go! */
     CAIRO_GDK_DRAWING_NOTE("TAKING FAST PATH\n");
     cairo_surface_flush (target);
-    callback (closure, GDK_DRAWABLE(gdk_xid_table_lookup(d)), 
-              offset_x, offset_y, rectangles,
-              needs_clip ? rect_count : 0);
-    cairo_surface_mark_dirty (target);
-    return True;
+    ret = callback (closure, target, offset_x, offset_y, rectangles,
+                    needs_clip ? rect_count : 0);
+    if (ret) {
+        cairo_surface_mark_dirty (target);
+    }
+    return ret;
 }
 
 static cairo_surface_t *
 _create_temp_xlib_surface (cairo_t *cr, Display *dpy, int width, int height,
                            cairo_gdk_drawing_support_t capabilities)
 {
     cairo_surface_t *result = NULL;
 
@@ -359,31 +363,29 @@ static cairo_surface_t *
 }
 
 static cairo_bool_t
 _draw_onto_temp_xlib_surface (cairo_surface_t *temp_xlib_surface,
                               cairo_gdk_drawing_callback callback,
                               void *closure,
                               double background_gray_value)
 {
-    Drawable d = cairo_xlib_surface_get_drawable (temp_xlib_surface);
     cairo_bool_t result;
 
     cairo_t *cr = cairo_create (temp_xlib_surface);
     cairo_set_source_rgb (cr, background_gray_value, background_gray_value,
                           background_gray_value);
     cairo_set_operator (cr, CAIRO_OPERATOR_SOURCE);
     cairo_paint (cr);
     cairo_destroy (cr);
     
     cairo_surface_flush (temp_xlib_surface);
     /* no clipping is needed because the callback can't draw outside the native
        surface anyway */
-    result = callback (closure, GDK_DRAWABLE(gdk_xid_table_lookup(d)),
-            0, 0, NULL, 0);
+    result = callback (closure, temp_xlib_surface, 0, 0, NULL, 0);
     cairo_surface_mark_dirty (temp_xlib_surface);
     return result;
 }
 
 static cairo_surface_t *
 _copy_xlib_surface_to_image (cairo_surface_t *temp_xlib_surface,
                              cairo_format_t format,
                              int width, int height,
@@ -487,47 +489,46 @@ static void
                 }
             }
         }
     }
 }
 
 void 
 cairo_draw_with_gdk (cairo_t *cr,
-                     GdkDrawable * drawable,
                      cairo_gdk_drawing_callback callback,
                      void * closure,
                      unsigned int width, unsigned int height,
                      cairo_gdk_drawing_opacity_t is_opaque,
                      cairo_gdk_drawing_support_t capabilities,
                      cairo_gdk_drawing_result_t *result)
 {
     cairo_surface_t *temp_xlib_surface;
     cairo_surface_t *black_image_surface;
     cairo_surface_t *white_image_surface;
     unsigned char *black_data;
     unsigned char *white_data;
-    Display *dpy = gdk_x11_drawable_get_xdisplay(drawable);
+    Display *dpy = gdk_x11_get_default_xdisplay();
   
     if (result) {
         result->surface = NULL;
         result->uniform_alpha = False;
         result->uniform_color = False;
     }
     
     /* exit early if there's no work to do. This is actually important
        because we'll die with an X error if we try to create an empty temporary
        pixmap */
     if (width == 0 || height == 0)
         return;
 
     if (_draw_with_xlib_direct (cr, dpy, callback, closure, width, height,
                                 capabilities))
         return;
-  
+
     temp_xlib_surface = _create_temp_xlib_surface (cr, dpy, width, height,
                                                    capabilities);
     if (temp_xlib_surface == NULL)
         return;
     /* update 'dpy' to refer to the display that actually got used. Might
        be different now, if cr was referring to an xlib surface on a different display */
     dpy = cairo_xlib_surface_get_display (temp_xlib_surface);
   
--- a/gfx/thebes/src/gfxGdkNativeRenderer.cpp
+++ b/gfx/thebes/src/gfxGdkNativeRenderer.cpp
@@ -15,16 +15,17 @@
  * The Original Code is Novell code.
  *
  * The Initial Developer of the Original Code is Novell.
  * Portions created by the Initial Developer are Copyright (C) 2006
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   rocallahan@novell.com
+ *   Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -45,21 +46,27 @@
 typedef struct {
     gfxGdkNativeRenderer* mRenderer;
     nsresult               mRV;
 } NativeRenderingClosure;
 
 
 static cairo_bool_t
 NativeRendering(void *closure,
-                GdkDrawable * drawable,
+                cairo_surface_t *surface,
                 short offset_x, short offset_y,
                 GdkRectangle * rectangles, unsigned int num_rects)
 {
     NativeRenderingClosure* cl = (NativeRenderingClosure*)closure;
+    nsRefPtr<gfxASurface> gfxSurface = gfxASurface::Wrap(surface);
+    GdkDrawable *drawable =
+        gfxPlatformGtk::GetPlatform()->GetGdkDrawable(gfxSurface);
+    if (!drawable)
+        return 0;
+
     nsresult rv = cl->mRenderer->
         NativeDraw(drawable, offset_x, offset_y,
                    rectangles, num_rects);
     cl->mRV = rv;
     return NS_SUCCEEDED(rv);
 }
 
 
@@ -91,17 +98,16 @@ gfxGdkNativeRenderer::Draw(gfxContext* c
     }
     if (flags & DRAW_SUPPORTS_ALTERNATE_SCREEN) {
         cairoFlags |= CAIRO_GDK_DRAWING_SUPPORTS_ALTERNATE_SCREEN;
     }
     if (flags & DRAW_SUPPORTS_NONDEFAULT_VISUAL) {
         cairoFlags |= CAIRO_GDK_DRAWING_SUPPORTS_NONDEFAULT_VISUAL;
     }
     cairo_draw_with_gdk(ctx->GetCairo(),
-                        gfxPlatformGtk::GetPlatform()->GetGdkDrawable(ctx->OriginalSurface()),
                         NativeRendering, 
                         &closure, width, height,
                         (flags & DRAW_IS_OPAQUE) ? CAIRO_GDK_DRAWING_OPAQUE : CAIRO_GDK_DRAWING_TRANSPARENT,
                         (cairo_gdk_drawing_support_t)cairoFlags,
                         output ? &result : NULL);
     if (NS_FAILED(closure.mRV)) {
         if (result.surface) {
             NS_ASSERTION(output, "How did that happen?");
--- a/gfx/thebes/src/gfxPlatformGtk.cpp
+++ b/gfx/thebes/src/gfxPlatformGtk.cpp
@@ -16,16 +16,17 @@
  *
  * The Initial Developer of the Original Code is Mozilla Foundation.
  * Portions created by the Initial Developer are Copyright (C) 2005
  * the Initial Developer. All Rights Reserved.
  *
  * Contributor(s):
  *   Vladimir Vukicevic <vladimir@pobox.com>
  *   Masayuki Nakano <masayuki@d-toybox.com>
+ *   Karl Tomlinson <karlt+@karlt.net>, Mozilla Corporation
  *
  * Alternatively, the contents of this file may be used under the terms of
  * either the GNU General Public License Version 2 or later (the "GPL"), or
  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  * in which case the provisions of the GPL or the LGPL are applicable instead
  * of those above. If you wish to allow use of your version of this file only
  * under the terms of either the GPL or the LGPL, and not to allow others to
  * use your version of this file under the terms of the MPL, indicate your
@@ -56,16 +57,17 @@
 
 #include "cairo.h"
 #include <gtk/gtk.h>
 
 #include "gfxImageSurface.h"
 #ifdef MOZ_X11
 #include <gdk/gdkx.h>
 #include "gfxXlibSurface.h"
+#include "cairo-xlib.h"
 #endif /* MOZ_X11 */
 
 #ifdef MOZ_DFB
 #include "gfxDirectFBSurface.h"
 #endif
 
 #ifdef MOZ_ENABLE_GLITZ
 #include "gfxGlitzSurface.h"
@@ -85,31 +87,28 @@
 #ifndef MOZ_PANGO
 #include <ft2build.h>
 #include FT_FREETYPE_H
 #endif
 
 PRInt32 gfxPlatformGtk::sDPI = -1;
 gfxFontconfigUtils *gfxPlatformGtk::sFontconfigUtils = nsnull;
 
-static cairo_user_data_key_t cairo_gdk_drawable_key;
-
 #ifndef MOZ_PANGO
 typedef nsDataHashtable<nsStringHashKey, nsRefPtr<FontFamily> > FontTable;
 static FontTable *gPlatformFonts = NULL;
 static FontTable *gPlatformFontAliases = NULL;
 static FT_Library gPlatformFTLibrary = NULL;
 #endif
 
-
-static cairo_user_data_key_t cairo_gdk_pixmap_key;
-static void do_gdk_pixmap_unref (void *data)
+static cairo_user_data_key_t cairo_gdk_drawable_key;
+static void do_gdk_drawable_unref (void *data)
 {
-    GdkPixmap *pmap = (GdkPixmap*)data;
-    gdk_pixmap_unref (pmap);
+    GdkDrawable *d = (GdkDrawable*) data;
+    g_object_unref (d);
 }
 
 gfxPlatformGtk::gfxPlatformGtk()
 {
 #ifdef MOZ_ENABLE_GLITZ
     if (UseGlitz())
         glitz_glx_init(NULL);
 #endif
@@ -207,27 +206,26 @@ gfxPlatformGtk::CreateOffscreenSurface(c
                                                 GDK_PIXMAP_XID(GDK_DRAWABLE(pixmap)),
                                                 xrenderFormat,
                                                 size);
             }
 
             if (newSurface && newSurface->CairoStatus() == 0) {
                 // set up the surface to auto-unref the gdk pixmap when
                 // the surface is released
-                newSurface->SetData(&cairo_gdk_pixmap_key,
-                                    pixmap,
-                                    do_gdk_pixmap_unref);
-            SetGdkDrawable(newSurface, GDK_DRAWABLE(pixmap));
+                SetGdkDrawable(newSurface, GDK_DRAWABLE(pixmap));
             } else {
                 // something went wrong with the surface creation.
                 // Ignore and let's fall back to image surfaces.
-                if (pixmap)
-                    gdk_pixmap_unref(pixmap);
                 newSurface = nsnull;
             }
+
+            // always unref; SetGdkDrawable takes its own ref
+            if (pixmap)
+                g_object_unref(pixmap);
         }
 
         if (!newSurface) {
             // We don't have Render or we couldn't create an xlib surface for
             // whatever reason; fall back to image surface for the data.
             newSurface = new gfxImageSurface(gfxIntSize(size.width, size.height), imageFormat);
         }
 
@@ -717,23 +715,114 @@ gfxPlatformGtk::FindFontEntry(const nsAS
 
 void
 gfxPlatformGtk::SetGdkDrawable(gfxASurface *target,
                                GdkDrawable *drawable)
 {
     if (target->CairoStatus())
         return;
 
+    gdk_drawable_ref(drawable);
+
     cairo_surface_set_user_data (target->CairoSurface(),
                                  &cairo_gdk_drawable_key,
                                  drawable,
-                                 NULL);
+                                 do_gdk_drawable_unref);
 }
 
+#ifdef MOZ_X11
+// Look for an existing Colormap that is known to be associated with visual.
+static GdkColormap *
+LookupGdkColormapForVisual(const Screen* screen, const Visual* visual)
+{
+    Display* dpy = DisplayOfScreen(screen);
+    GdkDisplay* gdkDpy = gdk_x11_lookup_xdisplay(dpy);
+    if (!gdkDpy)
+        return NULL;
+
+    // I wish there were a gdk_x11_display_lookup_screen.
+    gint screen_num = 0;
+    for (int s = 0; s < ScreenCount(dpy); ++s) {
+        if (ScreenOfDisplay(dpy, s) == screen) {
+            screen_num = s;
+            break;
+        }
+    }
+    GdkScreen* gdkScreen = gdk_display_get_screen(gdkDpy, screen_num);
+
+    // Common case: the display's default colormap
+    if (visual ==
+        GDK_VISUAL_XVISUAL(gdk_screen_get_system_visual(gdkScreen)))
+        return gdk_screen_get_system_colormap(gdkScreen);    
+
+    // widget/src/gtk2/mozcontainer.c uses gdk_rgb_get_colormap()
+    // which is inherited by child widgets, so this is the visual
+    // expected when drawing directly to widget surfaces or surfaces
+    // created using cairo_surface_create_similar with
+    // CAIRO_CONTENT_COLOR.
+    // gdk_screen_get_rgb_colormap is the generalization of
+    // gdk_rgb_get_colormap for any screen.
+    if (visual ==
+        GDK_VISUAL_XVISUAL(gdk_screen_get_rgb_visual(gdkScreen)))
+        return gdk_screen_get_rgb_colormap(gdkScreen);
+
+    // This is the visual expected on displays with the Composite
+    // extension enabled when the surface has been created using
+    // cairo_surface_create_similar with CAIRO_CONTENT_COLOR_ALPHA,
+    // as happens with non-unit opacity.
+    if (visual ==
+        GDK_VISUAL_XVISUAL(gdk_screen_get_rgba_visual(gdkScreen)))
+        return gdk_screen_get_rgba_colormap(gdkScreen);
+
+    return NULL;
+}
+#endif
+
 GdkDrawable *
 gfxPlatformGtk::GetGdkDrawable(gfxASurface *target)
 {
     if (target->CairoStatus())
         return nsnull;
 
-    return (GdkDrawable*) cairo_surface_get_user_data (target->CairoSurface(),
-                                                       &cairo_gdk_drawable_key);
+    GdkDrawable *result;
+
+    result = (GdkDrawable*) cairo_surface_get_user_data (target->CairoSurface(),
+                                                         &cairo_gdk_drawable_key);
+    if (result)
+        return result;
+
+#ifdef MOZ_X11
+    if (target->GetType() == gfxASurface::SurfaceTypeXlib) {
+        gfxXlibSurface *xs = (gfxXlibSurface*) target;
+
+        // try looking it up in gdk's table
+        result = (GdkDrawable*) gdk_xid_table_lookup(xs->XDrawable());
+        if (result) {
+            SetGdkDrawable(target, result);
+            return result;
+        }
+
+        // If all else fails, try doing a foreign_new
+        // but don't bother if we can't get a colormap.
+        // Without a colormap GDK won't know how to draw.
+        Screen *screen = cairo_xlib_surface_get_screen(xs->CairoSurface());
+        Visual *visual = cairo_xlib_surface_get_visual(xs->CairoSurface());
+        GdkColormap *cmap = LookupGdkColormapForVisual(screen, visual);
+        if (cmap == None)
+            return nsnull;
+
+        result = (GdkDrawable*) gdk_pixmap_foreign_new_for_display
+            (gdk_display_get_default(), xs->XDrawable());
+        if (result) {
+            gdk_drawable_set_colormap(result, cmap);
+
+            SetGdkDrawable(target, result);
+            // Release our ref.  The object is held by target.  Caller will
+            // only need to ref if it wants to keep the drawable longer than
+            // target.
+            g_object_unref(result);
+            return result;
+        }
+    }
+#endif
+
+    return nsnull;
 }
--- a/widget/src/gtk2/nsWindow.cpp
+++ b/widget/src/gtk2/nsWindow.cpp
@@ -1725,17 +1725,18 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
     if (NS_UNLIKELY(!rc)) {
         g_free(rects);
         return FALSE;
     }
 
     // do double-buffering and clipping here
     nsRefPtr<gfxContext> ctx = rc->ThebesContext();
 
-    gfxPlatformGtk::GetPlatform()->SetGdkDrawable(ctx->OriginalSurface(), GDK_DRAWABLE(mDrawingarea->inner_window));
+    gfxPlatformGtk::GetPlatform()->SetGdkDrawable(ctx->OriginalSurface(),
+                                                  GDK_DRAWABLE(mDrawingarea->inner_window));
 
     // clip to the update region
     ctx->Save();
     ctx->NewPath();
     for (r = rects; r < r_end; ++r) {
         ctx->Rectangle(gfxRect(r->x, r->y, r->width, r->height));
     }
     ctx->Clip();
@@ -1795,16 +1796,17 @@ nsWindow::OnExposeEvent(GtkWidget *aWidg
                                                            boundsRect.Size());
             if (bufferPixmapSurface && bufferPixmapSurface->CairoStatus()) {
                 bufferPixmapSurface = nsnull;
             }
             if (bufferPixmapSurface) {
                 gfxPlatformGtk::GetPlatform()->SetGdkDrawable(
                         static_cast<gfxASurface *>(bufferPixmapSurface), 
                         GDK_DRAWABLE(bufferPixmap));
+
                 bufferPixmapSurface->SetDeviceOffset(gfxPoint(-boundsRect.x, -boundsRect.y));
                 nsCOMPtr<nsIRenderingContext> newRC;
                 nsresult rv = GetDeviceContext()->
                     CreateRenderingContextInstance(*getter_AddRefs(newRC));
                 if (NS_FAILED(rv)) {
                     bufferPixmapSurface = nsnull;
                 } else {
                     rv = newRC->Init(GetDeviceContext(), bufferPixmapSurface);