Index: src/af/gr/gtk/gr_UnixCairoGraphics.h =================================================================== --- src/af/gr/gtk/gr_UnixCairoGraphics.h (revision 30621) +++ src/af/gr/gtk/gr_UnixCairoGraphics.h (working copy) @@ -85,8 +85,6 @@ virtual void scroll(UT_sint32 x_dest, UT_sint32 y_dest, UT_sint32 x_src, UT_sint32 y_src, UT_sint32 width, UT_sint32 height); - virtual void saveRectangle(UT_Rect & r, UT_uint32 iIndx); - virtual void restoreRectangle(UT_uint32 iIndx); virtual GR_Image * genImageFromRectangle(const UT_Rect & r); void init3dColors(GtkWidget* w); @@ -107,9 +105,6 @@ virtual GdkWindow * _getWindow(void) { return m_pWin;} - UT_GenericVector m_vSaveRect; - UT_GenericVector m_vSaveRectBuf; - virtual void _beginPaint(); virtual void _endPaint(); Index: src/af/gr/gtk/gr_UnixCairoGraphics.cpp =================================================================== --- src/af/gr/gtk/gr_UnixCairoGraphics.cpp (revision 30621) +++ src/af/gr/gtk/gr_UnixCairoGraphics.cpp (working copy) @@ -95,16 +95,6 @@ GR_UnixCairoGraphics::~GR_UnixCairoGraphics() { - UT_VECTOR_SPARSEPURGEALL( UT_Rect*, m_vSaveRect); - - // purge saved pixbufs (SPARSE) - for (UT_sint32 i = 0; i < m_vSaveRectBuf.size (); i++) - { - GdkPixbuf * pix = m_vSaveRectBuf.getNthItem(i); - if(pix) { - g_object_unref (G_OBJECT (pix)); - } - } if (m_Widget) { g_signal_handler_disconnect (m_Widget, m_Signal); g_signal_handler_disconnect (m_Widget, m_DestroySignal); @@ -464,62 +454,6 @@ xxx_UT_DEBUGMSG(("Reset clip in gtk cairo \n")); } -void GR_UnixCairoGraphics::saveRectangle(UT_Rect & r, UT_uint32 iIndx) -{ - UT_Rect* oldR = NULL; - cairo_save(m_cr); - cairo_reset_clip(m_cr); - m_vSaveRect.setNthItem(iIndx, new UT_Rect(r),&oldR); - if(oldR) { - delete oldR; - } - - GdkPixbuf * oldC = NULL; - UT_sint32 idx = _tduX(r.left); - UT_sint32 idy = _tduY(r.top); - UT_sint32 idw = _tduR(r.width); - UT_sint32 idh = _tduR(r.height); - cairo_surface_flush ( cairo_get_target(m_cr)); - -#if GTK_CHECK_VERSION(3,0,0) - GdkPixbuf * pix = gdk_pixbuf_get_from_window(_getWindow(), - idx, idy, - idw, idh); -#else - GdkPixbuf * pix = gdk_pixbuf_get_from_drawable(NULL, - _getWindow(), - NULL, - idx, idy, 0, 0, - idw, idh); -#endif - m_vSaveRectBuf.setNthItem(iIndx, pix, &oldC); - - if(oldC) - g_object_unref (G_OBJECT (oldC)); - cairo_restore(m_cr); -} - -void GR_UnixCairoGraphics::restoreRectangle(UT_uint32 iIndx) -{ - cairo_save(m_cr); - cairo_reset_clip(m_cr); - cairo_identity_matrix(m_cr); - UT_Rect * r = m_vSaveRect.getNthItem(iIndx); - GdkPixbuf *p = m_vSaveRectBuf.getNthItem(iIndx); - UT_sint32 idx = _tduX(r->left); - UT_sint32 idy = _tduY(r->top); - UT_sint32 idw = _tduR(r->width); - UT_sint32 idh = _tduR(r->height); - cairo_surface_flush ( cairo_get_target(m_cr)); - - if (p && r) { - gdk_cairo_set_source_pixbuf(m_cr, p, idx, idy); - cairo_rectangle(m_cr, idx, idy, idw, idh); - cairo_fill(m_cr); - } - cairo_restore(m_cr); -} - /*! * Take a screenshot of the graphics and convert it to an image. */ Index: src/af/gr/xp/gr_CairoGraphics.cpp =================================================================== --- src/af/gr/xp/gr_CairoGraphics.cpp (revision 30621) +++ src/af/gr/xp/gr_CairoGraphics.cpp (working copy) @@ -433,6 +433,13 @@ GR_CairoGraphics::~GR_CairoGraphics() { xxx_UT_DEBUGMSG(("Deleting UnixPangoGraphics %x \n",this)); + + // free m_vSaveRect & m_vSaveRectBuf elements + for(UT_uint32 i = 0; i < m_vSaveRect.size(); i++) + delete m_vSaveRect[i]; + for(UT_uint32 i = 0; i < m_vSaveRectBuf.size(); i++) + cairo_surface_destroy(m_vSaveRectBuf[i]); + cairo_destroy(m_cr); m_cr = NULL; @@ -3300,6 +3307,51 @@ cairo_restore(m_cr); } +void GR_CairoGraphics::saveRectangle(UT_Rect &r, UT_uint32 iIndex) +{ + if(iIndex >= m_vSaveRect.size()) + m_vSaveRect.resize(iIndex + 1, NULL); + if(iIndex >= m_vSaveRectBuf.size()) + m_vSaveRectBuf.resize(iIndex + 1, NULL); + + delete m_vSaveRect[iIndex]; + m_vSaveRect[iIndex] = new UT_Rect(r); + + cairo_save(m_cr); + cairo_reset_clip(m_cr); + + cairo_rectangle_t cacheRect; + cacheRect.x = -static_cast(_tduX(r.left)); + cacheRect.y = -static_cast(_tduY(r.top )); + cacheRect.width = static_cast(_tduR(r.width )); + cacheRect.height = static_cast(_tduR(r.height)); + + cairo_surface_flush(cairo_get_target(m_cr)); + cairo_surface_t* newC = _getCairoSurfaceFromContext(m_cr, cacheRect); + + cairo_surface_destroy(m_vSaveRectBuf[iIndex]); + m_vSaveRectBuf[iIndex] = newC; + + cairo_restore(m_cr); +} + +void GR_CairoGraphics::restoreRectangle(UT_uint32 iIndex) +{ + cairo_save(m_cr); + cairo_reset_clip(m_cr); + UT_Rect *r = m_vSaveRect[iIndex]; + cairo_surface_t *s = m_vSaveRectBuf[iIndex]; + double idx = static_cast(_tduX(r->left)) - 0.5; + double idy = static_cast(_tduY(r->top)) - 0.5; + cairo_surface_flush(cairo_get_target(m_cr)); + if(s && r) + { + cairo_set_source_surface(m_cr, s, idx, idy); + cairo_paint(m_cr); + } + cairo_restore(m_cr); +} + void GR_CairoGraphics::clearArea(UT_sint32 x, UT_sint32 y, UT_sint32 width, UT_sint32 height) { Index: src/af/gr/xp/gr_CairoGraphics.h =================================================================== --- src/af/gr/xp/gr_CairoGraphics.h (revision 30621) +++ src/af/gr/xp/gr_CairoGraphics.h (working copy) @@ -320,8 +320,8 @@ // UT_sint32 x_src, UT_sint32 y_src, // UT_sint32 width, UT_sint32 height); - // virtual void saveRectangle(UT_Rect & r, UT_uint32 iIndx); - // virtual void restoreRectangle(UT_uint32 iIndx); + virtual void saveRectangle(UT_Rect & r, UT_uint32 iIndx); + virtual void restoreRectangle(UT_uint32 iIndx); // virtual GR_Image * genImageFromRectangle(const UT_Rect & r); virtual void setLineProperties(double inWidth, @@ -414,6 +414,7 @@ UT_sint32 m_iPrevY2; UT_uint32 m_iPrevRect; UT_sint32 m_iXORCount; + /** init the cairo context once created */ void _initCairo(); @@ -424,6 +425,10 @@ // Suspend / resume drawing void _DeviceContext_SuspendDrawing(); void _DeviceContext_ResumeDrawing(); + + // save / restore rectangle vectors + std::vector m_vSaveRect; + std::vector m_vSaveRectBuf; private: static UT_uint32 s_iInstanceCount;