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
, wxWindow
* window
)
35 m_font
= window
->GetFont();
36 m_textForegroundColour
= window
->GetForegroundColour();
37 m_textBackgroundColour
= window
->GetBackgroundColour();
42 void wxGTKCairoDCImpl::DoDrawBitmap(const wxBitmap
& bitmap
, int x
, int y
, bool useMask
)
44 wxCHECK_RET(IsOk(), "invalid DC");
48 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
52 bitmap
.Draw(cr
, x
, y
, useMask
, &m_textForegroundColour
, &m_textBackgroundColour
);
57 void wxGTKCairoDCImpl::DoDrawIcon(const wxIcon
& icon
, int x
, int y
)
59 DoDrawBitmap(icon
, x
, y
, true);
63 bool wxDoFloodFill(wxDC
* dc
, int x
, int y
, const wxColour
& col
, wxFloodFillStyle style
);
65 bool wxGTKCairoDCImpl::DoFloodFill(int x
, int y
, const wxColour
& col
, wxFloodFillStyle style
)
67 return wxDoFloodFill(GetOwner(), x
, y
, col
, style
);
71 wxBitmap
wxGTKCairoDCImpl::DoGetAsBitmap(const wxRect
* /*subrect*/) const
73 wxFAIL_MSG("DoGetAsBitmap not implemented");
77 bool wxGTKCairoDCImpl::DoGetPixel(int x
, int y
, wxColour
* col
) const
83 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
86 cairo_surface_t
* surface
= cairo_get_target(cr
);
87 x
= LogicalToDeviceX(x
);
88 y
= LogicalToDeviceY(y
);
89 GdkPixbuf
* pixbuf
= gdk_pixbuf_get_from_surface(surface
, x
, y
, 1, 1);
92 const guchar
* src
= gdk_pixbuf_get_pixels(pixbuf
);
93 col
->Set(src
[0], src
[1], src
[2]);
94 g_object_unref(pixbuf
);
103 void wxGTKCairoDCImpl::DoGetSize(int* width
, int* height
) const
111 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
)
113 wxCHECK_MSG(IsOk(), false, "invalid DC");
114 wxCHECK_MSG(source
&& source
->IsOk(), false, "invalid source DC");
117 if (m_graphicContext
)
118 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
119 cairo_t
* cr_src
= NULL
;
120 wxGraphicsContext
* gc_src
= source
->GetGraphicsContext();
122 cr_src
= static_cast<cairo_t
*>(gc_src
->GetNativeContext());
124 if (cr
== NULL
|| cr_src
== NULL
)
127 const int xsrc_dev
= source
->LogicalToDeviceX(xsrc
);
128 const int ysrc_dev
= source
->LogicalToDeviceY(ysrc
);
130 cairo_surface_t
* surface
= cairo_get_target(cr_src
);
131 cairo_surface_flush(surface
);
133 cairo_translate(cr
, xdest
, ydest
);
134 cairo_rectangle(cr
, 0, 0, dstWidth
, dstHeight
);
136 source
->GetUserScale(&sx
, &sy
);
137 cairo_scale(cr
, dstWidth
/ (sx
* srcWidth
), dstHeight
/ (sy
* srcHeight
));
138 cairo_set_source_surface(cr
, surface
, -xsrc_dev
, -ysrc_dev
);
139 const wxRasterOperationMode rop_save
= m_logicalFunction
;
140 SetLogicalFunction(rop
);
141 cairo_pattern_set_filter(cairo_get_source(cr
), CAIRO_FILTER_NEAREST
);
142 cairo_surface_t
* maskSurf
= NULL
;
145 const wxBitmap
& bitmap
= source
->GetImpl()->GetSelectedBitmap();
148 wxMask
* mask
= bitmap
.GetMask();
150 maskSurf
= mask
->GetBitmap();
155 int xsrcMask_dev
= xsrc_dev
;
156 int ysrcMask_dev
= ysrc_dev
;
158 xsrcMask_dev
= source
->LogicalToDeviceX(xsrcMask
);
160 ysrcMask_dev
= source
->LogicalToDeviceY(ysrcMask
);
162 cairo_mask_surface(cr
, maskSurf
, -xsrcMask_dev
, -ysrcMask_dev
);
169 m_logicalFunction
= rop_save
;
173 void* wxGTKCairoDCImpl::GetCairoContext() const
176 if (m_graphicContext
)
177 cr
= static_cast<cairo_t
*>(m_graphicContext
->GetNativeContext());
182 //-----------------------------------------------------------------------------
184 wxWindowDCImpl::wxWindowDCImpl(wxWindowDC
* owner
, wxWindow
* window
)
185 : base_type(owner
, window
)
187 GtkWidget
* widget
= window
->m_wxwindow
;
189 widget
= window
->m_widget
;
190 GdkWindow
* gdkWindow
= NULL
;
193 gdkWindow
= gtk_widget_get_window(widget
);
198 cairo_t
* cr
= gdk_cairo_create(gdkWindow
);
199 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
201 gtk_widget_get_allocation(widget
, &a
);
203 if (gtk_widget_get_has_window(widget
))
205 m_width
= gdk_window_get_width(gdkWindow
);
206 m_height
= gdk_window_get_height(gdkWindow
);
207 x
= m_width
- a
.width
;
208 y
= m_height
- a
.height
;
216 cairo_rectangle(cr
, a
.x
, a
.y
, a
.width
, a
.height
);
220 SetDeviceLocalOrigin(x
, y
);
223 //-----------------------------------------------------------------------------
225 wxClientDCImpl::wxClientDCImpl(wxClientDC
* owner
, wxWindow
* window
)
226 : base_type(owner
, window
)
228 GtkWidget
* widget
= window
->m_wxwindow
;
230 widget
= window
->m_widget
;
231 GdkWindow
* gdkWindow
= NULL
;
234 gdkWindow
= gtk_widget_get_window(widget
);
239 cairo_t
* cr
= gdk_cairo_create(gdkWindow
);
240 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
241 if (gtk_widget_get_has_window(widget
))
243 m_width
= gdk_window_get_width(gdkWindow
);
244 m_height
= gdk_window_get_height(gdkWindow
);
249 gtk_widget_get_allocation(widget
, &a
);
252 cairo_rectangle(cr
, a
.x
, a
.y
, a
.width
, a
.height
);
254 SetDeviceLocalOrigin(a
.x
, a
.y
);
259 // create something that can be used for measuring, but not drawing
260 cairo_t
* cr
= gdk_cairo_create(gdk_get_default_root_window());
261 cairo_rectangle(cr
, 0, 0, 0, 0);
263 SetGraphicsContext(wxGraphicsContext::CreateFromNative(cr
));
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
)
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
)
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))
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)