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());
188 //-----------------------------------------------------------------------------
190 wxWindowDCImpl::wxWindowDCImpl(wxWindowDC
* owner
, wxWindow
* window
)
191 : base_type(owner
, window
)
193 GtkWidget
* widget
= window
->m_wxwindow
;
195 widget
= window
->m_widget
;
196 GdkWindow
* gdkWindow
= NULL
;
199 gdkWindow
= gtk_widget_get_window(widget
);
204 cairo_t
* cr
= gdk_cairo_create(gdkWindow
);
205 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
207 gtk_widget_get_allocation(widget
, &a
);
209 if (gtk_widget_get_has_window(widget
))
211 m_width
= gdk_window_get_width(gdkWindow
);
212 m_height
= gdk_window_get_height(gdkWindow
);
213 x
= m_width
- a
.width
;
214 y
= m_height
- a
.height
;
222 cairo_rectangle(cr
, a
.x
, a
.y
, a
.width
, a
.height
);
226 SetDeviceLocalOrigin(x
, y
);
229 SetGraphicsContext(wxGraphicsContext::Create());
231 //-----------------------------------------------------------------------------
233 wxClientDCImpl::wxClientDCImpl(wxClientDC
* owner
, wxWindow
* window
)
234 : base_type(owner
, window
)
236 GtkWidget
* widget
= window
->m_wxwindow
;
238 widget
= window
->m_widget
;
239 GdkWindow
* gdkWindow
= NULL
;
242 gdkWindow
= gtk_widget_get_window(widget
);
247 cairo_t
* cr
= gdk_cairo_create(gdkWindow
);
248 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
249 if (gtk_widget_get_has_window(widget
))
251 m_width
= gdk_window_get_width(gdkWindow
);
252 m_height
= gdk_window_get_height(gdkWindow
);
257 gtk_widget_get_allocation(widget
, &a
);
260 cairo_rectangle(cr
, a
.x
, a
.y
, a
.width
, a
.height
);
262 SetDeviceLocalOrigin(a
.x
, a
.y
);
266 SetGraphicsContext(wxGraphicsContext::Create());
268 //-----------------------------------------------------------------------------
270 wxPaintDCImpl::wxPaintDCImpl(wxPaintDC
* owner
, wxWindow
* window
)
271 : base_type(owner
, window
)
273 cairo_t
* cr
= window
->GTKPaintContext();
274 wxCHECK_RET(cr
, "using wxPaintDC without being in a native paint event");
275 GdkWindow
* gdkWindow
= gtk_widget_get_window(window
->m_wxwindow
);
276 m_width
= gdk_window_get_width(gdkWindow
);
277 m_height
= gdk_window_get_height(gdkWindow
);
279 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
281 //-----------------------------------------------------------------------------
283 wxScreenDCImpl::wxScreenDCImpl(wxScreenDC
* owner
)
284 : base_type(owner
, 0)
286 GdkWindow
* window
= gdk_get_default_root_window();
287 m_width
= gdk_window_get_width(window
);
288 m_height
= gdk_window_get_height(window
);
289 cairo_t
* cr
= gdk_cairo_create(window
);
290 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
292 //-----------------------------------------------------------------------------
294 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
)
300 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
, wxBitmap
& bitmap
)
301 : base_type(owner
, 0)
307 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
, wxDC
*)
313 wxBitmap
wxMemoryDCImpl::DoGetAsBitmap(const wxRect
* subrect
) const
315 return subrect
? m_bitmap
.GetSubBitmap(*subrect
) : m_bitmap
;
318 void wxMemoryDCImpl::DoSelect(const wxBitmap
& bitmap
)
324 const wxBitmap
& wxMemoryDCImpl::GetSelectedBitmap() const
329 wxBitmap
& wxMemoryDCImpl::GetSelectedBitmap()
334 void wxMemoryDCImpl::Setup()
336 wxGraphicsContext
* gc
= NULL
;
337 m_ok
= m_bitmap
.IsOk();
340 m_width
= m_bitmap
.GetWidth();
341 m_height
= m_bitmap
.GetHeight();
342 cairo_t
* cr
= m_bitmap
.CairoCreate();
343 gc
= wxGraphicsContext::CreateFromNative(cr
);
345 SetGraphicsContext(gc
);
347 //-----------------------------------------------------------------------------
349 wxGTKCairoDC::wxGTKCairoDC(cairo_t
* cr
)
350 : base_type(new wxGTKCairoDCImpl(this, 0))
353 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
358 #include "wx/gtk/dc.h"
360 //-----------------------------------------------------------------------------
362 //-----------------------------------------------------------------------------
364 IMPLEMENT_ABSTRACT_CLASS(wxGTKDCImpl
, wxDCImpl
)
366 wxGTKDCImpl::wxGTKDCImpl( wxDC
*owner
)
371 m_pen
= *wxBLACK_PEN
;
372 m_font
= *wxNORMAL_FONT
;
373 m_brush
= *wxWHITE_BRUSH
;
376 wxGTKDCImpl::~wxGTKDCImpl()
380 void wxGTKDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
385 m_clipX2
= x
+ width
;
386 m_clipY2
= y
+ height
;
389 // ---------------------------------------------------------------------------
390 // get DC capabilities
391 // ---------------------------------------------------------------------------
393 void wxGTKDCImpl::DoGetSizeMM( int* width
, int* height
) const
397 GetOwner()->GetSize( &w
, &h
);
398 if (width
) *width
= int( double(w
) / (m_userScaleX
*m_mm_to_pix_x
) );
399 if (height
) *height
= int( double(h
) / (m_userScaleY
*m_mm_to_pix_y
) );
402 // Resolution in pixels per logical inch
403 wxSize
wxGTKDCImpl::GetPPI() const
405 // TODO (should probably be pure virtual)