]> git.saurik.com Git - wxWidgets.git/blame - src/motif/dc.cpp
1. fixes for non-Posix sh in configure
[wxWidgets.git] / src / motif / dc.cpp
CommitLineData
4bb6408c
JS
1/////////////////////////////////////////////////////////////////////////////
2// Name: dc.cpp
3// Purpose: wxDC class
4// Author: Julian Smart
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "dc.h"
14#endif
15
16#include "wx/dc.h"
a367b9b3 17#include "wx/dcmemory.h"
4bb6408c
JS
18
19#if !USE_SHARED_LIBRARY
20IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
21#endif
22
23//-----------------------------------------------------------------------------
24// constants
25//-----------------------------------------------------------------------------
26
27#define mm2inches 0.0393700787402
28#define inches2mm 25.4
29#define mm2twips 56.6929133859
30#define twips2mm 0.0176388888889
31#define mm2pt 2.83464566929
32#define pt2mm 0.352777777778
33
34//-----------------------------------------------------------------------------
35// wxDC
36//-----------------------------------------------------------------------------
37
38wxDC::wxDC(void)
39{
2d120f83
JS
40 m_ok = FALSE;
41 m_optimize = FALSE;
42 m_colour = TRUE;
43 m_clipping = FALSE;
44
45 m_mm_to_pix_x = 1.0;
46 m_mm_to_pix_y = 1.0;
47
48 m_logicalOriginX = 0;
49 m_logicalOriginY = 0;
50 m_deviceOriginX = 0;
51 m_deviceOriginY = 0;
52 m_internalDeviceOriginX = 0;
53 m_internalDeviceOriginY = 0;
54 m_externalDeviceOriginX = 0;
55 m_externalDeviceOriginY = 0;
56
57 m_logicalScaleX = 1.0;
58 m_logicalScaleY = 1.0;
59 m_userScaleX = 1.0;
60 m_userScaleY = 1.0;
61 m_scaleX = 1.0;
62 m_scaleY = 1.0;
63
e3065973 64 m_mappingMode = wxMM_TEXT;
2d120f83
JS
65 m_needComputeScaleX = FALSE;
66 m_needComputeScaleY = FALSE;
67
68 m_signX = 1; // default x-axis left to right
69 m_signY = 1; // default y-axis top down
70
ea6f44b5
RR
71 m_maxX = m_maxY = 0;
72 m_minX = m_minY = 0;
2d120f83
JS
73
74 m_logicalFunction = wxCOPY;
75 // m_textAlignment = wxALIGN_TOP_LEFT;
76 m_backgroundMode = wxTRANSPARENT;
77
78 m_textForegroundColour = *wxBLACK;
79 m_textBackgroundColour = *wxWHITE;
80 m_pen = *wxBLACK_PEN;
81 m_font = *wxNORMAL_FONT;
82 m_brush = *wxTRANSPARENT_BRUSH;
83 m_backgroundBrush = *wxWHITE_BRUSH;
84
85 m_isInteractive = FALSE;
86
87 // m_palette = wxAPP_COLOURMAP;
4bb6408c
JS
88};
89
90wxDC::~wxDC(void)
91{
92};
93
793f619f 94void wxDC::DrawIcon( const wxIcon &WXUNUSED(icon), long WXUNUSED(x), long WXUNUSED(y))
4bb6408c
JS
95{
96};
97
a367b9b3
JS
98void wxDC::DrawBitmap( const wxBitmap& bitmap, long x, long y, bool useMask )
99{
100 if (!bitmap.Ok())
101 return;
2d120f83 102
a367b9b3
JS
103 wxMemoryDC memDC;
104 memDC.SelectObject(bitmap);
2d120f83
JS
105
106 /* Not sure if we need this. The mask should leave the
107 * masked areas as per the original background of this DC.
a367b9b3
JS
108 if (useMask)
109 {
2d120f83
JS
110 // There might be transparent areas, so make these
111 // the same colour as this DC
112 memDC.SetBackground(* GetBackground());
113 memDC.Clear();
a367b9b3 114 }
2d120f83
JS
115 */
116
a367b9b3 117 Blit(x, y, bitmap.GetWidth(), bitmap.GetHeight(), & memDC, 0, 0, wxCOPY, useMask);
2d120f83 118
a367b9b3
JS
119 memDC.SelectObject(wxNullBitmap);
120};
121
122
4bb6408c
JS
123void wxDC::DrawPoint( wxPoint& point )
124{
2d120f83 125 DrawPoint( point.x, point.y );
4bb6408c
JS
126};
127
128void wxDC::DrawPolygon( wxList *list, long xoffset, long yoffset, int fillStyle )
129{
2d120f83
JS
130 int n = list->Number();
131 wxPoint *points = new wxPoint[n];
132
133 int i = 0;
134 for( wxNode *node = list->First(); node; node = node->Next() )
135 {
136 wxPoint *point = (wxPoint *)node->Data();
137 points[i].x = point->x;
138 points[i++].y = point->y;
139 };
140 DrawPolygon( n, points, xoffset, yoffset, fillStyle );
141 delete[] points;
4bb6408c
JS
142};
143
144void wxDC::DrawLines( wxList *list, long xoffset, long yoffset )
145{
2d120f83
JS
146 int n = list->Number();
147 wxPoint *points = new wxPoint[n];
148
149 int i = 0;
150 for( wxNode *node = list->First(); node; node = node->Next() )
151 {
152 wxPoint *point = (wxPoint *)node->Data();
153 points[i].x = point->x;
154 points[i++].y = point->y;
155 };
156 DrawLines( n, points, xoffset, yoffset );
157 delete []points;
4bb6408c
JS
158};
159
160void wxDC::DrawSpline( long x1, long y1, long x2, long y2, long x3, long y3 )
161{
2d120f83
JS
162 wxList list;
163 list.Append( (wxObject*)new wxPoint(x1, y1) );
164 list.Append( (wxObject*)new wxPoint(x2, y2) );
165 list.Append( (wxObject*)new wxPoint(x3, y3) );
166 DrawSpline(&list);
167 wxNode *node = list.First();
168 while (node)
169 {
170 wxPoint *p = (wxPoint*)node->Data();
171 delete p;
172 node = node->Next();
173 };
4bb6408c
JS
174};
175
4bb6408c
JS
176void wxDC::DrawSpline( int n, wxPoint points[] )
177{
2d120f83
JS
178 wxList list;
179 for (int i = 0; i < n; i++) list.Append( (wxObject*)&points[i] );
180 DrawSpline( &list );
4bb6408c
JS
181};
182
183void wxDC::SetClippingRegion( long x, long y, long width, long height )
184{
2d120f83
JS
185 m_clipping = TRUE;
186 m_clipX1 = x;
187 m_clipY1 = y;
188 m_clipX2 = x + width;
189 m_clipY2 = y + height;
4bb6408c
JS
190};
191
192void wxDC::DestroyClippingRegion(void)
193{
2d120f83 194 m_clipping = FALSE;
4bb6408c
JS
195};
196
197void wxDC::GetClippingBox( long *x, long *y, long *width, long *height ) const
198{
2d120f83
JS
199 if (m_clipping)
200 {
201 if (x) *x = m_clipX1;
202 if (y) *y = m_clipY1;
203 if (width) *width = (m_clipX2 - m_clipX1);
204 if (height) *height = (m_clipY2 - m_clipY1);
205 }
206 else
207 *x = *y = *width = *height = 0;
4bb6408c
JS
208};
209
210void wxDC::GetSize( int* width, int* height ) const
211{
2d120f83
JS
212 *width = m_maxX-m_minX;
213 *height = m_maxY-m_minY;
4bb6408c
JS
214};
215
7bcb11d3 216void wxDC::GetSizeMM( int* width, int* height ) const
4bb6408c 217{
2d120f83
JS
218 int w = 0;
219 int h = 0;
220 GetSize( &w, &h );
7bcb11d3
JS
221 *width = int( double(w) / (m_scaleX*m_mm_to_pix_x) );
222 *height = int( double(h) / (m_scaleY*m_mm_to_pix_y) );
4bb6408c
JS
223};
224
7bcb11d3
JS
225// Resolution in pixels per logical inch
226wxSize wxDC::GetPPI(void) const
227{
228 // TODO (should probably be pure virtual)
229 return wxSize(0, 0);
230}
231
4bb6408c
JS
232void wxDC::SetTextForeground( const wxColour &col )
233{
2d120f83
JS
234 if (!Ok()) return;
235 m_textForegroundColour = col;
4bb6408c
JS
236};
237
238void wxDC::SetTextBackground( const wxColour &col )
239{
2d120f83
JS
240 if (!Ok()) return;
241 m_textBackgroundColour = col;
4bb6408c
JS
242};
243
244void wxDC::SetMapMode( int mode )
245{
2d120f83
JS
246 switch (mode)
247 {
e3065973 248 case wxMM_TWIPS:
2d120f83
JS
249 SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
250 break;
e3065973 251 case wxMM_POINTS:
2d120f83
JS
252 SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
253 break;
e3065973 254 case wxMM_METRIC:
2d120f83
JS
255 SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
256 break;
e3065973 257 case wxMM_LOMETRIC:
2d120f83
JS
258 SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
259 break;
4bb6408c 260 default:
e3065973 261 case wxMM_TEXT:
2d120f83
JS
262 SetLogicalScale( 1.0, 1.0 );
263 break;
264 };
e3065973 265 if (mode != wxMM_TEXT)
2d120f83
JS
266 {
267 m_needComputeScaleX = TRUE;
268 m_needComputeScaleY = TRUE;
269 };
4bb6408c
JS
270};
271
272void wxDC::SetUserScale( double x, double y )
273{
2d120f83
JS
274 // allow negative ? -> no
275 m_userScaleX = x;
276 m_userScaleY = y;
277 ComputeScaleAndOrigin();
4bb6408c
JS
278};
279
280void wxDC::GetUserScale( double *x, double *y )
281{
2d120f83
JS
282 if (x) *x = m_userScaleX;
283 if (y) *y = m_userScaleY;
4bb6408c
JS
284};
285
286void wxDC::SetLogicalScale( double x, double y )
287{
2d120f83
JS
288 // allow negative ?
289 m_logicalScaleX = x;
290 m_logicalScaleY = y;
291 ComputeScaleAndOrigin();
4bb6408c
JS
292};
293
294void wxDC::GetLogicalScale( double *x, double *y )
295{
2d120f83
JS
296 if (x) *x = m_logicalScaleX;
297 if (y) *y = m_logicalScaleY;
4bb6408c
JS
298};
299
300void wxDC::SetLogicalOrigin( long x, long y )
301{
2d120f83
JS
302 m_logicalOriginX = x * m_signX; // is this still correct ?
303 m_logicalOriginY = y * m_signY;
304 ComputeScaleAndOrigin();
4bb6408c
JS
305};
306
307void wxDC::GetLogicalOrigin( long *x, long *y )
308{
2d120f83
JS
309 if (x) *x = m_logicalOriginX;
310 if (y) *y = m_logicalOriginY;
4bb6408c
JS
311};
312
313void wxDC::SetDeviceOrigin( long x, long y )
314{
2d120f83
JS
315 m_externalDeviceOriginX = x;
316 m_externalDeviceOriginY = y;
317 ComputeScaleAndOrigin();
4bb6408c
JS
318};
319
320void wxDC::GetDeviceOrigin( long *x, long *y )
321{
2d120f83
JS
322 // if (x) *x = m_externalDeviceOriginX;
323 // if (y) *y = m_externalDeviceOriginY;
324 if (x) *x = m_deviceOriginX;
325 if (y) *y = m_deviceOriginY;
4bb6408c
JS
326};
327
328void wxDC::SetInternalDeviceOrigin( long x, long y )
329{
2d120f83
JS
330 m_internalDeviceOriginX = x;
331 m_internalDeviceOriginY = y;
332 ComputeScaleAndOrigin();
4bb6408c
JS
333};
334
335void wxDC::GetInternalDeviceOrigin( long *x, long *y )
336{
2d120f83
JS
337 if (x) *x = m_internalDeviceOriginX;
338 if (y) *y = m_internalDeviceOriginY;
4bb6408c
JS
339};
340
341void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
342{
2d120f83
JS
343 m_signX = (xLeftRight ? 1 : -1);
344 m_signY = (yBottomUp ? -1 : 1);
345 ComputeScaleAndOrigin();
4bb6408c
JS
346};
347
348long wxDC::DeviceToLogicalX(long x) const
349{
2d120f83 350 return XDEV2LOG(x);
4bb6408c
JS
351};
352
353long wxDC::DeviceToLogicalY(long y) const
354{
2d120f83 355 return YDEV2LOG(y);
4bb6408c
JS
356};
357
358long wxDC::DeviceToLogicalXRel(long x) const
359{
2d120f83 360 return XDEV2LOGREL(x);
4bb6408c
JS
361};
362
363long wxDC::DeviceToLogicalYRel(long y) const
364{
2d120f83 365 return YDEV2LOGREL(y);
4bb6408c
JS
366};
367
368long wxDC::LogicalToDeviceX(long x) const
369{
2d120f83 370 return XLOG2DEV(x);
4bb6408c
JS
371};
372
373long wxDC::LogicalToDeviceY(long y) const
374{
2d120f83 375 return YLOG2DEV(y);
4bb6408c
JS
376};
377
378long wxDC::LogicalToDeviceXRel(long x) const
379{
2d120f83 380 return XLOG2DEVREL(x);
4bb6408c
JS
381};
382
383long wxDC::LogicalToDeviceYRel(long y) const
384{
2d120f83 385 return YLOG2DEVREL(y);
4bb6408c 386};
2d120f83 387
4bb6408c
JS
388void wxDC::CalcBoundingBox( long x, long y )
389{
2d120f83
JS
390 if (x < m_minX) m_minX = x;
391 if (y < m_minY) m_minY = y;
392 if (x > m_maxX) m_maxX = x;
393 if (y > m_maxY) m_maxY = y;
4bb6408c
JS
394};
395
396void wxDC::ComputeScaleAndOrigin(void)
397{
2d120f83
JS
398 // CMB: copy scale to see if it changes
399 double origScaleX = m_scaleX;
400 double origScaleY = m_scaleY;
401
402 m_scaleX = m_logicalScaleX * m_userScaleX;
403 m_scaleY = m_logicalScaleY * m_userScaleY;
404
405 m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
406 m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
407
408 // CMB: if scale has changed call SetPen to recalulate the line width
409 if (m_scaleX != origScaleX || m_scaleY != origScaleY)
410 {
411 // this is a bit artificial, but we need to force wxDC to think
412 // the pen has changed
413 wxPen* pen = & GetPen();
414 wxPen tempPen;
415 m_pen = tempPen;
416 SetPen(* pen);
417 }
4bb6408c
JS
418};
419