]> git.saurik.com Git - wxWidgets.git/blame - src/common/dcbase.cpp
Implemented (for GTK+) and tested dataview_context_menu event
[wxWidgets.git] / src / common / dcbase.cpp
CommitLineData
dbe94982 1/////////////////////////////////////////////////////////////////////////////
06052f3f 2// Name: src/common/dcbase.cpp
1e6feb95
VZ
3// Purpose: generic methods of the wxDC Class
4// Author: Vadim Zeitlin
dbe94982
BM
5// Modified by:
6// Created: 05/25/99
7// RCS-ID: $Id$
77ffb593 8// Copyright: (c) wxWidgets team
65571936 9// Licence: wxWindows licence
dbe94982
BM
10/////////////////////////////////////////////////////////////////////////////
11
1e6feb95
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
1e6feb95
VZ
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
dbe94982
BM
20// For compilers that support precompilation, includes "wx.h".
21#include "wx/wxprec.h"
22
23#ifdef __BORLANDC__
bd1e9c12 24 #pragma hdrstop
dbe94982
BM
25#endif
26
dbe94982 27#include "wx/dc.h"
ab171e95
RR
28#include "wx/dcclient.h"
29#include "wx/dcmemory.h"
30#include "wx/dcscreen.h"
4f37154e 31#include "wx/dcprint.h"
4f37154e 32#include "wx/prntbase.h"
18680f86
WS
33
34#ifndef WX_PRECOMP
35 #include "wx/math.h"
f2498c4e 36 #include "wx/module.h"
18680f86 37#endif
dbe94982 38
888dde65 39#ifdef __WXMSW__
f2498c4e
VZ
40 #include "wx/msw/dcclient.h"
41 #include "wx/msw/dcmemory.h"
42 #include "wx/msw/dcscreen.h"
888dde65 43#endif
2970ae54 44
10d30222 45#ifdef __WXGTK20__
f2498c4e
VZ
46 #include "wx/gtk/dcclient.h"
47 #include "wx/gtk/dcmemory.h"
48 #include "wx/gtk/dcscreen.h"
10d30222
VZ
49#elif defined(__WXGTK__)
50 #include "wx/gtk1/dcclient.h"
51 #include "wx/gtk1/dcmemory.h"
52 #include "wx/gtk1/dcscreen.h"
888dde65
RR
53#endif
54
55#ifdef __WXMAC__
f2498c4e
VZ
56 #include "wx/mac/dcclient.h"
57 #include "wx/mac/dcmemory.h"
58 #include "wx/mac/dcscreen.h"
888dde65 59#endif
2970ae54 60
938156b2
DE
61#ifdef __WXCOCOA__
62 #include "wx/cocoa/dcclient.h"
63 #include "wx/cocoa/dcmemory.h"
64 #include "wx/cocoa/dcscreen.h"
65#endif
66
fce127d7
VZ
67#ifdef __WXMOTIF__
68 #include "wx/motif/dcclient.h"
69 #include "wx/motif/dcmemory.h"
70 #include "wx/motif/dcscreen.h"
71#endif
72
e6514d0e 73#ifdef __WXX11__
f2498c4e
VZ
74 #include "wx/x11/dcclient.h"
75 #include "wx/x11/dcmemory.h"
76 #include "wx/x11/dcscreen.h"
e6514d0e
RR
77#endif
78
4a624f6e
VZ
79#ifdef __WXDFB__
80 #include "wx/dfb/dcclient.h"
81 #include "wx/dfb/dcmemory.h"
82 #include "wx/dfb/dcscreen.h"
83#endif
84
e2fc40b4
VZ
85#ifdef __WXPALMOS__
86 #include "wx/palmos/dcclient.h"
87 #include "wx/palmos/dcmemory.h"
88 #include "wx/palmos/dcscreen.h"
89#endif
90
2970ae54
RR
91//----------------------------------------------------------------------------
92// wxDCFactory
93//----------------------------------------------------------------------------
94
95wxDCFactory *wxDCFactory::m_factory = NULL;
96
f2498c4e 97void wxDCFactory::Set(wxDCFactory *factory)
2970ae54 98{
f2498c4e 99 delete m_factory;
2970ae54 100
f2498c4e 101 m_factory = factory;
2970ae54
RR
102}
103
f0875501 104wxDCFactory *wxDCFactory::Get()
2970ae54 105{
f2498c4e
VZ
106 if ( !m_factory )
107 m_factory = new wxNativeDCFactory;
2970ae54 108
f2498c4e 109 return m_factory;
2970ae54
RR
110}
111
f2498c4e
VZ
112class wxDCFactoryCleanupModule : public wxModule
113{
114public:
115 virtual bool OnInit() { return true; }
116 virtual void OnExit() { wxDCFactory::Set(NULL); }
117
118private:
119 DECLARE_DYNAMIC_CLASS(wxDCFactoryCleanupModule)
120};
121
122IMPLEMENT_DYNAMIC_CLASS(wxDCFactoryCleanupModule, wxModule)
123
2970ae54
RR
124//-----------------------------------------------------------------------------
125// wxNativeDCFactory
126//-----------------------------------------------------------------------------
127
888dde65 128wxDCImpl* wxNativeDCFactory::CreateWindowDC( wxWindowDC *owner )
f0875501 129{
888dde65 130 return new wxWindowDCImpl( owner );
2970ae54
RR
131}
132
888dde65 133wxDCImpl* wxNativeDCFactory::CreateWindowDC( wxWindowDC *owner, wxWindow *window )
f0875501 134{
888dde65 135 return new wxWindowDCImpl( owner, window );
2970ae54
RR
136}
137
888dde65
RR
138wxDCImpl* wxNativeDCFactory::CreateClientDC( wxClientDC *owner )
139{
140 return new wxClientDCImpl( owner );
2970ae54
RR
141}
142
888dde65
RR
143wxDCImpl* wxNativeDCFactory::CreateClientDC( wxClientDC *owner, wxWindow *window )
144{
145 return new wxClientDCImpl( owner, window );
2970ae54
RR
146}
147
888dde65
RR
148wxDCImpl* wxNativeDCFactory::CreatePaintDC( wxPaintDC *owner )
149{
150 return new wxPaintDCImpl( owner );
2970ae54
RR
151}
152
888dde65
RR
153wxDCImpl* wxNativeDCFactory::CreatePaintDC( wxPaintDC *owner, wxWindow *window )
154{
155 return new wxPaintDCImpl( owner, window );
2970ae54
RR
156}
157
888dde65
RR
158wxDCImpl* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC *owner )
159{
160 return new wxMemoryDCImpl( owner );
2970ae54
RR
161}
162
888dde65
RR
163wxDCImpl* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC *owner, wxBitmap &bitmap )
164{
165 return new wxMemoryDCImpl( owner, bitmap );
2970ae54
RR
166}
167
888dde65
RR
168wxDCImpl* wxNativeDCFactory::CreateMemoryDC( wxMemoryDC *owner, wxDC *dc )
169{
170 return new wxMemoryDCImpl( owner, dc );
ab171e95
RR
171}
172
888dde65
RR
173wxDCImpl* wxNativeDCFactory::CreateScreenDC( wxScreenDC *owner )
174{
175 return new wxScreenDCImpl( owner );
2970ae54
RR
176}
177
6b4f4d47 178#if wxUSE_PRINTING_ARCHITECTURE
888dde65 179wxDCImpl *wxNativeDCFactory::CreatePrinterDC( wxPrinterDC *owner, const wxPrintData &data )
c8ddadff 180{
4f37154e 181 wxPrintFactory *factory = wxPrintFactory::GetFactory();
888dde65 182 return factory->CreatePrinterDCImpl( owner, data );
c8ddadff 183}
6b4f4d47 184#endif
c8ddadff 185
2970ae54
RR
186//-----------------------------------------------------------------------------
187// wxWindowDC
188//-----------------------------------------------------------------------------
189
f0875501 190IMPLEMENT_ABSTRACT_CLASS(wxWindowDC, wxDC)
2970ae54 191
f0875501
VZ
192wxWindowDC::wxWindowDC(wxWindow *win)
193 : wxDC(wxDCFactory::Get()->CreateWindowDC(this, win))
2970ae54 194{
2970ae54
RR
195}
196
197//-----------------------------------------------------------------------------
198// wxClientDC
199//-----------------------------------------------------------------------------
200
f0875501 201IMPLEMENT_ABSTRACT_CLASS(wxClientDC, wxWindowDC)
2970ae54 202
f0875501
VZ
203wxClientDC::wxClientDC(wxWindow *win)
204 : wxWindowDC(wxDCFactory::Get()->CreateClientDC(this, win))
2970ae54 205{
2970ae54
RR
206}
207
2970ae54
RR
208//-----------------------------------------------------------------------------
209// wxMemoryDC
210//-----------------------------------------------------------------------------
211
212IMPLEMENT_DYNAMIC_CLASS(wxMemoryDC, wxDC)
213
214wxMemoryDC::wxMemoryDC()
f0875501 215 : wxDC(wxDCFactory::Get()->CreateMemoryDC(this))
2970ae54 216{
2970ae54
RR
217}
218
f0875501
VZ
219wxMemoryDC::wxMemoryDC(wxBitmap& bitmap)
220 : wxDC(wxDCFactory::Get()->CreateMemoryDC(this, bitmap))
2970ae54 221{
2970ae54
RR
222}
223
f0875501
VZ
224wxMemoryDC::wxMemoryDC(wxDC *dc)
225 : wxDC(wxDCFactory::Get()->CreateMemoryDC(this, dc))
2970ae54 226{
ab171e95
RR
227}
228
229void wxMemoryDC::SelectObject(wxBitmap& bmp)
230{
231 // make sure that the given wxBitmap is not sharing its data with other
232 // wxBitmap instances as its contents will be modified by any drawing
233 // operation done on this DC
234 if (bmp.IsOk())
235 bmp.UnShare();
236
4f37154e 237 GetImpl()->DoSelect(bmp);
ab171e95
RR
238}
239
240void wxMemoryDC::SelectObjectAsSource(const wxBitmap& bmp)
241{
4f37154e 242 GetImpl()->DoSelect(bmp);
2970ae54 243}
ab171e95
RR
244
245const wxBitmap& wxMemoryDC::GetSelectedBitmap() const
246{
4f37154e 247 return GetImpl()->GetSelectedBitmap();
ab171e95
RR
248}
249
250wxBitmap& wxMemoryDC::GetSelectedBitmap()
251{
4f37154e 252 return GetImpl()->GetSelectedBitmap();
ab171e95
RR
253}
254
f0875501 255
2970ae54
RR
256//-----------------------------------------------------------------------------
257// wxPaintDC
258//-----------------------------------------------------------------------------
259
f0875501 260IMPLEMENT_ABSTRACT_CLASS(wxPaintDC, wxClientDC)
2970ae54 261
f0875501
VZ
262wxPaintDC::wxPaintDC(wxWindow *win)
263 : wxClientDC(wxDCFactory::Get()->CreatePaintDC(this, win))
2970ae54 264{
2970ae54
RR
265}
266
ab171e95
RR
267//-----------------------------------------------------------------------------
268// wxScreenDC
269//-----------------------------------------------------------------------------
270
271IMPLEMENT_DYNAMIC_CLASS(wxScreenDC, wxWindowDC)
272
273wxScreenDC::wxScreenDC()
f0875501 274 : wxDC(wxDCFactory::Get()->CreateScreenDC(this))
ab171e95 275{
2970ae54
RR
276}
277
4f37154e
RR
278//-----------------------------------------------------------------------------
279// wxPrinterDC
280//-----------------------------------------------------------------------------
281
6b4f4d47
RR
282#if wxUSE_PRINTING_ARCHITECTURE
283
4f37154e
RR
284IMPLEMENT_DYNAMIC_CLASS(wxPrinterDC, wxDC)
285
286wxPrinterDC::wxPrinterDC()
f0875501 287 : wxDC(wxDCFactory::Get()->CreatePrinterDC(this, wxPrintData()))
4f37154e 288{
4f37154e
RR
289}
290
f0875501
VZ
291wxPrinterDC::wxPrinterDC(const wxPrintData& data)
292 : wxDC(wxDCFactory::Get()->CreatePrinterDC(this, data))
38dd8ed4
RR
293{
294}
295
296wxRect wxPrinterDC::GetPaperRect()
297{
298 return GetImpl()->GetPaperRect();
299}
300
301int wxPrinterDC::GetResolution()
302{
303 return GetImpl()->GetResolution();
304}
305
f0875501 306#endif // wxUSE_PRINTING_ARCHITECTURE
38dd8ed4 307
2970ae54 308//-----------------------------------------------------------------------------
888dde65 309// wxDCImpl
2970ae54
RR
310//-----------------------------------------------------------------------------
311
888dde65 312IMPLEMENT_ABSTRACT_CLASS(wxDCImpl, wxObject)
2970ae54 313
888dde65
RR
314wxDCImpl::wxDCImpl( wxDC *owner )
315 : m_window(NULL)
316 , m_colour(wxColourDisplay())
2970ae54
RR
317 , m_ok(true)
318 , m_clipping(false)
319 , m_isInteractive(0)
320 , m_isBBoxValid(false)
321 , m_logicalOriginX(0), m_logicalOriginY(0)
322 , m_deviceOriginX(0), m_deviceOriginY(0)
323 , m_deviceLocalOriginX(0), m_deviceLocalOriginY(0)
324 , m_logicalScaleX(1.0), m_logicalScaleY(1.0)
325 , m_userScaleX(1.0), m_userScaleY(1.0)
326 , m_scaleX(1.0), m_scaleY(1.0)
327 , m_signX(1), m_signY(1)
328 , m_minX(0), m_minY(0), m_maxX(0), m_maxY(0)
329 , m_clipX1(0), m_clipY1(0), m_clipX2(0), m_clipY2(0)
330 , m_logicalFunction(wxCOPY)
331 , m_backgroundMode(wxTRANSPARENT)
332 , m_mappingMode(wxMM_TEXT)
333 , m_pen()
334 , m_brush()
335 , m_backgroundBrush(*wxTRANSPARENT_BRUSH)
336 , m_textForegroundColour(*wxBLACK)
337 , m_textBackgroundColour(*wxWHITE)
338 , m_font()
339#if wxUSE_PALETTE
340 , m_palette()
341 , m_hasCustomPalette(false)
342#endif // wxUSE_PALETTE
343{
344 m_owner = owner;
345
346 m_mm_to_pix_x = (double)wxGetDisplaySize().GetWidth() /
347 (double)wxGetDisplaySizeMM().GetWidth();
348 m_mm_to_pix_y = (double)wxGetDisplaySize().GetHeight() /
349 (double)wxGetDisplaySizeMM().GetHeight();
f0875501 350
2970ae54
RR
351 ResetBoundingBox();
352 ResetClipping();
353}
354
888dde65 355wxDCImpl::~wxDCImpl()
2970ae54
RR
356{
357}
358
2970ae54
RR
359// ----------------------------------------------------------------------------
360// coordinate conversions and transforms
361// ----------------------------------------------------------------------------
362
888dde65 363wxCoord wxDCImpl::DeviceToLogicalX(wxCoord x) const
2970ae54
RR
364{
365 return wxRound((double)(x - m_deviceOriginX - m_deviceLocalOriginX) / m_scaleX) * m_signX + m_logicalOriginX;
366}
367
888dde65 368wxCoord wxDCImpl::DeviceToLogicalY(wxCoord y) const
2970ae54
RR
369{
370 return wxRound((double)(y - m_deviceOriginY - m_deviceLocalOriginY) / m_scaleY) * m_signY + m_logicalOriginY;
371}
372
888dde65 373wxCoord wxDCImpl::DeviceToLogicalXRel(wxCoord x) const
2970ae54
RR
374{
375 return wxRound((double)(x) / m_scaleX);
376}
377
888dde65 378wxCoord wxDCImpl::DeviceToLogicalYRel(wxCoord y) const
2970ae54
RR
379{
380 return wxRound((double)(y) / m_scaleY);
381}
382
888dde65 383wxCoord wxDCImpl::LogicalToDeviceX(wxCoord x) const
2970ae54 384{
02255e07 385 return wxRound((double)(x - m_logicalOriginX) * m_scaleX) * m_signX + m_deviceOriginX * m_signY + m_deviceLocalOriginX;
2970ae54
RR
386}
387
888dde65 388wxCoord wxDCImpl::LogicalToDeviceY(wxCoord y) const
2970ae54 389{
02255e07 390 return wxRound((double)(y - m_logicalOriginY) * m_scaleY) * m_signY + m_deviceOriginY * m_signY + m_deviceLocalOriginY;
2970ae54
RR
391}
392
888dde65 393wxCoord wxDCImpl::LogicalToDeviceXRel(wxCoord x) const
2970ae54
RR
394{
395 return wxRound((double)(x) * m_scaleX);
396}
397
888dde65 398wxCoord wxDCImpl::LogicalToDeviceYRel(wxCoord y) const
2970ae54
RR
399{
400 return wxRound((double)(y) * m_scaleY);
401}
402
888dde65 403void wxDCImpl::ComputeScaleAndOrigin()
2970ae54
RR
404{
405 m_scaleX = m_logicalScaleX * m_userScaleX;
406 m_scaleY = m_logicalScaleY * m_userScaleY;
407}
408
888dde65 409void wxDCImpl::SetMapMode( int mode )
2970ae54
RR
410{
411 switch (mode)
412 {
413 case wxMM_TWIPS:
414 SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
415 break;
416 case wxMM_POINTS:
417 SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
418 break;
419 case wxMM_METRIC:
420 SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
421 break;
422 case wxMM_LOMETRIC:
423 SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
424 break;
425 default:
426 case wxMM_TEXT:
427 SetLogicalScale( 1.0, 1.0 );
428 break;
429 }
430 m_mappingMode = mode;
431}
432
888dde65 433void wxDCImpl::SetUserScale( double x, double y )
2970ae54
RR
434{
435 // allow negative ? -> no
436 m_userScaleX = x;
437 m_userScaleY = y;
438 ComputeScaleAndOrigin();
439}
440
888dde65 441void wxDCImpl::SetLogicalScale( double x, double y )
2970ae54
RR
442{
443 // allow negative ?
444 m_logicalScaleX = x;
445 m_logicalScaleY = y;
446 ComputeScaleAndOrigin();
447}
448
888dde65 449void wxDCImpl::SetLogicalOrigin( wxCoord x, wxCoord y )
2970ae54
RR
450{
451 m_logicalOriginX = x * m_signX;
452 m_logicalOriginY = y * m_signY;
453 ComputeScaleAndOrigin();
454}
455
888dde65 456void wxDCImpl::SetDeviceOrigin( wxCoord x, wxCoord y )
2970ae54
RR
457{
458 m_deviceOriginX = x;
459 m_deviceOriginY = y;
460 ComputeScaleAndOrigin();
461}
462
888dde65 463void wxDCImpl::SetDeviceLocalOrigin( wxCoord x, wxCoord y )
2970ae54
RR
464{
465 m_deviceLocalOriginX = x;
466 m_deviceLocalOriginY = y;
467 ComputeScaleAndOrigin();
468}
469
888dde65 470void wxDCImpl::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
2970ae54
RR
471{
472 // only wxPostScripDC has m_signX = -1, we override SetAxisOrientation there
02255e07 473 // wxWidgets 2.9: no longer override it
2970ae54
RR
474 m_signX = (xLeftRight ? 1 : -1);
475 m_signY = (yBottomUp ? -1 : 1);
476 ComputeScaleAndOrigin();
477}
478
479
480// Each element of the widths array will be the width of the string up to and
481// including the corresponding character in text. This is the generic
482// implementation, the port-specific classes should do this with native APIs
483// if available and if faster. Note: pango_layout_index_to_pos is much slower
484// than calling GetTextExtent!!
485
486#define FWC_SIZE 256
487
488class FontWidthCache
489{
490public:
491 FontWidthCache() : m_scaleX(1), m_widths(NULL) { }
492 ~FontWidthCache() { delete []m_widths; }
493
494 void Reset()
495 {
496 if (!m_widths)
497 m_widths = new int[FWC_SIZE];
498
499 memset(m_widths, 0, sizeof(int)*FWC_SIZE);
500 }
501
502 wxFont m_font;
503 double m_scaleX;
504 int *m_widths;
505};
506
507static FontWidthCache s_fontWidthCache;
508
888dde65 509bool wxDCImpl::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
2970ae54
RR
510{
511 int totalWidth = 0;
512
513 const size_t len = text.length();
514 widths.Empty();
515 widths.Add(0, len);
516
517 // reset the cache if font or horizontal scale have changed
518 if ( !s_fontWidthCache.m_widths ||
519 !wxIsSameDouble(s_fontWidthCache.m_scaleX, m_scaleX) ||
520 (s_fontWidthCache.m_font != GetFont()) )
521 {
522 s_fontWidthCache.Reset();
523 s_fontWidthCache.m_font = GetFont();
524 s_fontWidthCache.m_scaleX = m_scaleX;
525 }
526
527 // Calculate the position of each character based on the widths of
528 // the previous characters
529 int w, h;
530 for ( size_t i = 0; i < len; i++ )
531 {
532 const wxChar c = text[i];
533 unsigned int c_int = (unsigned int)c;
534
535 if ((c_int < FWC_SIZE) && (s_fontWidthCache.m_widths[c_int] != 0))
536 {
537 w = s_fontWidthCache.m_widths[c_int];
538 }
539 else
540 {
ab171e95 541 DoGetTextExtent(c, &w, &h);
2970ae54
RR
542 if (c_int < FWC_SIZE)
543 s_fontWidthCache.m_widths[c_int] = w;
544 }
545
546 totalWidth += w;
547 widths[i] = totalWidth;
548 }
549
550 return true;
551}
552
888dde65 553void wxDCImpl::GetMultiLineTextExtent(const wxString& text,
2970ae54
RR
554 wxCoord *x,
555 wxCoord *y,
556 wxCoord *h,
557 const wxFont *font) const
558{
559 wxCoord widthTextMax = 0, widthLine,
560 heightTextTotal = 0, heightLineDefault = 0, heightLine = 0;
561
562 wxString curLine;
4f37154e 563 for ( wxString::const_iterator pc = text.begin(); ; ++pc )
2970ae54 564 {
4f37154e 565 if ( pc == text.end() || *pc == _T('\n') )
2970ae54
RR
566 {
567 if ( curLine.empty() )
568 {
569 // we can't use GetTextExtent - it will return 0 for both width
570 // and height and an empty line should count in height
571 // calculation
572
573 // assume that this line has the same height as the previous
574 // one
575 if ( !heightLineDefault )
576 heightLineDefault = heightLine;
577
578 if ( !heightLineDefault )
579 {
580 // but we don't know it yet - choose something reasonable
581 DoGetTextExtent(_T("W"), NULL, &heightLineDefault,
582 NULL, NULL, font);
583 }
584
585 heightTextTotal += heightLineDefault;
586 }
587 else
588 {
589 DoGetTextExtent(curLine, &widthLine, &heightLine,
590 NULL, NULL, font);
591 if ( widthLine > widthTextMax )
592 widthTextMax = widthLine;
593 heightTextTotal += heightLine;
594 }
595
4f37154e 596 if ( pc == text.end() )
2970ae54 597 {
4f37154e 598 break;
2970ae54 599 }
4f37154e 600 else // '\n'
2970ae54 601 {
4f37154e 602 curLine.clear();
2970ae54
RR
603 }
604 }
605 else
606 {
607 curLine += *pc;
608 }
609 }
610
611 if ( x )
612 *x = widthTextMax;
613 if ( y )
614 *y = heightTextTotal;
615 if ( h )
616 *h = heightLine;
617}
618
888dde65 619void wxDCImpl::DoDrawCheckMark(wxCoord x1, wxCoord y1,
2970ae54
RR
620 wxCoord width, wxCoord height)
621{
ab171e95 622 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2970ae54
RR
623
624 wxCoord x2 = x1 + width,
625 y2 = y1 + height;
626
627 // the pen width is calibrated to give 3 for width == height == 10
ab171e95 628 wxDCPenChanger pen( *m_owner, wxPen(GetTextForeground(), (width + height + 1)/7));
2970ae54
RR
629
630 // we're drawing a scaled version of wx/generic/tick.xpm here
631 wxCoord x3 = x1 + (4*width) / 10, // x of the tick bottom
632 y3 = y1 + height / 2; // y of the left tick branch
633 DoDrawLine(x1, y3, x3, y2);
634 DoDrawLine(x3, y2, x2, y1);
635
636 CalcBoundingBox(x1, y1);
637 CalcBoundingBox(x2, y2);
638}
639
640bool
888dde65 641wxDCImpl::DoStretchBlit(wxCoord xdest, wxCoord ydest,
2970ae54
RR
642 wxCoord dstWidth, wxCoord dstHeight,
643 wxDC *source,
644 wxCoord xsrc, wxCoord ysrc,
645 wxCoord srcWidth, wxCoord srcHeight,
646 int rop,
647 bool useMask,
648 wxCoord xsrcMask,
649 wxCoord ysrcMask)
650{
651 wxCHECK_MSG( srcWidth && srcHeight && dstWidth && dstHeight, false,
652 _T("invalid blit size") );
653
654 // emulate the stretching by modifying the DC scale
655 double xscale = (double)srcWidth/dstWidth,
656 yscale = (double)srcHeight/dstHeight;
657
658 double xscaleOld, yscaleOld;
659 GetUserScale(&xscaleOld, &yscaleOld);
660 SetUserScale(xscaleOld/xscale, yscaleOld/yscale);
661
662 bool rc = DoBlit(wxCoord(xdest*xscale), wxCoord(ydest*yscale),
663 wxCoord(dstWidth*xscale), wxCoord(dstHeight*yscale),
664 source,
665 xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask);
666
667 SetUserScale(xscaleOld, yscaleOld);
668
669 return rc;
670}
671
888dde65 672void wxDCImpl::DrawLines(const wxPointList *list, wxCoord xoffset, wxCoord yoffset)
2970ae54
RR
673{
674 int n = list->GetCount();
675 wxPoint *points = new wxPoint[n];
676
677 int i = 0;
b0d7707b 678 for ( wxPointList::compatibility_iterator node = list->GetFirst(); node; node = node->GetNext(), i++ )
2970ae54 679 {
b0d7707b 680 wxPoint *point = node->GetData();
2970ae54
RR
681 points[i].x = point->x;
682 points[i].y = point->y;
683 }
684
685 DoDrawLines(n, points, xoffset, yoffset);
686
687 delete [] points;
688}
689
888dde65 690void wxDCImpl::DrawPolygon(const wxPointList *list,
2970ae54
RR
691 wxCoord xoffset, wxCoord yoffset,
692 int fillStyle)
693{
694 int n = list->GetCount();
695 wxPoint *points = new wxPoint[n];
696
697 int i = 0;
b0d7707b 698 for ( wxPointList::compatibility_iterator node = list->GetFirst(); node; node = node->GetNext(), i++ )
2970ae54 699 {
b0d7707b 700 wxPoint *point = node->GetData();
2970ae54
RR
701 points[i].x = point->x;
702 points[i].y = point->y;
703 }
704
705 DoDrawPolygon(n, points, xoffset, yoffset, fillStyle);
706
707 delete [] points;
708}
709
710void
888dde65 711wxDCImpl::DoDrawPolyPolygon(int n,
2970ae54
RR
712 int count[],
713 wxPoint points[],
714 wxCoord xoffset, wxCoord yoffset,
715 int fillStyle)
716{
717 if ( n == 1 )
718 {
719 DoDrawPolygon(count[0], points, xoffset, yoffset, fillStyle);
720 return;
721 }
722
723 int i, j, lastOfs;
724 wxPoint* pts;
725 wxPen pen;
726
727 for (i = j = lastOfs = 0; i < n; i++)
728 {
729 lastOfs = j;
730 j += count[i];
731 }
732 pts = new wxPoint[j+n-1];
733 for (i = 0; i < j; i++)
734 pts[i] = points[i];
735 for (i = 2; i <= n; i++)
736 {
737 lastOfs -= count[n-i];
738 pts[j++] = pts[lastOfs];
739 }
740
741 pen = GetPen();
742 SetPen(wxPen(*wxBLACK, 0, wxTRANSPARENT));
743 DoDrawPolygon(j, pts, xoffset, yoffset, fillStyle);
744 SetPen(pen);
745 for (i = j = 0; i < n; i++)
746 {
747 DoDrawLines(count[i], pts+j, xoffset, yoffset);
748 j += count[i];
749 }
750 delete[] pts;
751}
752
753#if wxUSE_SPLINES
754
888dde65 755void wxDCImpl::DoDrawSpline(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord x3, wxCoord y3)
2970ae54 756{
b0d7707b 757 wxPointList point_list;
2970ae54
RR
758
759 wxPoint *point1 = new wxPoint;
760 point1->x = x1; point1->y = y1;
b0d7707b 761 point_list.Append( point1 );
2970ae54
RR
762
763 wxPoint *point2 = new wxPoint;
764 point2->x = x2; point2->y = y2;
b0d7707b 765 point_list.Append( point2 );
2970ae54
RR
766
767 wxPoint *point3 = new wxPoint;
768 point3->x = x3; point3->y = y3;
b0d7707b 769 point_list.Append( point3 );
2970ae54 770
ab171e95 771 DoDrawSpline(&point_list);
2970ae54 772
b0d7707b 773 for( wxPointList::compatibility_iterator node = point_list.GetFirst(); node; node = node->GetNext() )
2970ae54 774 {
b0d7707b 775 wxPoint *p = node->GetData();
2970ae54
RR
776 delete p;
777 }
778}
779
888dde65 780void wxDCImpl::DoDrawSpline(int n, wxPoint points[])
2970ae54 781{
b0d7707b 782 wxPointList list;
2970ae54 783 for (int i =0; i < n; i++)
b0d7707b 784 list.Append( &points[i] );
2970ae54 785
ab171e95 786 DoDrawSpline(&list);
2970ae54
RR
787}
788
789// ----------------------------------- spline code ----------------------------------------
790
791void wx_quadratic_spline(double a1, double b1, double a2, double b2,
792 double a3, double b3, double a4, double b4);
793void wx_clear_stack();
794int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3,
795 double *y3, double *x4, double *y4);
796void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3,
797 double x4, double y4);
798static bool wx_spline_add_point(double x, double y);
ab171e95 799static void wx_spline_draw_point_array(wxDC *dc);
2970ae54 800
b0d7707b 801wxPointList wx_spline_point_list;
2970ae54
RR
802
803#define half(z1, z2) ((z1+z2)/2.0)
804#define THRESHOLD 5
805
806/* iterative version */
807
808void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4,
809 double b4)
810{
811 register double xmid, ymid;
812 double x1, y1, x2, y2, x3, y3, x4, y4;
813
814 wx_clear_stack();
815 wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4);
816
817 while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) {
818 xmid = (double)half(x2, x3);
819 ymid = (double)half(y2, y3);
820 if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD &&
821 fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
822 wx_spline_add_point( x1, y1 );
823 wx_spline_add_point( xmid, ymid );
824 } else {
825 wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3),
826 (double)half(x3, x4), (double)half(y3, y4), x4, y4);
827 wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2),
828 (double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid);
829 }
830 }
831}
832
833/* utilities used by spline drawing routines */
834
835typedef struct wx_spline_stack_struct {
836 double x1, y1, x2, y2, x3, y3, x4, y4;
837} Stack;
838
839#define SPLINE_STACK_DEPTH 20
840static Stack wx_spline_stack[SPLINE_STACK_DEPTH];
841static Stack *wx_stack_top;
842static int wx_stack_count;
843
844void wx_clear_stack()
845{
846 wx_stack_top = wx_spline_stack;
847 wx_stack_count = 0;
848}
849
850void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
851{
852 wx_stack_top->x1 = x1;
853 wx_stack_top->y1 = y1;
854 wx_stack_top->x2 = x2;
855 wx_stack_top->y2 = y2;
856 wx_stack_top->x3 = x3;
857 wx_stack_top->y3 = y3;
858 wx_stack_top->x4 = x4;
859 wx_stack_top->y4 = y4;
860 wx_stack_top++;
861 wx_stack_count++;
862}
863
864int wx_spline_pop(double *x1, double *y1, double *x2, double *y2,
865 double *x3, double *y3, double *x4, double *y4)
866{
867 if (wx_stack_count == 0)
868 return (0);
869 wx_stack_top--;
870 wx_stack_count--;
871 *x1 = wx_stack_top->x1;
872 *y1 = wx_stack_top->y1;
873 *x2 = wx_stack_top->x2;
874 *y2 = wx_stack_top->y2;
875 *x3 = wx_stack_top->x3;
876 *y3 = wx_stack_top->y3;
877 *x4 = wx_stack_top->x4;
878 *y4 = wx_stack_top->y4;
879 return (1);
880}
881
882static bool wx_spline_add_point(double x, double y)
883{
b0d7707b
RR
884 wxPoint *point = new wxPoint( wxRound(x), wxRound(y) );
885 wx_spline_point_list.Append(point );
886 return true;
2970ae54
RR
887}
888
889static void wx_spline_draw_point_array(wxDC *dc)
890{
4f37154e 891 dc->DrawLines(&wx_spline_point_list, 0, 0 );
b0d7707b
RR
892 wxPointList::compatibility_iterator node = wx_spline_point_list.GetFirst();
893 while (node)
894 {
895 wxPoint *point = node->GetData();
896 delete point;
897 wx_spline_point_list.Erase(node);
898 node = wx_spline_point_list.GetFirst();
899 }
2970ae54
RR
900}
901
888dde65 902void wxDCImpl::DoDrawSpline( const wxPointList *points )
2970ae54 903{
ab171e95 904 wxCHECK_RET( IsOk(), wxT("invalid window dc") );
2970ae54
RR
905
906 wxPoint *p;
907 double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
908 double x1, y1, x2, y2;
909
b0d7707b 910 wxPointList::compatibility_iterator node = points->GetFirst();
2970ae54
RR
911 if (!node)
912 // empty list
913 return;
914
915 p = (wxPoint *)node->GetData();
916
917 x1 = p->x;
918 y1 = p->y;
919
920 node = node->GetNext();
b0d7707b 921 p = node->GetData();
2970ae54
RR
922
923 x2 = p->x;
924 y2 = p->y;
925 cx1 = (double)((x1 + x2) / 2);
926 cy1 = (double)((y1 + y2) / 2);
927 cx2 = (double)((cx1 + x2) / 2);
928 cy2 = (double)((cy1 + y2) / 2);
929
930 wx_spline_add_point(x1, y1);
931
932 while ((node = node->GetNext())
933#if !wxUSE_STL
934 != NULL
935#endif // !wxUSE_STL
936 )
937 {
b0d7707b 938 p = node->GetData();
2970ae54
RR
939 x1 = x2;
940 y1 = y2;
941 x2 = p->x;
942 y2 = p->y;
943 cx4 = (double)(x1 + x2) / 2;
944 cy4 = (double)(y1 + y2) / 2;
945 cx3 = (double)(x1 + cx4) / 2;
946 cy3 = (double)(y1 + cy4) / 2;
947
948 wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
949
950 cx1 = cx4;
951 cy1 = cy4;
952 cx2 = (double)(cx1 + x2) / 2;
953 cy2 = (double)(cy1 + y2) / 2;
954 }
955
956 wx_spline_add_point( cx1, cy1 );
957 wx_spline_add_point( x2, y2 );
958
959 wx_spline_draw_point_array( m_owner );
960}
961
962#endif // wxUSE_SPLINES
963
964
2970ae54 965
888dde65 966void wxDCImpl::DoGradientFillLinear(const wxRect& rect,
2970ae54
RR
967 const wxColour& initialColour,
968 const wxColour& destColour,
969 wxDirection nDirection)
970{
971 // save old pen
972 wxPen oldPen = m_pen;
973 wxBrush oldBrush = m_brush;
974
975 wxUint8 nR1 = initialColour.Red();
976 wxUint8 nG1 = initialColour.Green();
977 wxUint8 nB1 = initialColour.Blue();
978 wxUint8 nR2 = destColour.Red();
979 wxUint8 nG2 = destColour.Green();
980 wxUint8 nB2 = destColour.Blue();
981 wxUint8 nR, nG, nB;
982
983 if ( nDirection == wxEAST || nDirection == wxWEST )
984 {
985 wxInt32 x = rect.GetWidth();
986 wxInt32 w = x; // width of area to shade
987 wxInt32 xDelta = w/256; // height of one shade bend
988 if (xDelta < 1)
989 xDelta = 1;
990
991 while (x >= xDelta)
992 {
993 x -= xDelta;
994 if (nR1 > nR2)
995 nR = nR1 - (nR1-nR2)*(w-x)/w;
996 else
997 nR = nR1 + (nR2-nR1)*(w-x)/w;
998
999 if (nG1 > nG2)
1000 nG = nG1 - (nG1-nG2)*(w-x)/w;
1001 else
1002 nG = nG1 + (nG2-nG1)*(w-x)/w;
1003
1004 if (nB1 > nB2)
1005 nB = nB1 - (nB1-nB2)*(w-x)/w;
1006 else
1007 nB = nB1 + (nB2-nB1)*(w-x)/w;
1008
1009 wxColour colour(nR,nG,nB);
1010 SetPen(wxPen(colour, 1, wxSOLID));
1011 SetBrush(wxBrush(colour));
1012 if(nDirection == wxEAST)
5f77ee3b 1013 DoDrawRectangle(rect.GetRight()-x-xDelta+1, rect.GetTop(),
2970ae54
RR
1014 xDelta, rect.GetHeight());
1015 else //nDirection == wxWEST
1016 DoDrawRectangle(rect.GetLeft()+x, rect.GetTop(),
1017 xDelta, rect.GetHeight());
1018 }
1019 }
1020 else // nDirection == wxNORTH || nDirection == wxSOUTH
1021 {
1022 wxInt32 y = rect.GetHeight();
1023 wxInt32 w = y; // height of area to shade
1024 wxInt32 yDelta = w/255; // height of one shade bend
1025 if (yDelta < 1)
1026 yDelta = 1;
1027
1028 while (y > 0)
1029 {
1030 y -= yDelta;
1031 if (nR1 > nR2)
1032 nR = nR1 - (nR1-nR2)*(w-y)/w;
1033 else
1034 nR = nR1 + (nR2-nR1)*(w-y)/w;
1035
1036 if (nG1 > nG2)
1037 nG = nG1 - (nG1-nG2)*(w-y)/w;
1038 else
1039 nG = nG1 + (nG2-nG1)*(w-y)/w;
1040
1041 if (nB1 > nB2)
1042 nB = nB1 - (nB1-nB2)*(w-y)/w;
1043 else
1044 nB = nB1 + (nB2-nB1)*(w-y)/w;
1045
1046 wxColour colour(nR,nG,nB);
1047 SetPen(wxPen(colour, 1, wxSOLID));
1048 SetBrush(wxBrush(colour));
1049 if(nDirection == wxNORTH)
1050 DoDrawRectangle(rect.GetLeft(), rect.GetTop()+y,
1051 rect.GetWidth(), yDelta);
1052 else //nDirection == wxSOUTH
5f77ee3b 1053 DoDrawRectangle(rect.GetLeft(), rect.GetBottom()-y-yDelta+1,
2970ae54
RR
1054 rect.GetWidth(), yDelta);
1055 }
1056 }
1057
1058 SetPen(oldPen);
1059 SetBrush(oldBrush);
1060}
1061
888dde65 1062void wxDCImpl::DoGradientFillConcentric(const wxRect& rect,
2970ae54
RR
1063 const wxColour& initialColour,
1064 const wxColour& destColour,
1065 const wxPoint& circleCenter)
1066{
1067 //save the old pen color
1068 wxColour oldPenColour = m_pen.GetColour();
1069
1070 wxUint8 nR1 = destColour.Red();
1071 wxUint8 nG1 = destColour.Green();
1072 wxUint8 nB1 = destColour.Blue();
1073 wxUint8 nR2 = initialColour.Red();
1074 wxUint8 nG2 = initialColour.Green();
1075 wxUint8 nB2 = initialColour.Blue();
1076 wxUint8 nR, nG, nB;
1077
1078
1079 //Radius
1080 wxInt32 cx = rect.GetWidth() / 2;
1081 wxInt32 cy = rect.GetHeight() / 2;
1082 wxInt32 nRadius;
1083 if (cx < cy)
1084 nRadius = cx;
1085 else
1086 nRadius = cy;
1087
1088 //Offset of circle
1089 wxInt32 nCircleOffX = circleCenter.x - (rect.GetWidth() / 2);
1090 wxInt32 nCircleOffY = circleCenter.y - (rect.GetHeight() / 2);
1091
1092 for ( wxInt32 x = 0; x < rect.GetWidth(); x++ )
1093 {
1094 for ( wxInt32 y = 0; y < rect.GetHeight(); y++ )
1095 {
1096 //get color difference
1097 wxInt32 nGradient = ((nRadius -
1098 (wxInt32)sqrt(
1099 pow((double)(x - cx - nCircleOffX), 2) +
1100 pow((double)(y - cy - nCircleOffY), 2)
1101 )) * 100) / nRadius;
1102
1103 //normalize Gradient
1104 if (nGradient < 0 )
1105 nGradient = 0;
1106
1107 //get dest colors
1108 nR = (wxUint8)(nR1 + ((nR2 - nR1) * nGradient / 100));
1109 nG = (wxUint8)(nG1 + ((nG2 - nG1) * nGradient / 100));
1110 nB = (wxUint8)(nB1 + ((nB2 - nB1) * nGradient / 100));
1111
1112 //set the pixel
1113 m_pen.SetColour(wxColour(nR,nG,nB));
ab171e95 1114 DoDrawPoint(x + rect.GetLeft(), y + rect.GetTop());
2970ae54
RR
1115 }
1116 }
1117 //return old pen color
1118 m_pen.SetColour(oldPenColour);
1119}
1120
1121//-----------------------------------------------------------------------------
1122// wxDC
1123//-----------------------------------------------------------------------------
1124
1125IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
1126
ab171e95
RR
1127void wxDC::DrawLabel(const wxString& text,
1128 const wxBitmap& bitmap,
1129 const wxRect& rect,
1130 int alignment,
1131 int indexAccel,
1132 wxRect *rectBounding)
1133{
1134 // find the text position
1135 wxCoord widthText, heightText, heightLine;
1136 GetMultiLineTextExtent(text, &widthText, &heightText, &heightLine);
1137
1138 wxCoord width, height;
1139 if ( bitmap.Ok() )
1140 {
1141 width = widthText + bitmap.GetWidth();
1142 height = bitmap.GetHeight();
1143 }
1144 else // no bitmap
1145 {
1146 width = widthText;
1147 height = heightText;
1148 }
1149
1150 wxCoord x, y;
1151 if ( alignment & wxALIGN_RIGHT )
1152 {
1153 x = rect.GetRight() - width;
1154 }
1155 else if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
1156 {
1157 x = (rect.GetLeft() + rect.GetRight() + 1 - width) / 2;
1158 }
1159 else // alignment & wxALIGN_LEFT
1160 {
1161 x = rect.GetLeft();
1162 }
1163
1164 if ( alignment & wxALIGN_BOTTOM )
1165 {
1166 y = rect.GetBottom() - height;
1167 }
1168 else if ( alignment & wxALIGN_CENTRE_VERTICAL )
1169 {
1170 y = (rect.GetTop() + rect.GetBottom() + 1 - height) / 2;
1171 }
1172 else // alignment & wxALIGN_TOP
1173 {
1174 y = rect.GetTop();
1175 }
1176
1177 // draw the bitmap first
1178 wxCoord x0 = x,
1179 y0 = y,
1180 width0 = width;
1181 if ( bitmap.Ok() )
1182 {
1183 DrawBitmap(bitmap, x, y, true /* use mask */);
1184
1185 wxCoord offset = bitmap.GetWidth() + 4;
1186 x += offset;
1187 width -= offset;
1188
1189 y += (height - heightText) / 2;
1190 }
1191
1192 // we will draw the underscore under the accel char later
1193 wxCoord startUnderscore = 0,
1194 endUnderscore = 0,
1195 yUnderscore = 0;
1196
1197 // split the string into lines and draw each of them separately
1198 wxString curLine;
1199 for ( wxString::const_iterator pc = text.begin(); ; ++pc )
1200 {
1201 if ( *pc == _T('\n') || pc == text.end() )
1202 {
1203 int xRealStart = x; // init it here to avoid compielr warnings
1204
1205 if ( !curLine.empty() )
1206 {
1207 // NB: can't test for !(alignment & wxALIGN_LEFT) because
1208 // wxALIGN_LEFT is 0
1209 if ( alignment & (wxALIGN_RIGHT | wxALIGN_CENTRE_HORIZONTAL) )
1210 {
1211 wxCoord widthLine;
1212 GetTextExtent(curLine, &widthLine, NULL);
1213
1214 if ( alignment & wxALIGN_RIGHT )
1215 {
1216 xRealStart += width - widthLine;
1217 }
1218 else // if ( alignment & wxALIGN_CENTRE_HORIZONTAL )
1219 {
1220 xRealStart += (width - widthLine) / 2;
1221 }
1222 }
1223 //else: left aligned, nothing to do
1224
1225 DrawText(curLine, xRealStart, y);
1226 }
1227
1228 y += heightLine;
1229
1230 // do we have underscore in this line? we can check yUnderscore
1231 // because it is set below to just y + heightLine if we do
1232 if ( y == yUnderscore )
1233 {
1234 // adjust the horz positions to account for the shift
1235 startUnderscore += xRealStart;
1236 endUnderscore += xRealStart;
1237 }
1238
1239 if ( pc == text.end() )
1240 break;
1241
1242 curLine.clear();
1243 }
1244 else // not end of line
1245 {
1246 if ( pc - text.begin() == indexAccel )
1247 {
1248 // remeber to draw underscore here
1249 GetTextExtent(curLine, &startUnderscore, NULL);
1250 curLine += *pc;
1251 GetTextExtent(curLine, &endUnderscore, NULL);
1252
1253 yUnderscore = y + heightLine;
1254 }
1255 else
1256 {
1257 curLine += *pc;
1258 }
1259 }
1260 }
1261
1262 // draw the underscore if found
1263 if ( startUnderscore != endUnderscore )
1264 {
1265 // it should be of the same colour as text
1266 SetPen(wxPen(GetTextForeground(), 0, wxSOLID));
1267
1268 yUnderscore--;
1269
1270 DrawLine(startUnderscore, yUnderscore, endUnderscore, yUnderscore);
1271 }
1272
1273 // return bounding rect if requested
1274 if ( rectBounding )
1275 {
1276 *rectBounding = wxRect(x, y - heightText, widthText, heightText);
1277 }
1278
1279 CalcBoundingBox(x0, y0);
1280 CalcBoundingBox(x0 + width0, y0 + height);
1281}
1282
2970ae54
RR
1283#if WXWIN_COMPATIBILITY_2_8
1284 // for compatibility with the old code when wxCoord was long everywhere
1285void wxDC::GetTextExtent(const wxString& string,
1286 long *x, long *y,
1287 long *descent,
1288 long *externalLeading,
1289 const wxFont *theFont) const
1290 {
1291 wxCoord x2, y2, descent2, externalLeading2;
1292 m_pimpl->DoGetTextExtent(string, &x2, &y2,
1293 &descent2, &externalLeading2,
1294 theFont);
1295 if ( x )
1296 *x = x2;
1297 if ( y )
1298 *y = y2;
1299 if ( descent )
1300 *descent = descent2;
1301 if ( externalLeading )
1302 *externalLeading = externalLeading2;
1303 }
1304
f0875501 1305void wxDC::GetLogicalOrigin(long *x, long *y) const
2970ae54
RR
1306 {
1307 wxCoord x2, y2;
1308 m_pimpl->DoGetLogicalOrigin(&x2, &y2);
1309 if ( x )
1310 *x = x2;
1311 if ( y )
1312 *y = y2;
1313 }
1314
f0875501 1315void wxDC::GetDeviceOrigin(long *x, long *y) const
2970ae54
RR
1316 {
1317 wxCoord x2, y2;
1318 m_pimpl->DoGetDeviceOrigin(&x2, &y2);
1319 if ( x )
1320 *x = x2;
1321 if ( y )
1322 *y = y2;
f0875501
VZ
1323 }
1324
1325void wxDC::GetClippingBox(long *x, long *y, long *w, long *h) const
2970ae54
RR
1326 {
1327 wxCoord xx,yy,ww,hh;
1328 m_pimpl->DoGetClippingBox(&xx, &yy, &ww, &hh);
1329 if (x) *x = xx;
1330 if (y) *y = yy;
1331 if (w) *w = ww;
1332 if (h) *h = hh;
f0875501
VZ
1333 }
1334
2970ae54 1335#endif // WXWIN_COMPATIBILITY_2_8