1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/gtk/dc.cpp
4 // Author: Robert Roebling
6 // Copyright: (c) 1998 Robert Roebling
7 // Licence: wxWindows licence
8 /////////////////////////////////////////////////////////////////////////////
10 // For compilers that support precompilation, includes "wx.h".
11 #include "wx/wxprec.h"
15 #include "wx/window.h"
16 #include "wx/dcclient.h"
17 #include "wx/dcmemory.h"
18 #include "wx/dcscreen.h"
20 #include "wx/gtk/dc.h"
24 wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC
* owner
)
31 wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC
* owner
, int)
38 wxGTKCairoDCImpl::wxGTKCairoDCImpl(wxDC
* owner
, wxWindow
* window
)
42 m_font
= window
->GetFont();
43 m_textForegroundColour
= window
->GetForegroundColour();
44 m_textBackgroundColour
= window
->GetBackgroundColour();
49 void wxGTKCairoDCImpl::DoDrawBitmap(const wxBitmap
& bitmap
, int x
, int y
, bool useMask
)
51 wxCHECK_RET(IsOk(), "invalid DC");
55 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
59 bitmap
.Draw(cr
, x
, y
, useMask
, &m_textForegroundColour
, &m_textBackgroundColour
);
64 void wxGTKCairoDCImpl::DoDrawIcon(const wxIcon
& icon
, int x
, int y
)
66 DoDrawBitmap(icon
, x
, y
, true);
70 bool wxDoFloodFill(wxDC
* dc
, int x
, int y
, const wxColour
& col
, wxFloodFillStyle style
);
72 bool wxGTKCairoDCImpl::DoFloodFill(int x
, int y
, const wxColour
& col
, wxFloodFillStyle style
)
74 return wxDoFloodFill(GetOwner(), x
, y
, col
, style
);
78 wxBitmap
wxGTKCairoDCImpl::DoGetAsBitmap(const wxRect
* /*subrect*/) const
80 wxFAIL_MSG("DoGetAsBitmap not implemented");
84 bool wxGTKCairoDCImpl::DoGetPixel(int x
, int y
, wxColour
* col
) const
90 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
93 cairo_surface_t
* surface
= cairo_get_target(cr
);
94 x
= LogicalToDeviceX(x
);
95 y
= LogicalToDeviceY(y
);
96 GdkPixbuf
* pixbuf
= gdk_pixbuf_get_from_surface(surface
, x
, y
, 1, 1);
99 const guchar
* src
= gdk_pixbuf_get_pixels(pixbuf
);
100 col
->Set(src
[0], src
[1], src
[2]);
101 g_object_unref(pixbuf
);
110 void wxGTKCairoDCImpl::DoGetSize(int* width
, int* height
) const
118 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
)
120 wxCHECK_MSG(IsOk(), false, "invalid DC");
121 wxCHECK_MSG(source
&& source
->IsOk(), false, "invalid source DC");
124 if (m_graphicContext
)
125 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
126 cairo_t
* cr_src
= NULL
;
127 wxGraphicsContext
* gc_src
= source
->GetGraphicsContext();
129 cr_src
= static_cast<cairo_t
*>(gc_src
->GetNativeContext());
131 if (cr
== NULL
|| cr_src
== NULL
)
134 const int xsrc_dev
= source
->LogicalToDeviceX(xsrc
);
135 const int ysrc_dev
= source
->LogicalToDeviceY(ysrc
);
137 cairo_surface_t
* surface
= cairo_get_target(cr_src
);
138 cairo_surface_flush(surface
);
140 cairo_translate(cr
, xdest
, ydest
);
141 cairo_rectangle(cr
, 0, 0, dstWidth
, dstHeight
);
143 source
->GetUserScale(&sx
, &sy
);
144 cairo_scale(cr
, dstWidth
/ (sx
* srcWidth
), dstHeight
/ (sy
* srcHeight
));
145 cairo_set_source_surface(cr
, surface
, -xsrc_dev
, -ysrc_dev
);
146 const wxRasterOperationMode rop_save
= m_logicalFunction
;
147 SetLogicalFunction(rop
);
148 cairo_pattern_set_filter(cairo_get_source(cr
), CAIRO_FILTER_NEAREST
);
149 cairo_surface_t
* maskSurf
= NULL
;
152 const wxBitmap
& bitmap
= source
->GetImpl()->GetSelectedBitmap();
155 wxMask
* mask
= bitmap
.GetMask();
162 int xsrcMask_dev
= xsrc_dev
;
163 int ysrcMask_dev
= ysrc_dev
;
165 xsrcMask_dev
= source
->LogicalToDeviceX(xsrcMask
);
167 ysrcMask_dev
= source
->LogicalToDeviceY(ysrcMask
);
169 cairo_mask_surface(cr
, maskSurf
, -xsrcMask_dev
, -ysrcMask_dev
);
176 m_logicalFunction
= rop_save
;
180 void* wxGTKCairoDCImpl::GetCairoContext() const
183 if (m_graphicContext
)
184 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
189 //-----------------------------------------------------------------------------
191 wxWindowDCImpl::wxWindowDCImpl(wxWindowDC
* owner
, wxWindow
* window
)
192 : base_type(owner
, window
)
194 GtkWidget
* widget
= window
->m_wxwindow
;
196 widget
= window
->m_widget
;
197 GdkWindow
* gdkWindow
= NULL
;
200 gdkWindow
= gtk_widget_get_window(widget
);
205 cairo_t
* cr
= gdk_cairo_create(gdkWindow
);
206 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
208 gtk_widget_get_allocation(widget
, &a
);
210 if (gtk_widget_get_has_window(widget
))
212 m_width
= gdk_window_get_width(gdkWindow
);
213 m_height
= gdk_window_get_height(gdkWindow
);
214 x
= m_width
- a
.width
;
215 y
= m_height
- a
.height
;
223 cairo_rectangle(cr
, a
.x
, a
.y
, a
.width
, a
.height
);
227 SetDeviceLocalOrigin(x
, y
);
230 SetGraphicsContext(wxGraphicsContext::Create());
232 //-----------------------------------------------------------------------------
234 wxClientDCImpl::wxClientDCImpl(wxClientDC
* owner
, wxWindow
* window
)
235 : base_type(owner
, window
)
237 GtkWidget
* widget
= window
->m_wxwindow
;
239 widget
= window
->m_widget
;
240 GdkWindow
* gdkWindow
= NULL
;
243 gdkWindow
= gtk_widget_get_window(widget
);
248 cairo_t
* cr
= gdk_cairo_create(gdkWindow
);
249 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
250 if (gtk_widget_get_has_window(widget
))
252 m_width
= gdk_window_get_width(gdkWindow
);
253 m_height
= gdk_window_get_height(gdkWindow
);
258 gtk_widget_get_allocation(widget
, &a
);
261 cairo_rectangle(cr
, a
.x
, a
.y
, a
.width
, a
.height
);
263 SetDeviceLocalOrigin(a
.x
, a
.y
);
267 SetGraphicsContext(wxGraphicsContext::Create());
269 //-----------------------------------------------------------------------------
271 wxPaintDCImpl::wxPaintDCImpl(wxPaintDC
* owner
, wxWindow
* window
)
272 : base_type(owner
, window
)
274 cairo_t
* cr
= window
->GTKPaintContext();
275 wxCHECK_RET(cr
, "using wxPaintDC without being in a native paint event");
276 GdkWindow
* gdkWindow
= gtk_widget_get_window(window
->m_wxwindow
);
277 m_width
= gdk_window_get_width(gdkWindow
);
278 m_height
= gdk_window_get_height(gdkWindow
);
280 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
282 //-----------------------------------------------------------------------------
284 wxScreenDCImpl::wxScreenDCImpl(wxScreenDC
* owner
)
285 : base_type(owner
, 0)
287 GdkWindow
* window
= gdk_get_default_root_window();
288 m_width
= gdk_window_get_width(window
);
289 m_height
= gdk_window_get_height(window
);
290 cairo_t
* cr
= gdk_cairo_create(window
);
291 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
293 //-----------------------------------------------------------------------------
295 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
)
301 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
, wxBitmap
& bitmap
)
302 : base_type(owner
, 0)
308 wxMemoryDCImpl::wxMemoryDCImpl(wxMemoryDC
* owner
, wxDC
*)
314 wxBitmap
wxMemoryDCImpl::DoGetAsBitmap(const wxRect
* subrect
) const
316 return subrect
? m_bitmap
.GetSubBitmap(*subrect
) : m_bitmap
;
319 void wxMemoryDCImpl::DoSelect(const wxBitmap
& bitmap
)
325 const wxBitmap
& wxMemoryDCImpl::GetSelectedBitmap() const
330 wxBitmap
& wxMemoryDCImpl::GetSelectedBitmap()
335 void wxMemoryDCImpl::Setup()
337 wxGraphicsContext
* gc
= NULL
;
338 m_ok
= m_bitmap
.IsOk();
341 m_width
= m_bitmap
.GetWidth();
342 m_height
= m_bitmap
.GetHeight();
343 cairo_t
* cr
= m_bitmap
.CairoCreate();
344 gc
= wxGraphicsContext::CreateFromNative(cr
);
346 SetGraphicsContext(gc
);
348 //-----------------------------------------------------------------------------
350 wxGTKCairoDC::wxGTKCairoDC(cairo_t
* cr
)
351 : base_type(new wxGTKCairoDCImpl(this, 0))
354 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
359 #include "wx/gtk/dc.h"
361 //-----------------------------------------------------------------------------
363 //-----------------------------------------------------------------------------
365 IMPLEMENT_ABSTRACT_CLASS(wxGTKDCImpl
, wxDCImpl
)
367 wxGTKDCImpl::wxGTKDCImpl( wxDC
*owner
)
372 m_pen
= *wxBLACK_PEN
;
373 m_font
= *wxNORMAL_FONT
;
374 m_brush
= *wxWHITE_BRUSH
;
377 wxGTKDCImpl::~wxGTKDCImpl()
381 void wxGTKDCImpl::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
386 m_clipX2
= x
+ width
;
387 m_clipY2
= y
+ height
;
390 // ---------------------------------------------------------------------------
391 // get DC capabilities
392 // ---------------------------------------------------------------------------
394 void wxGTKDCImpl::DoGetSizeMM( int* width
, int* height
) const
398 GetOwner()->GetSize( &w
, &h
);
399 if (width
) *width
= int( double(w
) / (m_userScaleX
*m_mm_to_pix_x
) );
400 if (height
) *height
= int( double(h
) / (m_userScaleY
*m_mm_to_pix_y
) );
403 // Resolution in pixels per logical inch
404 wxSize
wxGTKDCImpl::GetPPI() const
406 // TODO (should probably be pure virtual)