1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/dc.cpp
4 // Author: Robert Roebling
5 // Copyright: (c) 1998 Robert Roebling
6 // Licence: wxWindows licence
7 /////////////////////////////////////////////////////////////////////////////
9 // For compilers that support precompilation, includes "wx.h".
10 #include "wx/wxprec.h"
14 #include "wx/window.h"
15 #include "wx/dcclient.h"
16 #include "wx/dcmemory.h"
17 #include "wx/dcscreen.h"
19 #include "wx/gtk/dc.h"
23 wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC
* owner
)
30 wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC
* owner
, int)
37 wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC
* owner
, wxWindow
* window
)
41 m_font
= window
->GetFont();
42 m_textForegroundColour
= window
->GetForegroundColour();
43 m_textBackgroundColour
= window
->GetBackgroundColour();
48 void wxGTKCairoDCImpl::DoDrawBitmap(const wxBitmap
& bitmap
, int x
, int y
, bool useMask
)
50 wxCHECK_RET(IsOk(), "invalid DC");
54 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
58 bitmap
.Draw(cr
, x
, y
, useMask
, &m_textForegroundColour
, &m_textBackgroundColour
);
63 void wxGTKCairoDCImpl::DoDrawIcon(const wxIcon
& icon
, int x
, int y
)
65 DoDrawBitmap(icon
, x
, y
, true);
69 bool wxDoFloodFill(wxDC
* dc
, int x
, int y
, const wxColour
& col
, wxFloodFillStyle style
);
71 bool wxGTKCairoDCImpl::DoFloodFill(int x
, int y
, const wxColour
& col
, wxFloodFillStyle style
)
73 return wxDoFloodFill(GetOwner(), x
, y
, col
, style
);
77 wxBitmap
wxGTKCairoDCImpl::DoGetAsBitmap(const wxRect
* /*subrect*/) const
79 wxFAIL_MSG("DoGetAsBitmap not implemented");
83 bool wxGTKCairoDCImpl::DoGetPixel(int x
, int y
, wxColour
* col
) const
89 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
92 cairo_surface_t
* surface
= cairo_get_target(cr
);
93 x
= LogicalToDeviceX(x
);
94 y
= LogicalToDeviceY(y
);
95 GdkPixbuf
* pixbuf
= gdk_pixbuf_get_from_surface(surface
, x
, y
, 1, 1);
98 const guchar
* src
= gdk_pixbuf_get_pixels(pixbuf
);
99 col
->Set(src
[0], src
[1], src
[2]);
100 g_object_unref(pixbuf
);
109 void wxGTKCairoDCImpl::DoGetSize(int* width
, int* height
) const
117 bool wxGTKCairoDCImpl::DoStretchBlit(int xdest
, int ydest
, int dstWidth
, int dstHeight
, wxDC
* source
, int xsrc
, int ysrc
, int srcWidth
, int srcHeight
, wxRasterOperationMode rop
, bool useMask
, int xsrcMask
, int ysrcMask
)
119 wxCHECK_MSG(IsOk(), false, "invalid DC");
120 wxCHECK_MSG(source
&& source
->IsOk(), false, "invalid source DC");
123 if (m_graphicContext
)
124 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
125 cairo_t
* cr_src
= NULL
;
126 wxGraphicsContext
* gc_src
= source
->GetGraphicsContext();
128 cr_src
= static_cast<cairo_t
*>(gc_src
->GetNativeContext());
130 if (cr
== NULL
|| cr_src
== NULL
)
133 const int xsrc_dev
= source
->LogicalToDeviceX(xsrc
);
134 const int ysrc_dev
= source
->LogicalToDeviceY(ysrc
);
136 cairo_surface_t
* surface
= cairo_get_target(cr_src
);
137 cairo_surface_flush(surface
);
139 cairo_translate(cr
, xdest
, ydest
);
140 cairo_rectangle(cr
, 0, 0, dstWidth
, dstHeight
);
142 source
->GetUserScale(&sx
, &sy
);
143 cairo_scale(cr
, dstWidth
/ (sx
* srcWidth
), dstHeight
/ (sy
* srcHeight
));
144 cairo_set_source_surface(cr
, surface
, -xsrc_dev
, -ysrc_dev
);
145 const wxRasterOperationMode rop_save
= m_logicalFunction
;
146 SetLogicalFunction(rop
);
147 cairo_pattern_set_filter(cairo_get_source(cr
), CAIRO_FILTER_NEAREST
);
148 cairo_surface_t
* maskSurf
= NULL
;
151 const wxBitmap
& bitmap
= source
->GetImpl()->GetSelectedBitmap();
154 wxMask
* mask
= bitmap
.GetMask();
161 int xsrcMask_dev
= xsrc_dev
;
162 int ysrcMask_dev
= ysrc_dev
;
164 xsrcMask_dev
= source
->LogicalToDeviceX(xsrcMask
);
166 ysrcMask_dev
= source
->LogicalToDeviceY(ysrcMask
);
168 cairo_mask_surface(cr
, maskSurf
, -xsrcMask_dev
, -ysrcMask_dev
);
175 m_logicalFunction
= rop_save
;
179 void* wxGTKCairoDCImpl::GetCairoContext() const
182 if (m_graphicContext
)
183 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
186 //-----------------------------------------------------------------------------
188 wxWindowDCImpl::wxWindowDCImpl(wxWindowDC
* owner
, wxWindow
* window
)
189 : base_type(owner
, window
)
191 GtkWidget
* widget
= window
->m_wxwindow
;
193 widget
= window
->m_widget
;
194 GdkWindow
* gdkWindow
= NULL
;
197 gdkWindow
= gtk_widget_get_window(widget
);
202 cairo_t
* cr
= gdk_cairo_create(gdkWindow
);
203 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
205 gtk_widget_get_allocation(widget
, &a
);
207 if (gtk_widget_get_has_window(widget
))
209 m_width
= gdk_window_get_width(gdkWindow
);
210 m_height
= gdk_window_get_height(gdkWindow
);
211 x
= m_width
- a
.width
;
212 y
= m_height
- a
.height
;
220 cairo_rectangle(cr
, a
.x
, a
.y
, a
.width
, a
.height
);
224 SetDeviceLocalOrigin(x
, y
);
227 SetGraphicsContext(wxGraphicsContext::Create());
229 //-----------------------------------------------------------------------------
231 wxClientDCImpl::wxClientDCImpl(wxClientDC
* owner
, wxWindow
* window
)
232 : base_type(owner
, window
)
234 GtkWidget
* widget
= window
->m_wxwindow
;
236 widget
= window
->m_widget
;
237 GdkWindow
* gdkWindow
= NULL
;
240 gdkWindow
= gtk_widget_get_window(widget
);
245 cairo_t
* cr
= gdk_cairo_create(gdkWindow
);
246 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
247 if (gtk_widget_get_has_window(widget
))
249 m_width
= gdk_window_get_width(gdkWindow
);
250 m_height
= gdk_window_get_height(gdkWindow
);
255 gtk_widget_get_allocation(widget
, &a
);
258 cairo_rectangle(cr
, a
.x
, a
.y
, a
.width
, a
.height
);
260 SetDeviceLocalOrigin(a
.x
, a
.y
);
264 SetGraphicsContext(wxGraphicsContext::Create());
266 //-----------------------------------------------------------------------------
268 wxPaintDCImpl::wxPaintDCImpl(wxPaintDC
* owner
, wxWindow
* window
)
269 : base_type(owner
, window
)
271 cairo_t
* cr
= window
->GTKPaintContext();
272 wxCHECK_RET(cr
, "using wxPaintDC without being in a native paint event");
273 GdkWindow
* gdkWindow
= gtk_widget_get_window(window
->m_wxwindow
);
274 m_width
= gdk_window_get_width(gdkWindow
);
275 m_height
= gdk_window_get_height(gdkWindow
);
277 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
279 //-----------------------------------------------------------------------------
281 wxScreenDCImpl::wxScreenDCImpl(wxScreenDC
* owner
)
282 : base_type(owner
, 0)
284 GdkWindow
* window
= gdk_get_default_root_window();
285 m_width
= gdk_window_get_width(window
);
286 m_height
= gdk_window_get_height(window
);
287 cairo_t
* cr
= gdk_cairo_create(window
);
288 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
290 //-----------------------------------------------------------------------------
292 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
)
298 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
, wxBitmap
& bitmap
)
299 : base_type(owner
, 0)
305 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
, wxDC
*)
311 wxBitmap
wxMemoryDCImpl::DoGetAsBitmap(const wxRect
* subrect
) const
313 return subrect
? m_bitmap
.GetSubBitmap(*subrect
) : m_bitmap
;
316 void wxMemoryDCImpl::DoSelect(const wxBitmap
& bitmap
)
322 const wxBitmap
& wxMemoryDCImpl::GetSelectedBitmap() const
327 wxBitmap
& wxMemoryDCImpl::GetSelectedBitmap()
332 void wxMemoryDCImpl::Setup()
334 wxGraphicsContext
* gc
= NULL
;
335 m_ok
= m_bitmap
.IsOk();
338 m_width
= m_bitmap
.GetWidth();
339 m_height
= m_bitmap
.GetHeight();
340 cairo_t
* cr
= m_bitmap
.CairoCreate();
341 gc
= wxGraphicsContext::CreateFromNative(cr
);
343 SetGraphicsContext(gc
);
345 //-----------------------------------------------------------------------------
347 wxGTKCairoDC::wxGTKCairoDC(cairo_t
* cr
)
348 : base_type(new wxGTKCairoDCImpl(this, 0))
351 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
356 #include "wx/gtk/dc.h"
358 //-----------------------------------------------------------------------------
360 //-----------------------------------------------------------------------------
362 IMPLEMENT_ABSTRACT_CLASS(wxGTKDCImpl
, wxDCImpl
)
364 wxGTKDCImpl::wxGTKDCImpl( wxDC
*owner
)
369 m_pen
= *wxBLACK_PEN
;
370 m_font
= *wxNORMAL_FONT
;
371 m_brush
= *wxWHITE_BRUSH
;
374 wxGTKDCImpl::~wxGTKDCImpl()
378 void wxGTKDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
383 m_clipX2
= x
+ width
;
384 m_clipY2
= y
+ height
;
387 // ---------------------------------------------------------------------------
388 // get DC capabilities
389 // ---------------------------------------------------------------------------
391 void wxGTKDCImpl::DoGetSizeMM( int* width
, int* height
) const
395 GetOwner()->GetSize( &w
, &h
);
396 if (width
) *width
= int( double(w
) / (m_userScaleX
*m_mm_to_pix_x
) );
397 if (height
) *height
= int( double(h
) / (m_userScaleY
*m_mm_to_pix_y
) );
400 // Resolution in pixels per logical inch
401 wxSize
wxGTKDCImpl::GetPPI() const
403 // TODO (should probably be pure virtual)