From 3d2d8da1d89c195cb44f95f267989118e205c7bf Mon Sep 17 00:00:00 2001 From: Robert Roebling Date: Mon, 21 Feb 2000 14:16:32 +0000 Subject: [PATCH] Implemented MSW's paint region clipping, but it exposed some bug in GTK's guffaw stuff. Implmented GC pooling. Implemented Corrcet mixing of pain region clipping, user clipping and masked bitmap clipping. Minor other corrections. git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@6172 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- include/wx/gtk/dcclient.h | 2 + include/wx/gtk1/dcclient.h | 2 + include/wx/stubs/frame.h | 3 + samples/drawing/drawing.cpp | 15 ++ samples/printing/printing.cpp | 4 +- src/generic/listctrl.cpp | 33 ++- src/generic/plot.cpp | 4 +- src/gtk/data.cpp | 4 + src/gtk/dcclient.cpp | 406 ++++++++++++++++++++++++++-------- src/gtk/dcmemory.cpp | 1 + src/gtk/window.cpp | 50 +++-- src/gtk1/data.cpp | 4 + src/gtk1/dcclient.cpp | 406 ++++++++++++++++++++++++++-------- src/gtk1/dcmemory.cpp | 1 + src/gtk1/window.cpp | 50 +++-- 15 files changed, 732 insertions(+), 253 deletions(-) diff --git a/include/wx/gtk/dcclient.h b/include/wx/gtk/dcclient.h index acc3896336..a70c424edb 100644 --- a/include/wx/gtk/dcclient.h +++ b/include/wx/gtk/dcclient.h @@ -116,6 +116,8 @@ public: GdkColormap *m_cmap; bool m_isMemDC; wxWindow *m_owner; + wxRegion m_currentClippingRegion; + wxRegion m_paintClippingRegion; void SetUpDC(); void Destroy(); diff --git a/include/wx/gtk1/dcclient.h b/include/wx/gtk1/dcclient.h index acc3896336..a70c424edb 100644 --- a/include/wx/gtk1/dcclient.h +++ b/include/wx/gtk1/dcclient.h @@ -116,6 +116,8 @@ public: GdkColormap *m_cmap; bool m_isMemDC; wxWindow *m_owner; + wxRegion m_currentClippingRegion; + wxRegion m_paintClippingRegion; void SetUpDC(); void Destroy(); diff --git a/include/wx/stubs/frame.h b/include/wx/stubs/frame.h index 64ec0d6cd1..540caf249e 100644 --- a/include/wx/stubs/frame.h +++ b/include/wx/stubs/frame.h @@ -18,7 +18,10 @@ #include "wx/window.h" #include "wx/toolbar.h" + +#if wxUSE_ACCEL #include "wx/accel.h" +#endif WXDLLEXPORT_DATA(extern const char*) wxFrameNameStr; WXDLLEXPORT_DATA(extern const char*) wxToolBarNameStr; diff --git a/samples/drawing/drawing.cpp b/samples/drawing/drawing.cpp index aec42daa61..ddfdeaa009 100644 --- a/samples/drawing/drawing.cpp +++ b/samples/drawing/drawing.cpp @@ -677,6 +677,21 @@ void MyCanvas::DrawDefault(wxDC& dc) dc.DrawLine(400, 170, 400, 210); dc.DrawLine(300, 200, 410, 200); + // a few more tests of this kind + dc.SetPen(*wxRED_PEN); + dc.SetBrush( *wxWHITE_BRUSH ); + dc.DrawRectangle(300, 220, 1, 1); + dc.DrawRectangle(310, 220, 2, 2); + dc.DrawRectangle(320, 220, 3, 3); + dc.DrawRectangle(330, 220, 4, 4); + + dc.SetPen(*wxTRANSPARENT_PEN); + dc.SetBrush( *wxWHITE_BRUSH ); + dc.DrawRectangle(300, 230, 1, 1); + dc.DrawRectangle(310, 230, 2, 2); + dc.DrawRectangle(320, 230, 3, 3); + dc.DrawRectangle(330, 230, 4, 4); + // and now for filled rect with outline dc.SetPen(*wxRED_PEN); dc.SetBrush( *wxWHITE_BRUSH ); diff --git a/samples/printing/printing.cpp b/samples/printing/printing.cpp index 04d721a4af..bdc779878e 100644 --- a/samples/printing/printing.cpp +++ b/samples/printing/printing.cpp @@ -104,12 +104,14 @@ bool MyApp::OnInit(void) file_menu->Append(WXPRINT_PAGE_SETUP, "Page Set&up...", "Page setup"); file_menu->Append(WXPRINT_PREVIEW, "Print Pre&view", "Preview"); +#if wxUSE_ACCEL // Accelerators wxAcceleratorEntry entries[1]; entries[0].Set(wxACCEL_CTRL, (int) 'V', WXPRINT_PREVIEW); wxAcceleratorTable accel(1, entries); frame->SetAcceleratorTable(accel); - +#endif + #if defined(__WXMSW__) && wxTEST_POSTSCRIPT_IN_MSW file_menu->AppendSeparator(); file_menu->Append(WXPRINT_PRINT_PS, "Print PostScript...", "Print (PostScript)"); diff --git a/src/generic/listctrl.cpp b/src/generic/listctrl.cpp index fa4ced72aa..8e582c5b55 100644 --- a/src/generic/listctrl.cpp +++ b/src/generic/listctrl.cpp @@ -618,15 +618,14 @@ void wxListLineData::SetAttributes(wxDC *dc, void wxListLineData::DoDraw( wxDC *dc, bool hilight, bool paintBG ) { - wxCoord dev_x = dc->LogicalToDeviceX( m_bound_all.x-2 ); - wxCoord dev_y = dc->LogicalToDeviceY( m_bound_all.y-2 ); - wxCoord dev_w = dc->LogicalToDeviceXRel( m_bound_all.width+4 ); - wxCoord dev_h = dc->LogicalToDeviceYRel( m_bound_all.height+4 ); + wxCoord dev_x = 0; + wxCoord dev_y = 0; + m_owner->CalcScrolledPosition( m_bound_all.x, m_bound_all.y, &dev_x, &dev_y ); + wxCoord dev_w = m_bound_all.width; + wxCoord dev_h = m_bound_all.height; if (!m_owner->IsExposed( dev_x, dev_y, dev_w, dev_h )) - { return; - } wxWindow *listctrl = m_owner->GetParent(); @@ -884,9 +883,9 @@ void wxListHeaderWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) dc.SetPen( *wxWHITE_PEN ); DoDrawRect( &dc, x, y, cw, h-2 ); - dc.SetClippingRegion( x, y, cw-5, h-4 ); +// dc.SetClippingRegion( x, y, cw-5, h-4 ); dc.DrawText( item.m_text, x+4, y+3 ); - dc.DestroyClippingRegion(); +// dc.DestroyClippingRegion(); x += item.m_width; #if wxUSE_GENERIC_LIST_EXTENSIONS if (dc.LogicalToDeviceX(x) > w+5) break; @@ -1191,22 +1190,16 @@ void wxListMainWindow::RefreshLine( wxListLineData *line ) { if (m_dirty) return; + if (!line) return; + int x = 0; int y = 0; int w = 0; int h = 0; - if (line) - { - wxClientDC dc(this); - PrepareDC( dc ); - line->GetExtent( x, y, w, h ); - wxRect rect( - dc.LogicalToDeviceX(x-3), - dc.LogicalToDeviceY(y-3), - dc.LogicalToDeviceXRel(w+6), - dc.LogicalToDeviceXRel(h+6) ); - Refresh( TRUE, &rect ); - } + line->GetExtent( x, y, w, h ); + CalcScrolledPosition( x, y, &x, &y ); + wxRect rect( x, y, w, h ); + Refresh( TRUE, &rect ); } void wxListMainWindow::OnPaint( wxPaintEvent &WXUNUSED(event) ) diff --git a/src/generic/plot.cpp b/src/generic/plot.cpp index a600522441..9d363e9880 100644 --- a/src/generic/plot.cpp +++ b/src/generic/plot.cpp @@ -196,8 +196,6 @@ void wxPlotArea::DrawCurve( wxDC *dc, wxPlotCurve *curve, int from, int to ) if (to == -1) to = view_x + client_width; - to += 2; // no idea why this is needed - double zoom = m_owner->GetZoom(); int start_x = wxMax( from, (int)floor(curve->GetStartX()*zoom) ); @@ -206,6 +204,8 @@ void wxPlotArea::DrawCurve( wxDC *dc, wxPlotCurve *curve, int from, int to ) start_x = wxMax( view_x, start_x ); end_x = wxMin( view_x + client_width, end_x ); + end_x++; + double double_client_height = (double)client_height; double range = curve->GetEndY() - curve->GetStartY(); double end = curve->GetEndY(); diff --git a/src/gtk/data.cpp b/src/gtk/data.cpp index 9971508a7b..abf1e939c0 100644 --- a/src/gtk/data.cpp +++ b/src/gtk/data.cpp @@ -15,7 +15,11 @@ #include "wx/object.h" #include "wx/window.h" #include "wx/dc.h" + +#if wxUSE_ACCEL #include "wx/accel.h" +#endif + #include "wx/dcps.h" #include "wx/icon.h" diff --git a/src/gtk/dcclient.cpp b/src/gtk/dcclient.cpp index 4a06916eef..294e9b890b 100644 --- a/src/gtk/dcclient.cpp +++ b/src/gtk/dcclient.cpp @@ -35,6 +35,8 @@ static GdkPixmap *hatches[num_hatches]; static GdkPixmap **hatch_bitmap = (GdkPixmap **) NULL; +extern GtkWidget *wxRootWindow; + //----------------------------------------------------------------------------- // constants //----------------------------------------------------------------------------- @@ -94,6 +96,70 @@ void gdk_draw_bitmap (GdkDrawable *drawable, 1 ); } +//----------------------------------------------------------------------------- +// Implement Pool of Graphic contexts. Creating them takes too much time. +//----------------------------------------------------------------------------- + +struct wxGC +{ + GdkGC *m_gc; + bool m_mono; + bool m_used; +}; + +static wxGC wxGCPool[200]; + +static void wxInitGCPool() +{ + memset( wxGCPool, 0, 200*sizeof(wxGC) ); +} + +static void wxCleanUpGCPool() +{ + for (int i = 0; i < 200; i++) + { + if (wxGCPool[i].m_gc) + gdk_gc_unref( wxGCPool[i].m_gc ); + } +} + +static GdkGC* wxGetPoolGC( GdkWindow *window, bool mono=FALSE ) +{ + for (int i = 0; i < 200; i++) + { + if (!wxGCPool[i].m_gc) + { + wxGCPool[i].m_gc = gdk_gc_new( window ); + gdk_gc_set_exposures( wxGCPool[i].m_gc, FALSE ); + wxGCPool[i].m_mono = mono; + wxGCPool[i].m_used = FALSE; + } + if ((!wxGCPool[i].m_used) && (wxGCPool[i].m_mono == mono)) + { + wxGCPool[i].m_used = TRUE; + return wxGCPool[i].m_gc; + } + } + + wxFAIL_MSG( wxT("No GC available") ); + + return (GdkGC*) NULL; +} + +static void wxFreePoolGC( GdkGC *gc ) +{ + for (int i = 0; i < 200; i++) + { + if (wxGCPool[i].m_gc == gc) + { + wxGCPool[i].m_used = FALSE; + return; + } + } + + wxFAIL_MSG( wxT("Wrong GC") ); +} + //----------------------------------------------------------------------------- // wxWindowDC //----------------------------------------------------------------------------- @@ -525,7 +591,6 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, bool is_mono = (bitmap.GetBitmap() != NULL); /* scale/translate size and position */ - int xx = XLOG2DEV(x); int yy = YLOG2DEV(y); @@ -540,10 +605,17 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, int ww = XLOG2DEVREL(w); int hh = YLOG2DEVREL(h); + /* compare to current clipping region */ + if (!m_currentClippingRegion.IsEmpty()) + { + wxRegion tmp( xx,yy,ww,hh ); + tmp.Intersect( m_currentClippingRegion ); + if (tmp.IsEmpty()) + return; + } + /* scale bitmap if required */ - wxBitmap use_bitmap; - if ((w != ww) || (h != hh)) { wxImage image( bitmap ); @@ -559,23 +631,51 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, } /* apply mask if any */ - GdkBitmap *mask = (GdkBitmap *) NULL; if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); - if (useMask && mask) - { - if (is_mono) - { - gdk_gc_set_clip_mask( m_textGC, mask ); - gdk_gc_set_clip_origin( m_textGC, xx, yy ); - } - else + if (useMask && mask) { - gdk_gc_set_clip_mask( m_penGC, mask ); - gdk_gc_set_clip_origin( m_penGC, xx, yy ); + GdkBitmap *new_mask = (GdkBitmap*) NULL; + if (!m_currentClippingRegion.IsEmpty()) + { + GdkColor col; + new_mask = gdk_pixmap_new( wxRootWindow->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 ); + } + 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 */ @@ -585,18 +685,21 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); /* remove mask again if any */ - if (useMask && mask) { if (is_mono) { gdk_gc_set_clip_mask( m_textGC, (GdkBitmap *) NULL ); gdk_gc_set_clip_origin( m_textGC, 0, 0 ); + if (!m_currentClippingRegion.IsEmpty()) + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); } else { gdk_gc_set_clip_mask( m_penGC, (GdkBitmap *) NULL ); gdk_gc_set_clip_origin( m_penGC, 0, 0 ); + if (!m_currentClippingRegion.IsEmpty()) + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } } @@ -666,13 +769,28 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he CalcBoundingBox( xdest, ydest ); CalcBoundingBox( xdest + width, ydest + height ); + /* scale/translate size and position */ + wxCoord xx = XLOG2DEV(xdest); + wxCoord yy = YLOG2DEV(ydest); + + wxCoord ww = XLOG2DEVREL(width); + wxCoord hh = YLOG2DEVREL(height); + + /* compare to current clipping region */ + if (!m_currentClippingRegion.IsEmpty()) + { + wxRegion tmp( xx,yy,ww,hh ); + tmp.Intersect( m_currentClippingRegion ); + if (tmp.IsEmpty()) + return TRUE; + } + int old_logical_func = m_logicalFunction; SetLogicalFunction( logical_func ); if (use_bitmap_method) { /* scale/translate bitmap size */ - wxCoord bm_width = memDC->m_selected.GetWidth(); wxCoord bm_height = memDC->m_selected.GetHeight(); @@ -680,7 +798,6 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he wxCoord bm_hh = YLOG2DEVREL( bm_height ); /* scale bitmap if required */ - wxBitmap use_bitmap; if ((bm_width != bm_ww) || (bm_height != bm_hh)) @@ -698,31 +815,51 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he use_bitmap = memDC->m_selected; } - /* scale/translate size and position */ - - wxCoord xx = XLOG2DEV(xdest); - wxCoord yy = YLOG2DEV(ydest); - - wxCoord ww = XLOG2DEVREL(width); - wxCoord hh = YLOG2DEVREL(height); - /* 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 (!m_currentClippingRegion.IsEmpty()) + { + GdkColor col; + new_mask = gdk_pixmap_new( wxRootWindow->window, bm_ww, bm_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, bm_ww, bm_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, bm_ww, bm_hh ); + gdk_gc_unref( gc ); + } + if (is_mono) { - gdk_gc_set_clip_mask( m_textGC, mask ); + 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 { - gdk_gc_set_clip_mask( m_penGC, mask ); + 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 ); } /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For @@ -733,31 +870,26 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); /* remove mask again if any */ - if (useMask && mask) { if (is_mono) { gdk_gc_set_clip_mask( m_textGC, (GdkBitmap *) NULL ); gdk_gc_set_clip_origin( m_textGC, 0, 0 ); + if (!m_currentClippingRegion.IsEmpty()) + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); } else { gdk_gc_set_clip_mask( m_penGC, (GdkBitmap *) NULL ); gdk_gc_set_clip_origin( m_penGC, 0, 0 ); + if (!m_currentClippingRegion.IsEmpty()) + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } } else /* use_bitmap_method */ { - /* scale/translate size and position */ - - wxCoord xx = XLOG2DEV(xdest); - wxCoord yy = YLOG2DEV(ydest); - - wxCoord ww = XLOG2DEVREL(width); - wxCoord hh = YLOG2DEVREL(height); - if ((width != ww) || (height != hh)) { /* draw source window into a bitmap as we cannot scale @@ -1309,8 +1441,9 @@ void wxWindowDC::SetLogicalFunction( int function ) gdk_gc_set_function( m_brushGC, mode ); // to stay compatible with wxMSW, we don't apply ROPs to the text - // operations (i.e. DrawText/DrawRotatedText) - // gdk_gc_set_function( m_textGC, mode ); + // operations (i.e. DrawText/DrawRotatedText). + // True, but mono-bitmaps use the m_textGC and they use ROPs as well. + gdk_gc_set_function( m_textGC, mode ); } void wxWindowDC::SetTextForeground( const wxColour &col ) @@ -1374,15 +1507,21 @@ void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoo if (!m_window) return; - GdkRectangle rect; + wxRect rect; rect.x = XLOG2DEV(x); rect.y = YLOG2DEV(y); rect.width = XLOG2DEVREL(width); rect.height = YLOG2DEVREL(height); - gdk_gc_set_clip_rectangle( m_penGC, &rect ); - gdk_gc_set_clip_rectangle( m_brushGC, &rect ); - gdk_gc_set_clip_rectangle( m_textGC, &rect ); - gdk_gc_set_clip_rectangle( m_bgGC, &rect ); + + m_currentClippingRegion.Clear(); + m_currentClippingRegion.Union( rect ); + if (!m_paintClippingRegion.IsEmpty()) + m_currentClippingRegion.Intersect( m_paintClippingRegion ); + + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, m_currentClippingRegion.GetRegion() ); } void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) @@ -1401,11 +1540,16 @@ void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) wxDC::DoSetClippingRegion( x, y, w, h ); if (!m_window) return; - - gdk_gc_set_clip_region( m_penGC, region.GetRegion() ); - gdk_gc_set_clip_region( m_brushGC, region.GetRegion() ); - gdk_gc_set_clip_region( m_textGC, region.GetRegion() ); - gdk_gc_set_clip_region( m_bgGC, region.GetRegion() ); + + m_currentClippingRegion.Clear(); + m_currentClippingRegion.Union( region ); + if (!m_paintClippingRegion.IsEmpty()) + m_currentClippingRegion.Intersect( m_paintClippingRegion ); + + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, m_currentClippingRegion.GetRegion() ); } void wxWindowDC::DestroyClippingRegion() @@ -1414,52 +1558,92 @@ void wxWindowDC::DestroyClippingRegion() wxDC::DestroyClippingRegion(); + m_currentClippingRegion.Clear(); + + if (!m_paintClippingRegion.IsEmpty()) + m_currentClippingRegion.Union( m_paintClippingRegion ); + if (!m_window) return; - gdk_gc_set_clip_rectangle( m_penGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_brushGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_textGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_bgGC, (GdkRectangle *) NULL ); + if (m_currentClippingRegion.IsEmpty()) + { + gdk_gc_set_clip_rectangle( m_penGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_brushGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_textGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_bgGC, (GdkRectangle *) NULL ); + } + else + { + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, m_currentClippingRegion.GetRegion() ); + } } void wxWindowDC::SetUpDC() { - Destroy(); m_ok = TRUE; - m_logicalFunction = wxCOPY; - m_penGC = gdk_gc_new( m_window ); - m_brushGC = gdk_gc_new( m_window ); - m_textGC = gdk_gc_new( m_window ); - m_bgGC = gdk_gc_new( m_window ); - - wxColour tmp_col( m_textForegroundColour ); - m_textForegroundColour = wxNullColour; - SetTextForeground( tmp_col ); - tmp_col = m_textBackgroundColour; - m_textBackgroundColour = wxNullColour; - SetTextBackground( tmp_col ); - - wxPen tmp_pen( m_pen ); - m_pen = wxNullPen; - SetPen( tmp_pen ); - - wxFont tmp_font( m_font ); - m_font = wxNullFont; - SetFont( tmp_font ); - - wxBrush tmp_brush( m_brush ); - m_brush = wxNullBrush; - SetBrush( tmp_brush ); + + if (!m_penGC) + { + m_penGC = wxGetPoolGC( m_window ); + m_brushGC = wxGetPoolGC( m_window ); + m_textGC = wxGetPoolGC( m_window ); + m_bgGC = wxGetPoolGC( m_window ); + } -/* - tmp_brush = m_backgroundBrush; - m_backgroundBrush = wxNullBrush; - SetBackground( tmp_brush ); -*/ - tmp_brush = m_backgroundBrush; - m_backgroundBrush = wxNullBrush; - SetBackground( *wxWHITE_BRUSH ); - m_backgroundBrush = tmp_brush; + /* background colour */ + m_backgroundBrush = *wxWHITE_BRUSH; + m_backgroundBrush.GetColour().CalcPixel( m_cmap ); + GdkColor *bg_col = m_backgroundBrush.GetColour().GetColor(); + + /* m_textGC */ + m_textForegroundColour.CalcPixel( m_cmap ); + gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() ); + + m_textBackgroundColour.CalcPixel( m_cmap ); + gdk_gc_set_background( m_textGC, m_textBackgroundColour.GetColor() ); + + gdk_gc_set_fill( m_textGC, GDK_SOLID ); + gdk_gc_set_line_attributes( m_textGC, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND ); + + /* m_penGC */ + m_pen.GetColour().CalcPixel( m_cmap ); + gdk_gc_set_foreground( m_penGC, m_pen.GetColour().GetColor() ); + gdk_gc_set_background( m_penGC, bg_col ); + + gdk_gc_set_fill( m_penGC, GDK_SOLID ); + gdk_gc_set_line_attributes( m_penGC, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND ); + + + /* m_brushGC */ + m_brush.GetColour().CalcPixel( m_cmap ); + gdk_gc_set_foreground( m_brushGC, m_brush.GetColour().GetColor() ); + gdk_gc_set_background( m_brushGC, bg_col ); + + gdk_gc_set_fill( m_brushGC, GDK_SOLID ); + gdk_gc_set_line_attributes( m_brushGC, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND ); + + + /* m_bgGC */ + gdk_gc_set_background( m_bgGC, bg_col ); + gdk_gc_set_foreground( m_bgGC, bg_col ); + + gdk_gc_set_fill( m_bgGC, GDK_SOLID ); + gdk_gc_set_line_attributes( m_bgGC, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND ); + + /* ROPs */ + gdk_gc_set_function( m_textGC, GDK_COPY ); + gdk_gc_set_function( m_brushGC, GDK_COPY ); + gdk_gc_set_function( m_penGC, GDK_COPY ); + gdk_gc_set_function( m_bgGC, GDK_COPY ); + + /* clipping */ + gdk_gc_set_clip_rectangle( m_penGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_brushGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_textGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_bgGC, (GdkRectangle *) NULL ); if (!hatch_bitmap) { @@ -1475,13 +1659,13 @@ void wxWindowDC::SetUpDC() void wxWindowDC::Destroy() { - if (m_penGC) gdk_gc_unref( m_penGC ); + if (m_penGC) wxFreePoolGC( m_penGC ); m_penGC = (GdkGC*) NULL; - if (m_brushGC) gdk_gc_unref( m_brushGC ); + if (m_brushGC) wxFreePoolGC( m_brushGC ); m_brushGC = (GdkGC*) NULL; - if (m_textGC) gdk_gc_unref( m_textGC ); + if (m_textGC) wxFreePoolGC( m_textGC ); m_textGC = (GdkGC*) NULL; - if (m_bgGC) gdk_gc_unref( m_bgGC ); + if (m_bgGC) wxFreePoolGC( m_bgGC ); m_bgGC = (GdkGC*) NULL; } @@ -1702,6 +1886,18 @@ wxPaintDC::wxPaintDC() wxPaintDC::wxPaintDC( wxWindow *win ) : wxWindowDC( win ) { +/* + if (!win->GetUpdateRegion().IsEmpty()) + { + m_paintClippingRegion = win->GetUpdateRegion(); + m_currentClippingRegion.Union( m_paintClippingRegion ); + + gdk_gc_set_clip_region( m_penGC, m_paintClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, m_paintClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, m_paintClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, m_paintClippingRegion.GetRegion() ); + } +*/ } //----------------------------------------------------------------------------- @@ -1720,3 +1916,29 @@ wxClientDC::wxClientDC( wxWindow *win ) { } +// ---------------------------------------------------------------------------- +// wxDCModule +// ---------------------------------------------------------------------------- + +class wxDCModule : public wxModule +{ +public: + bool OnInit(); + void OnExit(); + +private: + DECLARE_DYNAMIC_CLASS(wxDCModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) + +bool wxDCModule::OnInit() +{ + wxInitGCPool(); + return TRUE; +} + +void wxDCModule::OnExit() +{ + wxCleanUpGCPool(); +} diff --git a/src/gtk/dcmemory.cpp b/src/gtk/dcmemory.cpp index 27dd0e8e9d..95bf5b9a8a 100644 --- a/src/gtk/dcmemory.cpp +++ b/src/gtk/dcmemory.cpp @@ -43,6 +43,7 @@ wxMemoryDC::~wxMemoryDC() void wxMemoryDC::SelectObject( const wxBitmap& bitmap ) { + Destroy(); m_selected = bitmap; if (m_selected.Ok()) { diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 8e9a7d3052..805201a26c 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -615,20 +615,24 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp if (!win->m_hasVMT) return; +/* + if (win->GetName() == wxT("columntitles")) + { + wxPrintf( wxT("OnExpose from ") ); + if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) + wxPrintf( win->GetClassInfo()->GetClassName() ); + wxPrintf( wxT(" %d %d %d %d\n"), (int)gdk_event->area.x, + (int)gdk_event->area.y, + (int)gdk_event->area.width, + (int)gdk_event->area.height ); + } +*/ + win->GetUpdateRegion().Union( gdk_event->area.x, gdk_event->area.y, gdk_event->area.width, gdk_event->area.height ); -/* - wxPrintf( "OnExpose from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - wxPrintf( win->GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x, - (int)gdk_event->area.y, - (int)gdk_event->area.width, - (int)gdk_event->area.height ); -*/ if (gdk_event->count > 0) return; @@ -656,21 +660,21 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), if (g_isIdle) wxapp_install_idle_handler(); - if (!win->m_hasVMT) - return; - - win->GetUpdateRegion().Union( rect->x, rect->y, - rect->width, rect->height ); - /* - wxPrintf( "OnDraw from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - printf( win->GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)rect->x, - (int)rect->y, - (int)rect->width, - (int)rect->height ); + if ((win->GetName() == wxT("columntitles")) && (rect->x == 2)) + { + wxPrintf( wxT("OnDraw from ") ); + if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) + wxPrintf( win->GetClassInfo()->GetClassName() ); + wxPrintf( wxT(" %d %d %d %d\n"), (int)rect->x, + (int)rect->y, + (int)rect->width, + (int)rect->height ); + } */ + + win->GetUpdateRegion().Union( rect->x, rect->y, + rect->width, rect->height ); wxEraseEvent eevent( win->GetId() ); eevent.SetEventObject( win ); @@ -1718,7 +1722,7 @@ gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win ) wxWindowCreateEvent event( win ); event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( event ); - + return FALSE; } diff --git a/src/gtk1/data.cpp b/src/gtk1/data.cpp index 9971508a7b..abf1e939c0 100644 --- a/src/gtk1/data.cpp +++ b/src/gtk1/data.cpp @@ -15,7 +15,11 @@ #include "wx/object.h" #include "wx/window.h" #include "wx/dc.h" + +#if wxUSE_ACCEL #include "wx/accel.h" +#endif + #include "wx/dcps.h" #include "wx/icon.h" diff --git a/src/gtk1/dcclient.cpp b/src/gtk1/dcclient.cpp index 4a06916eef..294e9b890b 100644 --- a/src/gtk1/dcclient.cpp +++ b/src/gtk1/dcclient.cpp @@ -35,6 +35,8 @@ static GdkPixmap *hatches[num_hatches]; static GdkPixmap **hatch_bitmap = (GdkPixmap **) NULL; +extern GtkWidget *wxRootWindow; + //----------------------------------------------------------------------------- // constants //----------------------------------------------------------------------------- @@ -94,6 +96,70 @@ void gdk_draw_bitmap (GdkDrawable *drawable, 1 ); } +//----------------------------------------------------------------------------- +// Implement Pool of Graphic contexts. Creating them takes too much time. +//----------------------------------------------------------------------------- + +struct wxGC +{ + GdkGC *m_gc; + bool m_mono; + bool m_used; +}; + +static wxGC wxGCPool[200]; + +static void wxInitGCPool() +{ + memset( wxGCPool, 0, 200*sizeof(wxGC) ); +} + +static void wxCleanUpGCPool() +{ + for (int i = 0; i < 200; i++) + { + if (wxGCPool[i].m_gc) + gdk_gc_unref( wxGCPool[i].m_gc ); + } +} + +static GdkGC* wxGetPoolGC( GdkWindow *window, bool mono=FALSE ) +{ + for (int i = 0; i < 200; i++) + { + if (!wxGCPool[i].m_gc) + { + wxGCPool[i].m_gc = gdk_gc_new( window ); + gdk_gc_set_exposures( wxGCPool[i].m_gc, FALSE ); + wxGCPool[i].m_mono = mono; + wxGCPool[i].m_used = FALSE; + } + if ((!wxGCPool[i].m_used) && (wxGCPool[i].m_mono == mono)) + { + wxGCPool[i].m_used = TRUE; + return wxGCPool[i].m_gc; + } + } + + wxFAIL_MSG( wxT("No GC available") ); + + return (GdkGC*) NULL; +} + +static void wxFreePoolGC( GdkGC *gc ) +{ + for (int i = 0; i < 200; i++) + { + if (wxGCPool[i].m_gc == gc) + { + wxGCPool[i].m_used = FALSE; + return; + } + } + + wxFAIL_MSG( wxT("Wrong GC") ); +} + //----------------------------------------------------------------------------- // wxWindowDC //----------------------------------------------------------------------------- @@ -525,7 +591,6 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, bool is_mono = (bitmap.GetBitmap() != NULL); /* scale/translate size and position */ - int xx = XLOG2DEV(x); int yy = YLOG2DEV(y); @@ -540,10 +605,17 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, int ww = XLOG2DEVREL(w); int hh = YLOG2DEVREL(h); + /* compare to current clipping region */ + if (!m_currentClippingRegion.IsEmpty()) + { + wxRegion tmp( xx,yy,ww,hh ); + tmp.Intersect( m_currentClippingRegion ); + if (tmp.IsEmpty()) + return; + } + /* scale bitmap if required */ - wxBitmap use_bitmap; - if ((w != ww) || (h != hh)) { wxImage image( bitmap ); @@ -559,23 +631,51 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, } /* apply mask if any */ - GdkBitmap *mask = (GdkBitmap *) NULL; if (use_bitmap.GetMask()) mask = use_bitmap.GetMask()->GetBitmap(); - if (useMask && mask) - { - if (is_mono) - { - gdk_gc_set_clip_mask( m_textGC, mask ); - gdk_gc_set_clip_origin( m_textGC, xx, yy ); - } - else + if (useMask && mask) { - gdk_gc_set_clip_mask( m_penGC, mask ); - gdk_gc_set_clip_origin( m_penGC, xx, yy ); + GdkBitmap *new_mask = (GdkBitmap*) NULL; + if (!m_currentClippingRegion.IsEmpty()) + { + GdkColor col; + new_mask = gdk_pixmap_new( wxRootWindow->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 ); + } + 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 */ @@ -585,18 +685,21 @@ void wxWindowDC::DoDrawBitmap( const wxBitmap &bitmap, gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), 0, 0, xx, yy, -1, -1 ); /* remove mask again if any */ - if (useMask && mask) { if (is_mono) { gdk_gc_set_clip_mask( m_textGC, (GdkBitmap *) NULL ); gdk_gc_set_clip_origin( m_textGC, 0, 0 ); + if (!m_currentClippingRegion.IsEmpty()) + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); } else { gdk_gc_set_clip_mask( m_penGC, (GdkBitmap *) NULL ); gdk_gc_set_clip_origin( m_penGC, 0, 0 ); + if (!m_currentClippingRegion.IsEmpty()) + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } } @@ -666,13 +769,28 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he CalcBoundingBox( xdest, ydest ); CalcBoundingBox( xdest + width, ydest + height ); + /* scale/translate size and position */ + wxCoord xx = XLOG2DEV(xdest); + wxCoord yy = YLOG2DEV(ydest); + + wxCoord ww = XLOG2DEVREL(width); + wxCoord hh = YLOG2DEVREL(height); + + /* compare to current clipping region */ + if (!m_currentClippingRegion.IsEmpty()) + { + wxRegion tmp( xx,yy,ww,hh ); + tmp.Intersect( m_currentClippingRegion ); + if (tmp.IsEmpty()) + return TRUE; + } + int old_logical_func = m_logicalFunction; SetLogicalFunction( logical_func ); if (use_bitmap_method) { /* scale/translate bitmap size */ - wxCoord bm_width = memDC->m_selected.GetWidth(); wxCoord bm_height = memDC->m_selected.GetHeight(); @@ -680,7 +798,6 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he wxCoord bm_hh = YLOG2DEVREL( bm_height ); /* scale bitmap if required */ - wxBitmap use_bitmap; if ((bm_width != bm_ww) || (bm_height != bm_hh)) @@ -698,31 +815,51 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he use_bitmap = memDC->m_selected; } - /* scale/translate size and position */ - - wxCoord xx = XLOG2DEV(xdest); - wxCoord yy = YLOG2DEV(ydest); - - wxCoord ww = XLOG2DEVREL(width); - wxCoord hh = YLOG2DEVREL(height); - /* 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 (!m_currentClippingRegion.IsEmpty()) + { + GdkColor col; + new_mask = gdk_pixmap_new( wxRootWindow->window, bm_ww, bm_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, bm_ww, bm_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, bm_ww, bm_hh ); + gdk_gc_unref( gc ); + } + if (is_mono) { - gdk_gc_set_clip_mask( m_textGC, mask ); + 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 { - gdk_gc_set_clip_mask( m_penGC, mask ); + 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 ); } /* Draw XPixmap or XBitmap, depending on what the wxBitmap contains. For @@ -733,31 +870,26 @@ bool wxWindowDC::DoBlit( wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord he gdk_draw_pixmap( m_window, m_penGC, use_bitmap.GetPixmap(), xsrc, ysrc, xx, yy, ww, hh ); /* remove mask again if any */ - if (useMask && mask) { if (is_mono) { gdk_gc_set_clip_mask( m_textGC, (GdkBitmap *) NULL ); gdk_gc_set_clip_origin( m_textGC, 0, 0 ); + if (!m_currentClippingRegion.IsEmpty()) + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); } else { gdk_gc_set_clip_mask( m_penGC, (GdkBitmap *) NULL ); gdk_gc_set_clip_origin( m_penGC, 0, 0 ); + if (!m_currentClippingRegion.IsEmpty()) + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); } } } else /* use_bitmap_method */ { - /* scale/translate size and position */ - - wxCoord xx = XLOG2DEV(xdest); - wxCoord yy = YLOG2DEV(ydest); - - wxCoord ww = XLOG2DEVREL(width); - wxCoord hh = YLOG2DEVREL(height); - if ((width != ww) || (height != hh)) { /* draw source window into a bitmap as we cannot scale @@ -1309,8 +1441,9 @@ void wxWindowDC::SetLogicalFunction( int function ) gdk_gc_set_function( m_brushGC, mode ); // to stay compatible with wxMSW, we don't apply ROPs to the text - // operations (i.e. DrawText/DrawRotatedText) - // gdk_gc_set_function( m_textGC, mode ); + // operations (i.e. DrawText/DrawRotatedText). + // True, but mono-bitmaps use the m_textGC and they use ROPs as well. + gdk_gc_set_function( m_textGC, mode ); } void wxWindowDC::SetTextForeground( const wxColour &col ) @@ -1374,15 +1507,21 @@ void wxWindowDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoo if (!m_window) return; - GdkRectangle rect; + wxRect rect; rect.x = XLOG2DEV(x); rect.y = YLOG2DEV(y); rect.width = XLOG2DEVREL(width); rect.height = YLOG2DEVREL(height); - gdk_gc_set_clip_rectangle( m_penGC, &rect ); - gdk_gc_set_clip_rectangle( m_brushGC, &rect ); - gdk_gc_set_clip_rectangle( m_textGC, &rect ); - gdk_gc_set_clip_rectangle( m_bgGC, &rect ); + + m_currentClippingRegion.Clear(); + m_currentClippingRegion.Union( rect ); + if (!m_paintClippingRegion.IsEmpty()) + m_currentClippingRegion.Intersect( m_paintClippingRegion ); + + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, m_currentClippingRegion.GetRegion() ); } void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) @@ -1401,11 +1540,16 @@ void wxWindowDC::DoSetClippingRegionAsRegion( const wxRegion ®ion ) wxDC::DoSetClippingRegion( x, y, w, h ); if (!m_window) return; - - gdk_gc_set_clip_region( m_penGC, region.GetRegion() ); - gdk_gc_set_clip_region( m_brushGC, region.GetRegion() ); - gdk_gc_set_clip_region( m_textGC, region.GetRegion() ); - gdk_gc_set_clip_region( m_bgGC, region.GetRegion() ); + + m_currentClippingRegion.Clear(); + m_currentClippingRegion.Union( region ); + if (!m_paintClippingRegion.IsEmpty()) + m_currentClippingRegion.Intersect( m_paintClippingRegion ); + + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, m_currentClippingRegion.GetRegion() ); } void wxWindowDC::DestroyClippingRegion() @@ -1414,52 +1558,92 @@ void wxWindowDC::DestroyClippingRegion() wxDC::DestroyClippingRegion(); + m_currentClippingRegion.Clear(); + + if (!m_paintClippingRegion.IsEmpty()) + m_currentClippingRegion.Union( m_paintClippingRegion ); + if (!m_window) return; - gdk_gc_set_clip_rectangle( m_penGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_brushGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_textGC, (GdkRectangle *) NULL ); - gdk_gc_set_clip_rectangle( m_bgGC, (GdkRectangle *) NULL ); + if (m_currentClippingRegion.IsEmpty()) + { + gdk_gc_set_clip_rectangle( m_penGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_brushGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_textGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_bgGC, (GdkRectangle *) NULL ); + } + else + { + gdk_gc_set_clip_region( m_penGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, m_currentClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, m_currentClippingRegion.GetRegion() ); + } } void wxWindowDC::SetUpDC() { - Destroy(); m_ok = TRUE; - m_logicalFunction = wxCOPY; - m_penGC = gdk_gc_new( m_window ); - m_brushGC = gdk_gc_new( m_window ); - m_textGC = gdk_gc_new( m_window ); - m_bgGC = gdk_gc_new( m_window ); - - wxColour tmp_col( m_textForegroundColour ); - m_textForegroundColour = wxNullColour; - SetTextForeground( tmp_col ); - tmp_col = m_textBackgroundColour; - m_textBackgroundColour = wxNullColour; - SetTextBackground( tmp_col ); - - wxPen tmp_pen( m_pen ); - m_pen = wxNullPen; - SetPen( tmp_pen ); - - wxFont tmp_font( m_font ); - m_font = wxNullFont; - SetFont( tmp_font ); - - wxBrush tmp_brush( m_brush ); - m_brush = wxNullBrush; - SetBrush( tmp_brush ); + + if (!m_penGC) + { + m_penGC = wxGetPoolGC( m_window ); + m_brushGC = wxGetPoolGC( m_window ); + m_textGC = wxGetPoolGC( m_window ); + m_bgGC = wxGetPoolGC( m_window ); + } -/* - tmp_brush = m_backgroundBrush; - m_backgroundBrush = wxNullBrush; - SetBackground( tmp_brush ); -*/ - tmp_brush = m_backgroundBrush; - m_backgroundBrush = wxNullBrush; - SetBackground( *wxWHITE_BRUSH ); - m_backgroundBrush = tmp_brush; + /* background colour */ + m_backgroundBrush = *wxWHITE_BRUSH; + m_backgroundBrush.GetColour().CalcPixel( m_cmap ); + GdkColor *bg_col = m_backgroundBrush.GetColour().GetColor(); + + /* m_textGC */ + m_textForegroundColour.CalcPixel( m_cmap ); + gdk_gc_set_foreground( m_textGC, m_textForegroundColour.GetColor() ); + + m_textBackgroundColour.CalcPixel( m_cmap ); + gdk_gc_set_background( m_textGC, m_textBackgroundColour.GetColor() ); + + gdk_gc_set_fill( m_textGC, GDK_SOLID ); + gdk_gc_set_line_attributes( m_textGC, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND ); + + /* m_penGC */ + m_pen.GetColour().CalcPixel( m_cmap ); + gdk_gc_set_foreground( m_penGC, m_pen.GetColour().GetColor() ); + gdk_gc_set_background( m_penGC, bg_col ); + + gdk_gc_set_fill( m_penGC, GDK_SOLID ); + gdk_gc_set_line_attributes( m_penGC, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND ); + + + /* m_brushGC */ + m_brush.GetColour().CalcPixel( m_cmap ); + gdk_gc_set_foreground( m_brushGC, m_brush.GetColour().GetColor() ); + gdk_gc_set_background( m_brushGC, bg_col ); + + gdk_gc_set_fill( m_brushGC, GDK_SOLID ); + gdk_gc_set_line_attributes( m_brushGC, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND ); + + + /* m_bgGC */ + gdk_gc_set_background( m_bgGC, bg_col ); + gdk_gc_set_foreground( m_bgGC, bg_col ); + + gdk_gc_set_fill( m_bgGC, GDK_SOLID ); + gdk_gc_set_line_attributes( m_bgGC, 0, GDK_LINE_SOLID, GDK_CAP_NOT_LAST, GDK_JOIN_ROUND ); + + /* ROPs */ + gdk_gc_set_function( m_textGC, GDK_COPY ); + gdk_gc_set_function( m_brushGC, GDK_COPY ); + gdk_gc_set_function( m_penGC, GDK_COPY ); + gdk_gc_set_function( m_bgGC, GDK_COPY ); + + /* clipping */ + gdk_gc_set_clip_rectangle( m_penGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_brushGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_textGC, (GdkRectangle *) NULL ); + gdk_gc_set_clip_rectangle( m_bgGC, (GdkRectangle *) NULL ); if (!hatch_bitmap) { @@ -1475,13 +1659,13 @@ void wxWindowDC::SetUpDC() void wxWindowDC::Destroy() { - if (m_penGC) gdk_gc_unref( m_penGC ); + if (m_penGC) wxFreePoolGC( m_penGC ); m_penGC = (GdkGC*) NULL; - if (m_brushGC) gdk_gc_unref( m_brushGC ); + if (m_brushGC) wxFreePoolGC( m_brushGC ); m_brushGC = (GdkGC*) NULL; - if (m_textGC) gdk_gc_unref( m_textGC ); + if (m_textGC) wxFreePoolGC( m_textGC ); m_textGC = (GdkGC*) NULL; - if (m_bgGC) gdk_gc_unref( m_bgGC ); + if (m_bgGC) wxFreePoolGC( m_bgGC ); m_bgGC = (GdkGC*) NULL; } @@ -1702,6 +1886,18 @@ wxPaintDC::wxPaintDC() wxPaintDC::wxPaintDC( wxWindow *win ) : wxWindowDC( win ) { +/* + if (!win->GetUpdateRegion().IsEmpty()) + { + m_paintClippingRegion = win->GetUpdateRegion(); + m_currentClippingRegion.Union( m_paintClippingRegion ); + + gdk_gc_set_clip_region( m_penGC, m_paintClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_brushGC, m_paintClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_textGC, m_paintClippingRegion.GetRegion() ); + gdk_gc_set_clip_region( m_bgGC, m_paintClippingRegion.GetRegion() ); + } +*/ } //----------------------------------------------------------------------------- @@ -1720,3 +1916,29 @@ wxClientDC::wxClientDC( wxWindow *win ) { } +// ---------------------------------------------------------------------------- +// wxDCModule +// ---------------------------------------------------------------------------- + +class wxDCModule : public wxModule +{ +public: + bool OnInit(); + void OnExit(); + +private: + DECLARE_DYNAMIC_CLASS(wxDCModule) +}; + +IMPLEMENT_DYNAMIC_CLASS(wxDCModule, wxModule) + +bool wxDCModule::OnInit() +{ + wxInitGCPool(); + return TRUE; +} + +void wxDCModule::OnExit() +{ + wxCleanUpGCPool(); +} diff --git a/src/gtk1/dcmemory.cpp b/src/gtk1/dcmemory.cpp index 27dd0e8e9d..95bf5b9a8a 100644 --- a/src/gtk1/dcmemory.cpp +++ b/src/gtk1/dcmemory.cpp @@ -43,6 +43,7 @@ wxMemoryDC::~wxMemoryDC() void wxMemoryDC::SelectObject( const wxBitmap& bitmap ) { + Destroy(); m_selected = bitmap; if (m_selected.Ok()) { diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 8e9a7d3052..805201a26c 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -615,20 +615,24 @@ static void gtk_window_expose_callback( GtkWidget *WXUNUSED(widget), GdkEventExp if (!win->m_hasVMT) return; +/* + if (win->GetName() == wxT("columntitles")) + { + wxPrintf( wxT("OnExpose from ") ); + if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) + wxPrintf( win->GetClassInfo()->GetClassName() ); + wxPrintf( wxT(" %d %d %d %d\n"), (int)gdk_event->area.x, + (int)gdk_event->area.y, + (int)gdk_event->area.width, + (int)gdk_event->area.height ); + } +*/ + win->GetUpdateRegion().Union( gdk_event->area.x, gdk_event->area.y, gdk_event->area.width, gdk_event->area.height ); -/* - wxPrintf( "OnExpose from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - wxPrintf( win->GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)gdk_event->area.x, - (int)gdk_event->area.y, - (int)gdk_event->area.width, - (int)gdk_event->area.height ); -*/ if (gdk_event->count > 0) return; @@ -656,21 +660,21 @@ static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), if (g_isIdle) wxapp_install_idle_handler(); - if (!win->m_hasVMT) - return; - - win->GetUpdateRegion().Union( rect->x, rect->y, - rect->width, rect->height ); - /* - wxPrintf( "OnDraw from " ); - if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) - printf( win->GetClassInfo()->GetClassName() ); - wxPrintf( " %d %d %d %d\n", (int)rect->x, - (int)rect->y, - (int)rect->width, - (int)rect->height ); + if ((win->GetName() == wxT("columntitles")) && (rect->x == 2)) + { + wxPrintf( wxT("OnDraw from ") ); + if (win->GetClassInfo() && win->GetClassInfo()->GetClassName()) + wxPrintf( win->GetClassInfo()->GetClassName() ); + wxPrintf( wxT(" %d %d %d %d\n"), (int)rect->x, + (int)rect->y, + (int)rect->width, + (int)rect->height ); + } */ + + win->GetUpdateRegion().Union( rect->x, rect->y, + rect->width, rect->height ); wxEraseEvent eevent( win->GetId() ); eevent.SetEventObject( win ); @@ -1718,7 +1722,7 @@ gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win ) wxWindowCreateEvent event( win ); event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( event ); - + return FALSE; } -- 2.45.2