]> git.saurik.com Git - wxWidgets.git/blame - src/motif/dc.cpp
Added (untested) support for sub-locales.
[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
64 m_mappingMode = MM_TEXT;
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
71 m_maxX = m_maxY = -100000;
72 m_minY = m_minY = 100000;
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
216void wxDC::GetSizeMM( long* width, long* height ) const
217{
2d120f83
JS
218 int w = 0;
219 int h = 0;
220 GetSize( &w, &h );
221 *width = long( double(w) / (m_scaleX*m_mm_to_pix_x) );
222 *height = long( double(h) / (m_scaleY*m_mm_to_pix_y) );
4bb6408c
JS
223};
224
225void wxDC::SetTextForeground( const wxColour &col )
226{
2d120f83
JS
227 if (!Ok()) return;
228 m_textForegroundColour = col;
4bb6408c
JS
229};
230
231void wxDC::SetTextBackground( const wxColour &col )
232{
2d120f83
JS
233 if (!Ok()) return;
234 m_textBackgroundColour = col;
4bb6408c
JS
235};
236
237void wxDC::SetMapMode( int mode )
238{
2d120f83
JS
239 switch (mode)
240 {
4bb6408c 241 case MM_TWIPS:
2d120f83
JS
242 SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
243 break;
4bb6408c 244 case MM_POINTS:
2d120f83
JS
245 SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
246 break;
4bb6408c 247 case MM_METRIC:
2d120f83
JS
248 SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
249 break;
4bb6408c 250 case MM_LOMETRIC:
2d120f83
JS
251 SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
252 break;
4bb6408c
JS
253 default:
254 case MM_TEXT:
2d120f83
JS
255 SetLogicalScale( 1.0, 1.0 );
256 break;
257 };
258 if (mode != MM_TEXT)
259 {
260 m_needComputeScaleX = TRUE;
261 m_needComputeScaleY = TRUE;
262 };
4bb6408c
JS
263};
264
265void wxDC::SetUserScale( double x, double y )
266{
2d120f83
JS
267 // allow negative ? -> no
268 m_userScaleX = x;
269 m_userScaleY = y;
270 ComputeScaleAndOrigin();
4bb6408c
JS
271};
272
273void wxDC::GetUserScale( double *x, double *y )
274{
2d120f83
JS
275 if (x) *x = m_userScaleX;
276 if (y) *y = m_userScaleY;
4bb6408c
JS
277};
278
279void wxDC::SetLogicalScale( double x, double y )
280{
2d120f83
JS
281 // allow negative ?
282 m_logicalScaleX = x;
283 m_logicalScaleY = y;
284 ComputeScaleAndOrigin();
4bb6408c
JS
285};
286
287void wxDC::GetLogicalScale( double *x, double *y )
288{
2d120f83
JS
289 if (x) *x = m_logicalScaleX;
290 if (y) *y = m_logicalScaleY;
4bb6408c
JS
291};
292
293void wxDC::SetLogicalOrigin( long x, long y )
294{
2d120f83
JS
295 m_logicalOriginX = x * m_signX; // is this still correct ?
296 m_logicalOriginY = y * m_signY;
297 ComputeScaleAndOrigin();
4bb6408c
JS
298};
299
300void wxDC::GetLogicalOrigin( long *x, long *y )
301{
2d120f83
JS
302 if (x) *x = m_logicalOriginX;
303 if (y) *y = m_logicalOriginY;
4bb6408c
JS
304};
305
306void wxDC::SetDeviceOrigin( long x, long y )
307{
2d120f83
JS
308 m_externalDeviceOriginX = x;
309 m_externalDeviceOriginY = y;
310 ComputeScaleAndOrigin();
4bb6408c
JS
311};
312
313void wxDC::GetDeviceOrigin( long *x, long *y )
314{
2d120f83
JS
315 // if (x) *x = m_externalDeviceOriginX;
316 // if (y) *y = m_externalDeviceOriginY;
317 if (x) *x = m_deviceOriginX;
318 if (y) *y = m_deviceOriginY;
4bb6408c
JS
319};
320
321void wxDC::SetInternalDeviceOrigin( long x, long y )
322{
2d120f83
JS
323 m_internalDeviceOriginX = x;
324 m_internalDeviceOriginY = y;
325 ComputeScaleAndOrigin();
4bb6408c
JS
326};
327
328void wxDC::GetInternalDeviceOrigin( long *x, long *y )
329{
2d120f83
JS
330 if (x) *x = m_internalDeviceOriginX;
331 if (y) *y = m_internalDeviceOriginY;
4bb6408c
JS
332};
333
334void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
335{
2d120f83
JS
336 m_signX = (xLeftRight ? 1 : -1);
337 m_signY = (yBottomUp ? -1 : 1);
338 ComputeScaleAndOrigin();
4bb6408c
JS
339};
340
341long wxDC::DeviceToLogicalX(long x) const
342{
2d120f83 343 return XDEV2LOG(x);
4bb6408c
JS
344};
345
346long wxDC::DeviceToLogicalY(long y) const
347{
2d120f83 348 return YDEV2LOG(y);
4bb6408c
JS
349};
350
351long wxDC::DeviceToLogicalXRel(long x) const
352{
2d120f83 353 return XDEV2LOGREL(x);
4bb6408c
JS
354};
355
356long wxDC::DeviceToLogicalYRel(long y) const
357{
2d120f83 358 return YDEV2LOGREL(y);
4bb6408c
JS
359};
360
361long wxDC::LogicalToDeviceX(long x) const
362{
2d120f83 363 return XLOG2DEV(x);
4bb6408c
JS
364};
365
366long wxDC::LogicalToDeviceY(long y) const
367{
2d120f83 368 return YLOG2DEV(y);
4bb6408c
JS
369};
370
371long wxDC::LogicalToDeviceXRel(long x) const
372{
2d120f83 373 return XLOG2DEVREL(x);
4bb6408c
JS
374};
375
376long wxDC::LogicalToDeviceYRel(long y) const
377{
2d120f83 378 return YLOG2DEVREL(y);
4bb6408c 379};
2d120f83 380
4bb6408c
JS
381void wxDC::CalcBoundingBox( long x, long y )
382{
2d120f83
JS
383 if (x < m_minX) m_minX = x;
384 if (y < m_minY) m_minY = y;
385 if (x > m_maxX) m_maxX = x;
386 if (y > m_maxY) m_maxY = y;
4bb6408c
JS
387};
388
389void wxDC::ComputeScaleAndOrigin(void)
390{
2d120f83
JS
391 // CMB: copy scale to see if it changes
392 double origScaleX = m_scaleX;
393 double origScaleY = m_scaleY;
394
395 m_scaleX = m_logicalScaleX * m_userScaleX;
396 m_scaleY = m_logicalScaleY * m_userScaleY;
397
398 m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
399 m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
400
401 // CMB: if scale has changed call SetPen to recalulate the line width
402 if (m_scaleX != origScaleX || m_scaleY != origScaleY)
403 {
404 // this is a bit artificial, but we need to force wxDC to think
405 // the pen has changed
406 wxPen* pen = & GetPen();
407 wxPen tempPen;
408 m_pen = tempPen;
409 SetPen(* pen);
410 }
4bb6408c
JS
411};
412