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