From 5e4e624b517c071f22bc29908654025664d89b62 Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Thu, 9 Oct 2003 00:24:12 +0000 Subject: [PATCH] Further work on bitmap drawing and rescaling. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/WX_2_4_BRANCH@24132 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- src/gtk/bitmap.cpp | 58 ++++++++-- src/gtk/dcclient.cpp | 248 +++++++++++++++++++++++------------------- src/gtk1/bitmap.cpp | 58 ++++++++-- src/gtk1/dcclient.cpp | 248 +++++++++++++++++++++++------------------- 4 files changed, 372 insertions(+), 240 deletions(-) diff --git a/src/gtk/bitmap.cpp b/src/gtk/bitmap.cpp index b67a17c421..e8e1948d3d 100644 --- a/src/gtk/bitmap.cpp +++ b/src/gtk/bitmap.cpp @@ -1047,7 +1047,7 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight, tabley[y] = (int) floor(0.5 + scy * (y+clipy)); // Main rescaling routine starts here - for(int h=0; hGetBitmap(), 0, 0, GetWidth(), GetHeight() ); + + for (int h = 0; h < height; h++) + { + char outbyte = 0; + + for (int w=0; wdestroyed || src_private->destroyed) - return; - - src_width = src_private->width; - src_height = src_private->height; - - gc_private = (GdkGCPrivate*) gc; -#endif - if (width == -1) width = src_width; if (height == -1) height = src_height; -#ifdef __WXGTK20__ XCopyPlane( GDK_WINDOW_XDISPLAY(drawable), GDK_WINDOW_XID(src), GDK_WINDOW_XID(drawable), GDK_GC_XGC(gc), xsrc, ysrc, width, height, - xdest, ydest, + 0, 0, 1 ); #else + GdkWindowPrivate *drawable_private; + GdkWindowPrivate *src_private; + GdkGCPrivate *gc_private; + + drawable_private = (GdkWindowPrivate*) drawable; + src_private = (GdkWindowPrivate*) src; + if (drawable_private->destroyed || src_private->destroyed) + return; + + gint src_width = src_private->width; + gint src_height = src_private->height; + + gc_private = (GdkGCPrivate*) gc; + + if (width == -1) width = src_width; + if (height == -1) height = src_height; + XCopyPlane( drawable_private->xdisplay, src_private->xwindow, drawable_private->xwindow, @@ -1041,7 +1035,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, bool is_mono = (bitmap.GetBitmap() != NULL); - /* scale/translate size and position */ + // scale/translate size and position int xx = XLOG2DEV(x); int yy = YLOG2DEV(y); @@ -1056,7 +1050,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, int ww = XLOG2DEVREL(w); int hh = YLOG2DEVREL(h); - /* compare to current clipping region */ + // compare to current clipping region if (!m_currentClippingRegion.IsNull()) { wxRegion tmp( xx,yy,ww,hh ); @@ -1065,7 +1059,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, return; } - /* scale bitmap if required */ + // scale bitmap if required wxBitmap use_bitmap; if ((w != ww) || (h != hh)) { @@ -1081,63 +1075,77 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, use_bitmap = bitmap; } - /* apply mask if any */ + // apply mask if any GdkBitmap *mask = (GdkBitmap *) NULL; if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); - if (useMask && mask) + GdkBitmap *new_mask = (GdkBitmap*) NULL; + + if (useMask && mask) + { + if (!m_currentClippingRegion.IsNull()) { - GdkBitmap *new_mask = (GdkBitmap*) NULL; -#ifndef __WXGTK20__ // TODO fix crash - if (!m_currentClippingRegion.IsNull()) - { - GdkColor col; - new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 ); - GdkGC *gc = gdk_gc_new( new_mask ); - col.pixel = 0; - gdk_gc_set_foreground( gc, &col ); - gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); - col.pixel = 0; - gdk_gc_set_background( gc, &col ); - col.pixel = 1; - gdk_gc_set_foreground( gc, &col ); - gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() ); - gdk_gc_set_clip_origin( gc, -xx, -yy ); - gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED ); - gdk_gc_set_stipple( gc, mask ); - gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); - gdk_gc_unref( gc ); - } -#endif - if (is_mono) - { - if (new_mask) - gdk_gc_set_clip_mask( m_textGC, new_mask ); - else - gdk_gc_set_clip_mask( m_textGC, mask ); - gdk_gc_set_clip_origin( m_textGC, xx, yy ); - } - else - { - if (new_mask) - gdk_gc_set_clip_mask( m_penGC, new_mask ); - else - gdk_gc_set_clip_mask( m_penGC, mask ); - gdk_gc_set_clip_origin( m_penGC, xx, yy ); - } - - if (new_mask) - gdk_bitmap_unref( new_mask ); + GdkColor col; + new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 ); + GdkGC *gc = gdk_gc_new( new_mask ); + col.pixel = 0; + gdk_gc_set_foreground( gc, &col ); + gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); + col.pixel = 0; + gdk_gc_set_background( gc, &col ); + col.pixel = 1; + gdk_gc_set_foreground( gc, &col ); + gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_origin( gc, -xx, -yy ); + gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED ); + gdk_gc_set_stipple( gc, mask ); + gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); + gdk_gc_unref( gc ); } + + if (is_mono) + { + if (new_mask) + gdk_gc_set_clip_mask( m_textGC, new_mask ); + else + gdk_gc_set_clip_mask( m_textGC, mask ); + gdk_gc_set_clip_origin( m_textGC, xx, yy ); + } + else + { + if (new_mask) + gdk_gc_set_clip_mask( m_penGC, new_mask ); + else + gdk_gc_set_clip_mask( m_penGC, mask ); + gdk_gc_set_clip_origin( m_penGC, xx, yy ); + } + } - /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For - drawing a mono-bitmap (XBitmap) we use the current text GC */ + // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For + // drawing a mono-bitmap (XBitmap) we use the current text GC if (is_mono) + { +#ifdef __WXGTK20__ + GdkPixmap *bitmap = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, -1 ); + GdkGC *gc = gdk_gc_new( bitmap ); + gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() ); + gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() ); + gdk_wx_draw_bitmap( bitmap, gc, use_bitmap.GetBitmap(), 0, 0, 0, 0, -1, -1 ); + + gdk_draw_drawable( m_window, m_textGC, bitmap, 0, 0, xx, yy, -1, -1 ); + + gdk_bitmap_unref( bitmap ); + gdk_gc_unref( gc ); +#else gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), 0, 0, xx, yy, -1, -1 ); +#endif + } else + { gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); + } - /* remove mask again if any */ + // remove mask again if any if (useMask && mask) { if (is_mono) @@ -1155,6 +1163,9 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } + + if (new_mask) + gdk_bitmap_unref( new_mask ); } bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, @@ -1165,22 +1176,15 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask ) { - /* this is the nth try to get this utterly useless function to - work. it now completely ignores the scaling or translation - of the source dc, but scales correctly on the target dc and - knows about possible mask information in a memory dc. */ - wxCHECK_MSG( Ok(), FALSE, wxT("invalid window dc") ); wxCHECK_MSG( source, FALSE, wxT("invalid source dc") ); if (!m_window) return FALSE; -#if 1 // transform the source DC coords to the device ones xsrc = source->XLOG2DEV(xsrc); ysrc = source->YLOG2DEV(ysrc); -#endif wxClientDC *srcDC = (wxClientDC*)source; wxMemoryDC *memDC = (wxMemoryDC*)source; @@ -1188,10 +1192,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, bool use_bitmap_method = FALSE; bool is_mono = FALSE; - /* TODO: use the mask origin when drawing transparently */ + // TODO: use the mask origin when drawing transparently if (xsrcMask == -1 && ysrcMask == -1) { - xsrcMask = xsrc; ysrcMask = ysrc; + xsrcMask = xsrc; + ysrcMask = ysrc; } if (srcDC->m_isMemDC) @@ -1200,34 +1205,34 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, is_mono = (memDC->m_selected.GetDepth() == 1); - /* we use the "XCopyArea" way to copy a memory dc into - y different window if the memory dc BOTH - a) doesn't have any mask or its mask isn't used - b) it is clipped - c) is not 1-bit */ + // we use the "XCopyArea" way to copy a memory dc into + // a different window if the memory dc BOTH + // a) doesn't have any mask or its mask isn't used + // b) it is clipped + // c) is not 1-bit if (useMask && (memDC->m_selected.GetMask())) { - /* we HAVE TO use the direct way for memory dcs - that have mask since the XCopyArea doesn't know - about masks */ + // we HAVE TO use the direct way for memory dcs + // that have mask since the XCopyArea doesn't know + // about masks use_bitmap_method = TRUE; } else if (is_mono) { - /* we HAVE TO use the direct way for memory dcs - that are bitmaps because XCopyArea doesn't cope - with different bit depths */ + // we HAVE TO use the direct way for memory dcs + // that are bitmaps because XCopyArea doesn't cope + // with different bit depths use_bitmap_method = TRUE; } else if ((xsrc == 0) && (ysrc == 0) && (width == memDC->m_selected.GetWidth()) && (height == memDC->m_selected.GetHeight())) { - /* we SHOULD use the direct way if all of the bitmap - in the memory dc is copied in which case XCopyArea - wouldn't be able able to boost performace by reducing - the area to be scaled */ + // we SHOULD use the direct way if all of the bitmap + // in the memory dc is copied in which case XCopyArea + // wouldn't be able able to boost performace by reducing + // the area to be scaled use_bitmap_method = TRUE; } else @@ -1284,7 +1289,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, if ((bm_width != bm_ww) || (bm_height != bm_hh)) { - use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh); + use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh); } else { @@ -1296,10 +1301,10 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, GdkBitmap *mask = (GdkBitmap *) NULL; if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); + GdkBitmap *new_mask = (GdkBitmap*) NULL; + if (useMask && mask) { - GdkBitmap *new_mask = (GdkBitmap*) NULL; -#ifndef __WXGTK20__ // TODO fix crash if (!m_currentClippingRegion.IsNull()) { GdkColor col; @@ -1320,7 +1325,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, bm_ww, bm_hh ); gdk_gc_unref( gc ); } -#endif + if (is_mono) { if (new_mask) @@ -1339,21 +1344,36 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, // was: gdk_gc_set_clip_origin( m_penGC, xx, yy ); gdk_gc_set_clip_origin( m_penGC, cx, cy ); } - if (new_mask) - gdk_bitmap_unref( new_mask ); } - /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For - drawing a mono-bitmap (XBitmap) we use the current text GC */ + // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For + // drawing a mono-bitmap (XBitmap) we use the current text GC if (is_mono) + { +#ifdef __WXGTK20__ + GdkPixmap *bitmap = gdk_pixmap_new( wxGetRootWindow()->window, bm_ww, bm_hh, -1 ); + GdkGC *gc = gdk_gc_new( bitmap ); + gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() ); + gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() ); + gdk_wx_draw_bitmap( bitmap, gc, use_bitmap.GetBitmap(), 0, 0, 0, 0, -1, -1 ); + + gdk_draw_drawable( m_window, m_textGC, bitmap, xsrc, ysrc, cx, cy, cw, ch ); + + gdk_bitmap_unref( bitmap ); + gdk_gc_unref( gc ); +#else // was: gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, xx, yy, ww, hh ); gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, cx, cy, cw, ch ); +#endif + } else + { // was: gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, cx, cy, cw, ch ); + } - /* remove mask again if any */ + // remove mask again if any if (useMask && mask) { if (is_mono) @@ -1371,8 +1391,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } + + if (new_mask) + gdk_bitmap_unref( new_mask ); } - else /* use_bitmap_method */ + else // use_bitmap_method { if ((width != ww) || (height != hh)) { @@ -1382,7 +1405,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord cx,cy,cw,ch; tmp.GetBox(cx,cy,cw,ch); - // rescale bitmap + // rescale bitmap wxBitmap bitmap = memDC->m_selected.Rescale( cx-xx, cy-yy, cw, ch, ww, hh ); // draw scaled bitmap @@ -1391,9 +1414,9 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, } else { - /* No scaling and not a memory dc with a mask either */ + // No scaling and not a memory dc with a mask either - /* copy including child window contents */ + // copy including child window contents gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS ); gdk_window_copy_area( m_window, m_penGC, xx, yy, srcDC->GetWindow(), @@ -1403,6 +1426,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, } SetLogicalFunction( old_logical_func ); + return TRUE; } diff --git a/src/gtk1/bitmap.cpp b/src/gtk1/bitmap.cpp index b67a17c421..e8e1948d3d 100644 --- a/src/gtk1/bitmap.cpp +++ b/src/gtk1/bitmap.cpp @@ -1047,7 +1047,7 @@ wxBitmap wxBitmap::Rescale( int clipx, int clipy, int clipwidth, int clipheight, tabley[y] = (int) floor(0.5 + scy * (y+clipy)); // Main rescaling routine starts here - for(int h=0; hGetBitmap(), 0, 0, GetWidth(), GetHeight() ); + + for (int h = 0; h < height; h++) + { + char outbyte = 0; + + for (int w=0; wdestroyed || src_private->destroyed) - return; - - src_width = src_private->width; - src_height = src_private->height; - - gc_private = (GdkGCPrivate*) gc; -#endif - if (width == -1) width = src_width; if (height == -1) height = src_height; -#ifdef __WXGTK20__ XCopyPlane( GDK_WINDOW_XDISPLAY(drawable), GDK_WINDOW_XID(src), GDK_WINDOW_XID(drawable), GDK_GC_XGC(gc), xsrc, ysrc, width, height, - xdest, ydest, + 0, 0, 1 ); #else + GdkWindowPrivate *drawable_private; + GdkWindowPrivate *src_private; + GdkGCPrivate *gc_private; + + drawable_private = (GdkWindowPrivate*) drawable; + src_private = (GdkWindowPrivate*) src; + if (drawable_private->destroyed || src_private->destroyed) + return; + + gint src_width = src_private->width; + gint src_height = src_private->height; + + gc_private = (GdkGCPrivate*) gc; + + if (width == -1) width = src_width; + if (height == -1) height = src_height; + XCopyPlane( drawable_private->xdisplay, src_private->xwindow, drawable_private->xwindow, @@ -1041,7 +1035,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, bool is_mono = (bitmap.GetBitmap() != NULL); - /* scale/translate size and position */ + // scale/translate size and position int xx = XLOG2DEV(x); int yy = YLOG2DEV(y); @@ -1056,7 +1050,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, int ww = XLOG2DEVREL(w); int hh = YLOG2DEVREL(h); - /* compare to current clipping region */ + // compare to current clipping region if (!m_currentClippingRegion.IsNull()) { wxRegion tmp( xx,yy,ww,hh ); @@ -1065,7 +1059,7 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, return; } - /* scale bitmap if required */ + // scale bitmap if required wxBitmap use_bitmap; if ((w != ww) || (h != hh)) { @@ -1081,63 +1075,77 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, use_bitmap = bitmap; } - /* apply mask if any */ + // apply mask if any GdkBitmap *mask = (GdkBitmap *) NULL; if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); - if (useMask && mask) + GdkBitmap *new_mask = (GdkBitmap*) NULL; + + if (useMask && mask) + { + if (!m_currentClippingRegion.IsNull()) { - GdkBitmap *new_mask = (GdkBitmap*) NULL; -#ifndef __WXGTK20__ // TODO fix crash - if (!m_currentClippingRegion.IsNull()) - { - GdkColor col; - new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 ); - GdkGC *gc = gdk_gc_new( new_mask ); - col.pixel = 0; - gdk_gc_set_foreground( gc, &col ); - gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); - col.pixel = 0; - gdk_gc_set_background( gc, &col ); - col.pixel = 1; - gdk_gc_set_foreground( gc, &col ); - gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() ); - gdk_gc_set_clip_origin( gc, -xx, -yy ); - gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED ); - gdk_gc_set_stipple( gc, mask ); - gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); - gdk_gc_unref( gc ); - } -#endif - if (is_mono) - { - if (new_mask) - gdk_gc_set_clip_mask( m_textGC, new_mask ); - else - gdk_gc_set_clip_mask( m_textGC, mask ); - gdk_gc_set_clip_origin( m_textGC, xx, yy ); - } - else - { - if (new_mask) - gdk_gc_set_clip_mask( m_penGC, new_mask ); - else - gdk_gc_set_clip_mask( m_penGC, mask ); - gdk_gc_set_clip_origin( m_penGC, xx, yy ); - } - - if (new_mask) - gdk_bitmap_unref( new_mask ); + GdkColor col; + new_mask = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, 1 ); + GdkGC *gc = gdk_gc_new( new_mask ); + col.pixel = 0; + gdk_gc_set_foreground( gc, &col ); + gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); + col.pixel = 0; + gdk_gc_set_background( gc, &col ); + col.pixel = 1; + gdk_gc_set_foreground( gc, &col ); + gdk_gc_set_clip_region( gc, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_origin( gc, -xx, -yy ); + gdk_gc_set_fill( gc, GDK_OPAQUE_STIPPLED ); + gdk_gc_set_stipple( gc, mask ); + gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, ww, hh ); + gdk_gc_unref( gc ); } + + if (is_mono) + { + if (new_mask) + gdk_gc_set_clip_mask( m_textGC, new_mask ); + else + gdk_gc_set_clip_mask( m_textGC, mask ); + gdk_gc_set_clip_origin( m_textGC, xx, yy ); + } + else + { + if (new_mask) + gdk_gc_set_clip_mask( m_penGC, new_mask ); + else + gdk_gc_set_clip_mask( m_penGC, mask ); + gdk_gc_set_clip_origin( m_penGC, xx, yy ); + } + } - /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For - drawing a mono-bitmap (XBitmap) we use the current text GC */ + // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For + // drawing a mono-bitmap (XBitmap) we use the current text GC if (is_mono) + { +#ifdef __WXGTK20__ + GdkPixmap *bitmap = gdk_pixmap_new( wxGetRootWindow()->window, ww, hh, -1 ); + GdkGC *gc = gdk_gc_new( bitmap ); + gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() ); + gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() ); + gdk_wx_draw_bitmap( bitmap, gc, use_bitmap.GetBitmap(), 0, 0, 0, 0, -1, -1 ); + + gdk_draw_drawable( m_window, m_textGC, bitmap, 0, 0, xx, yy, -1, -1 ); + + gdk_bitmap_unref( bitmap ); + gdk_gc_unref( gc ); +#else gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), 0, 0, xx, yy, -1, -1 ); +#endif + } else + { gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); + } - /* remove mask again if any */ + // remove mask again if any if (useMask && mask) { if (is_mono) @@ -1155,6 +1163,9 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } + + if (new_mask) + gdk_bitmap_unref( new_mask ); } bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, @@ -1165,22 +1176,15 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask ) { - /* this is the nth try to get this utterly useless function to - work. it now completely ignores the scaling or translation - of the source dc, but scales correctly on the target dc and - knows about possible mask information in a memory dc. */ - wxCHECK_MSG( Ok(), FALSE, wxT("invalid window dc") ); wxCHECK_MSG( source, FALSE, wxT("invalid source dc") ); if (!m_window) return FALSE; -#if 1 // transform the source DC coords to the device ones xsrc = source->XLOG2DEV(xsrc); ysrc = source->YLOG2DEV(ysrc); -#endif wxClientDC *srcDC = (wxClientDC*)source; wxMemoryDC *memDC = (wxMemoryDC*)source; @@ -1188,10 +1192,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, bool use_bitmap_method = FALSE; bool is_mono = FALSE; - /* TODO: use the mask origin when drawing transparently */ + // TODO: use the mask origin when drawing transparently if (xsrcMask == -1 && ysrcMask == -1) { - xsrcMask = xsrc; ysrcMask = ysrc; + xsrcMask = xsrc; + ysrcMask = ysrc; } if (srcDC->m_isMemDC) @@ -1200,34 +1205,34 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, is_mono = (memDC->m_selected.GetDepth() == 1); - /* we use the "XCopyArea" way to copy a memory dc into - y different window if the memory dc BOTH - a) doesn't have any mask or its mask isn't used - b) it is clipped - c) is not 1-bit */ + // we use the "XCopyArea" way to copy a memory dc into + // a different window if the memory dc BOTH + // a) doesn't have any mask or its mask isn't used + // b) it is clipped + // c) is not 1-bit if (useMask && (memDC->m_selected.GetMask())) { - /* we HAVE TO use the direct way for memory dcs - that have mask since the XCopyArea doesn't know - about masks */ + // we HAVE TO use the direct way for memory dcs + // that have mask since the XCopyArea doesn't know + // about masks use_bitmap_method = TRUE; } else if (is_mono) { - /* we HAVE TO use the direct way for memory dcs - that are bitmaps because XCopyArea doesn't cope - with different bit depths */ + // we HAVE TO use the direct way for memory dcs + // that are bitmaps because XCopyArea doesn't cope + // with different bit depths use_bitmap_method = TRUE; } else if ((xsrc == 0) && (ysrc == 0) && (width == memDC->m_selected.GetWidth()) && (height == memDC->m_selected.GetHeight())) { - /* we SHOULD use the direct way if all of the bitmap - in the memory dc is copied in which case XCopyArea - wouldn't be able able to boost performace by reducing - the area to be scaled */ + // we SHOULD use the direct way if all of the bitmap + // in the memory dc is copied in which case XCopyArea + // wouldn't be able able to boost performace by reducing + // the area to be scaled use_bitmap_method = TRUE; } else @@ -1284,7 +1289,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, if ((bm_width != bm_ww) || (bm_height != bm_hh)) { - use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh); + use_bitmap = memDC->m_selected.Rescale(cx-xx,cy-yy,cw,ch,bm_ww,bm_hh); } else { @@ -1296,10 +1301,10 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, GdkBitmap *mask = (GdkBitmap *) NULL; if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); + GdkBitmap *new_mask = (GdkBitmap*) NULL; + if (useMask && mask) { - GdkBitmap *new_mask = (GdkBitmap*) NULL; -#ifndef __WXGTK20__ // TODO fix crash if (!m_currentClippingRegion.IsNull()) { GdkColor col; @@ -1320,7 +1325,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, gdk_draw_rectangle( new_mask, gc, TRUE, 0, 0, bm_ww, bm_hh ); gdk_gc_unref( gc ); } -#endif + if (is_mono) { if (new_mask) @@ -1339,21 +1344,36 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, // was: gdk_gc_set_clip_origin( m_penGC, xx, yy ); gdk_gc_set_clip_origin( m_penGC, cx, cy ); } - if (new_mask) - gdk_bitmap_unref( new_mask ); } - /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For - drawing a mono-bitmap (XBitmap) we use the current text GC */ + // Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For + // drawing a mono-bitmap (XBitmap) we use the current text GC if (is_mono) + { +#ifdef __WXGTK20__ + GdkPixmap *bitmap = gdk_pixmap_new( wxGetRootWindow()->window, bm_ww, bm_hh, -1 ); + GdkGC *gc = gdk_gc_new( bitmap ); + gdk_gc_set_foreground( gc, m_textForegroundColour.GetColor() ); + gdk_gc_set_background( gc, m_textBackgroundColour.GetColor() ); + gdk_wx_draw_bitmap( bitmap, gc, use_bitmap.GetBitmap(), 0, 0, 0, 0, -1, -1 ); + + gdk_draw_drawable( m_window, m_textGC, bitmap, xsrc, ysrc, cx, cy, cw, ch ); + + gdk_bitmap_unref( bitmap ); + gdk_gc_unref( gc ); +#else // was: gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, xx, yy, ww, hh ); gdk_wx_draw_bitmap( m_window, m_textGC, use_bitmap.GetBitmap(), xsrc, ysrc, cx, cy, cw, ch ); +#endif + } else + { // was: gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, cx, cy, cw, ch ); + } - /* remove mask again if any */ + // remove mask again if any if (useMask && mask) { if (is_mono) @@ -1371,8 +1391,11 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } + + if (new_mask) + gdk_bitmap_unref( new_mask ); } - else /* use_bitmap_method */ + else // use_bitmap_method { if ((width != ww) || (height != hh)) { @@ -1382,7 +1405,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord cx,cy,cw,ch; tmp.GetBox(cx,cy,cw,ch); - // rescale bitmap + // rescale bitmap wxBitmap bitmap = memDC->m_selected.Rescale( cx-xx, cy-yy, cw, ch, ww, hh ); // draw scaled bitmap @@ -1391,9 +1414,9 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, } else { - /* No scaling and not a memory dc with a mask either */ + // No scaling and not a memory dc with a mask either - /* copy including child window contents */ + // copy including child window contents gdk_gc_set_subwindow( m_penGC, GDK_INCLUDE_INFERIORS ); gdk_window_copy_area( m_window, m_penGC, xx, yy, srcDC->GetWindow(), @@ -1403,6 +1426,7 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, } SetLogicalFunction( old_logical_func ); + return TRUE; }