]> git.saurik.com Git - wxWidgets.git/blame - src/mac/carbon/dc.cpp
added calls for invalidating the dc setup on mac explicitely (needed in case of neste...
[wxWidgets.git] / src / mac / carbon / dc.cpp
CommitLineData
e9576ca5
SC
1/////////////////////////////////////////////////////////////////////////////
2// Name: dc.cpp
3// Purpose: wxDC class
4// Author: AUTHOR
5// Modified by:
6// Created: 01/02/97
7// RCS-ID: $Id$
8// Copyright: (c) AUTHOR
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
12#ifdef __GNUG__
13#pragma implementation "dc.h"
14#endif
15
16#include "wx/dc.h"
03e11df5 17#include "wx/app.h"
2f1ae414 18#include "wx/mac/uma.h"
e9576ca5 19
5b781a67
SC
20#if __MSL__ >= 0x6000
21#include "math.h"
22#endif
23
2f1ae414 24#if !USE_SHARED_LIBRARY
e9576ca5 25IMPLEMENT_ABSTRACT_CLASS(wxDC, wxObject)
2f1ae414 26#endif
e9576ca5
SC
27
28//-----------------------------------------------------------------------------
29// constants
30//-----------------------------------------------------------------------------
31
32#define mm2inches 0.0393700787402
33#define inches2mm 25.4
34#define mm2twips 56.6929133859
35#define twips2mm 0.0176388888889
36#define mm2pt 2.83464566929
37#define pt2mm 0.352777777778
38
519cb848
SC
39long wxDC::m_macCurrentPortId = 1 ;
40
e9576ca5
SC
41//-----------------------------------------------------------------------------
42// wxDC
43//-----------------------------------------------------------------------------
44
2f1ae414 45wxDC::wxDC()
e9576ca5
SC
46{
47 m_ok = FALSE;
48 m_optimize = FALSE;
49 m_autoSetting = FALSE;
50 m_colour = TRUE;
51 m_clipping = FALSE;
52
2f1ae414
SC
53 m_mm_to_pix_x = mm2pt;
54 m_mm_to_pix_y = mm2pt;
e9576ca5
SC
55
56 m_logicalOriginX = 0;
57 m_logicalOriginY = 0;
58 m_deviceOriginX = 0;
59 m_deviceOriginY = 0;
60 m_internalDeviceOriginX = 0;
61 m_internalDeviceOriginY = 0;
62 m_externalDeviceOriginX = 0;
63 m_externalDeviceOriginY = 0;
64
65 m_logicalScaleX = 1.0;
66 m_logicalScaleY = 1.0;
67 m_userScaleX = 1.0;
68 m_userScaleY = 1.0;
69 m_scaleX = 1.0;
70 m_scaleY = 1.0;
71
e3065973 72 m_mappingMode = wxMM_TEXT;
e9576ca5
SC
73 m_needComputeScaleX = FALSE;
74 m_needComputeScaleY = FALSE;
75
76 m_signX = 1; // default x-axis left to right
77 m_signY = 1; // default y-axis top down
78
79 m_maxX = m_maxY = -100000;
80 m_minY = m_minY = 100000;
81
82 m_logicalFunction = wxCOPY;
83// m_textAlignment = wxALIGN_TOP_LEFT;
84 m_backgroundMode = wxTRANSPARENT;
85
86 m_textForegroundColour = *wxBLACK;
87 m_textBackgroundColour = *wxWHITE;
88 m_pen = *wxBLACK_PEN;
89 m_font = *wxNORMAL_FONT;
90 m_brush = *wxTRANSPARENT_BRUSH;
91 m_backgroundBrush = *wxWHITE_BRUSH;
92
93// m_palette = wxAPP_COLOURMAP;
519cb848 94 m_macPort = NULL ;
8208e181 95 m_macMask = NULL ;
519cb848
SC
96 m_ok = FALSE ;
97
98 m_macFontInstalled = false ;
99 m_macBrushInstalled = false ;
100 m_macPenInstalled = false ;
101
102 m_macPortId = 0 ;
103 m_macLocalOrigin.h = m_macLocalOrigin.v = 0 ;
104 m_macClipRect.left = -32000 ;
105 m_macClipRect.top = -32000 ;
106 m_macClipRect.right = 32000 ;
107 m_macClipRect.bottom = 32000 ;
108 ::GetPort( &m_macOrigPort ) ;
e9576ca5
SC
109};
110
111wxDC::~wxDC(void)
112{
2f1ae414
SC
113 if ( !m_macPortHelper.IsCleared() )
114 {
115 GrafPtr port ;
116 GetPort( &port ) ;
117 SetPort( m_macPortHelper.GetCurrentPort() ) ;
118 SetOrigin( 0 , 0 ) ;
119 SetPort( port ) ;
120 }
121 /*
519cb848
SC
122 if ( m_macPort )
123 {
2f1ae414 124 ::SetPort( m_macPort ) ;
519cb848
SC
125 ::SetOrigin( 0 , 0 ) ;
126 ::ClipRect( &m_macPort->portRect ) ;
127 ::PenNormal() ;
128 ::SetPort( m_macOrigPort ) ;
129 }
2f1ae414 130 */
519cb848 131 ++m_macCurrentPortId ;
e9576ca5
SC
132};
133
519cb848
SC
134void wxDC::MacSetupPort() const
135{
5b781a67 136 AGAPortHelper* help = (AGAPortHelper*) &m_macPortHelper ;
2f1ae414 137 help->Setup( m_macPort ) ;
519cb848 138 m_macPortId = ++m_macCurrentPortId ;
519cb848
SC
139 ::SetOrigin(-m_macLocalOrigin.h, -m_macLocalOrigin.v);
140 ::ClipRect(&m_macClipRect);
141
142 m_macFontInstalled = false ;
143 m_macBrushInstalled = false ;
144 m_macPenInstalled = false ;
145}
146
2f1ae414 147void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask )
519cb848 148{
2f1ae414
SC
149 float scale = 1.0 ;
150
519cb848
SC
151 if (!Ok())
152 return;
153 MacVerifySetup() ;
154
155 long xx1 = XLOG2DEV(x);
156 long yy1 = YLOG2DEV(y);
157
158 {
159 wxBitmapRefData * bmap = (wxBitmapRefData*) ( bmp.GetRefData()) ;
160
161 if ( bmap )
162 {
163 if ( bmap->m_bitmapType == kMacBitmapTypePict )
164 {
03e11df5 165 Rect bitmaprect = { 0 , 0 , int(bmap->m_height * scale) , int(bmap->m_width * scale)} ;
519cb848
SC
166 ::OffsetRect( &bitmaprect , xx1 , yy1 ) ;
167 ::DrawPicture( bmap->m_hPict , &bitmaprect ) ;
168 }
169 else if ( bmap->m_bitmapType == kMacBitmapTypeGrafWorld )
170 {
171 if ( bmap->m_hBitmap )
172 {
173 GWorldPtr bmapworld = bmap->m_hBitmap ;
174 PixMapHandle bmappixels ;
175 RGBColor white = { 0xFFFF, 0xFFFF,0xFFFF} ;
176 RGBColor black = { 0,0,0} ;
177 RGBForeColor( &black ) ;
178 RGBBackColor( &white ) ;
519cb848
SC
179
180 bmappixels = GetGWorldPixMap( bmapworld ) ;
181 if ( LockPixels(bmappixels) )
182 {
183 Rect source , dest ;
184 source.top = 0 ;
185 source.left = 0 ;
186 source.right = bmap->m_width ;
187 source.bottom = bmap->m_height ;
188 dest.top = YLOG2DEV(y) ;
189 dest.left = XLOG2DEV(x) ;
2f1ae414
SC
190 dest.bottom = YLOG2DEV(y + bmap->m_height * scale) ;
191 dest.right = XLOG2DEV(x + bmap->m_width * scale ) ;
519cb848 192
8208e181
SC
193 if ( useMask && bmp.GetMask() )
194 {
195 if ( LockPixels( GetGWorldPixMap( bmp.GetMask()->GetMaskBitmap( ) ) ) )
196 {
2f1ae414
SC
197 CopyMask( GetPortBitMapForCopyBits( bmapworld ) , GetPortBitMapForCopyBits( bmp.GetMask()->GetMaskBitmap( ) ) ,
198 GetPortBitMapForCopyBits( m_macPort ) ,
8208e181
SC
199 &source, &source , &dest ) ;
200 UnlockPixels( GetGWorldPixMap( bmp.GetMask()->GetMaskBitmap( ) ) ) ;
201 }
519cb848 202 }
8208e181 203 else
2f1ae414 204 CopyBits( GetPortBitMapForCopyBits( bmapworld ) , GetPortBitMapForCopyBits( m_macPort ),
8208e181
SC
205 &source, &dest, srcCopy, NULL ) ;
206
519cb848
SC
207 UnlockPixels( bmappixels ) ;
208 }
209 m_macPenInstalled = false ;
210 m_macBrushInstalled = false ;
211 m_macFontInstalled = false ;
212 }
213 }
214 }
215 }
216}
217
2f1ae414 218void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y )
e9576ca5 219{
519cb848
SC
220 if (!Ok())
221 return;
222 MacVerifySetup() ;
223
224 long xx1 = XLOG2DEV(x);
225 long yy1 = YLOG2DEV(y);
226
227 {
228 wxIconRefData * iconref = (wxIconRefData*) ( icon.GetRefData()) ;
229
230 if ( iconref && iconref->m_ok && iconref->m_hIcon )
231 {
232 Rect bitmaprect = { 0 , 0 , iconref->m_height , iconref->m_width } ;
233 OffsetRect( &bitmaprect , xx1 , yy1 ) ;
234 PlotCIconHandle( &bitmaprect , atNone , ttNone , iconref->m_hIcon ) ;
235 }
236 }
e9576ca5
SC
237};
238
2f1ae414 239void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
e9576ca5 240{
2f1ae414 241 MacVerifySetup() ;
519cb848
SC
242 if( m_clipping )
243 {
244 m_clipX1 = wxMax( m_clipX1 , x ) ;
245 m_clipY1 = wxMax( m_clipY1 ,y );
246 m_clipX2 = wxMin( m_clipX2, (x + width));
247 m_clipY2 = wxMin( m_clipY2,(y + height));
248
249 }
250 else
251 {
252 m_clipping = TRUE;
253 m_clipX1 = x;
254 m_clipY1 = y;
255 m_clipX2 = x + width;
256 m_clipY2 = y + height;
257 }
258
259 long x1 = XLOG2DEV(m_clipX1);
260 long y1 = YLOG2DEV(m_clipY1);
261 long x2 = XLOG2DEV(m_clipX2);
7c74e7fe 262 long y2 = YLOG2DEV(m_clipY2);
519cb848
SC
263
264 Rect clip = { y1 , x1 , y2 , x2 } ;
265
2f1ae414 266 ::ClipRect( &clip ) ;
519cb848 267
e9576ca5
SC
268};
269
2f1ae414
SC
270void wxDC::DoSetClippingRegionAsRegion( const wxRegion &region )
271{
272 wxCHECK_RET( Ok(), wxT("invalid window dc") );
273
274 MacVerifySetup() ;
275 if (region.Empty())
276 {
277 DestroyClippingRegion();
278 return;
279 }
280
281 wxCoord xx, yy, ww, hh;
282 region.GetBox( xx, yy, ww, hh );
283 wxDC::DoSetClippingRegion( xx, yy, ww, hh );
ee41971c
UJ
284}
285
e9576ca5
SC
286void wxDC::DestroyClippingRegion(void)
287{
519cb848 288 MacVerifySetup() ;
e9576ca5 289 m_clipping = FALSE;
519cb848
SC
290// Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
291 ::ClipRect(&m_macClipRect);
e9576ca5 292};
ee41971c 293
2f1ae414 294void wxDC::DoGetSize( int* width, int* height ) const
e9576ca5
SC
295{
296 *width = m_maxX-m_minX;
297 *height = m_maxY-m_minY;
298};
299
2f1ae414 300void wxDC::DoGetSizeMM( int* width, int* height ) const
e9576ca5
SC
301{
302 int w = 0;
303 int h = 0;
304 GetSize( &w, &h );
305 *width = long( double(w) / (m_scaleX*m_mm_to_pix_x) );
306 *height = long( double(h) / (m_scaleY*m_mm_to_pix_y) );
307};
308
309void wxDC::SetTextForeground( const wxColour &col )
310{
311 if (!Ok()) return;
312 m_textForegroundColour = col;
519cb848 313 m_macFontInstalled = false ;
e9576ca5
SC
314};
315
316void wxDC::SetTextBackground( const wxColour &col )
317{
318 if (!Ok()) return;
319 m_textBackgroundColour = col;
519cb848 320 m_macFontInstalled = false ;
e9576ca5
SC
321};
322
323void wxDC::SetMapMode( int mode )
324{
325 switch (mode)
326 {
e3065973 327 case wxMM_TWIPS:
e9576ca5
SC
328 SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
329 break;
e3065973 330 case wxMM_POINTS:
e9576ca5
SC
331 SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
332 break;
e3065973 333 case wxMM_METRIC:
e9576ca5
SC
334 SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
335 break;
e3065973 336 case wxMM_LOMETRIC:
e9576ca5
SC
337 SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
338 break;
339 default:
e3065973 340 case wxMM_TEXT:
e9576ca5
SC
341 SetLogicalScale( 1.0, 1.0 );
342 break;
343 };
e3065973 344 if (mode != wxMM_TEXT)
e9576ca5
SC
345 {
346 m_needComputeScaleX = TRUE;
347 m_needComputeScaleY = TRUE;
348 };
349};
350
351void wxDC::SetUserScale( double x, double y )
352{
353 // allow negative ? -> no
354 m_userScaleX = x;
355 m_userScaleY = y;
356 ComputeScaleAndOrigin();
357};
358
e9576ca5
SC
359void wxDC::SetLogicalScale( double x, double y )
360{
361 // allow negative ?
362 m_logicalScaleX = x;
363 m_logicalScaleY = y;
364 ComputeScaleAndOrigin();
365};
366
2f1ae414 367void wxDC::SetLogicalOrigin( wxCoord x, wxCoord y )
e9576ca5
SC
368{
369 m_logicalOriginX = x * m_signX; // is this still correct ?
370 m_logicalOriginY = y * m_signY;
371 ComputeScaleAndOrigin();
372};
373
2f1ae414 374void wxDC::SetDeviceOrigin( wxCoord x, wxCoord y )
e9576ca5
SC
375{
376 m_externalDeviceOriginX = x;
377 m_externalDeviceOriginY = y;
378 ComputeScaleAndOrigin();
379};
2f1ae414 380/*
e9576ca5
SC
381void wxDC::SetInternalDeviceOrigin( long x, long y )
382{
383 m_internalDeviceOriginX = x;
384 m_internalDeviceOriginY = y;
385 ComputeScaleAndOrigin();
386};
387
388void wxDC::GetInternalDeviceOrigin( long *x, long *y )
389{
390 if (x) *x = m_internalDeviceOriginX;
391 if (y) *y = m_internalDeviceOriginY;
392};
2f1ae414 393*/
e9576ca5
SC
394void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
395{
396 m_signX = (xLeftRight ? 1 : -1);
397 m_signY = (yBottomUp ? -1 : 1);
398 ComputeScaleAndOrigin();
399};
2f1ae414 400/*
e9576ca5
SC
401
402void wxDC::CalcBoundingBox( long x, long y )
403{
404 if (x < m_minX) m_minX = x;
405 if (y < m_minY) m_minY = y;
406 if (x > m_maxX) m_maxX = x;
407 if (y > m_maxY) m_maxY = y;
408};
2f1ae414
SC
409*/
410wxSize wxDC::GetPPI() const
411{
412 return wxSize(72, 72);
413}
414
415int wxDC::GetDepth() const
416{
417 return wxDisplayDepth() ;
418}
e9576ca5
SC
419
420void wxDC::ComputeScaleAndOrigin(void)
421{
422 // CMB: copy scale to see if it changes
423 double origScaleX = m_scaleX;
424 double origScaleY = m_scaleY;
425
426 m_scaleX = m_logicalScaleX * m_userScaleX;
427 m_scaleY = m_logicalScaleY * m_userScaleY;
428
429 m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
430 m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
431
432 // CMB: if scale has changed call SetPen to recalulate the line width
433 if (m_scaleX != origScaleX || m_scaleY != origScaleY)
434 {
5b781a67
SC
435 // this is a bit artificial, but we need to force wxDC to think
436 // the pen has changed
437 wxPen* pen = & GetPen();
438 wxPen tempPen;
439 m_pen = tempPen;
440 SetPen(* pen);
e9576ca5
SC
441 }
442};
443
519cb848
SC
444void wxDC::SetPalette( const wxPalette& palette )
445{
446}
447
448void wxDC::SetBackgroundMode( int mode )
449{
450 m_backgroundMode = mode ;
451}
452
453void wxDC::SetFont( const wxFont &font )
454{
455 if (!Ok())
456 return;
457
458 MacVerifySetup() ;
459
460 m_font = font;
461 m_macFontInstalled = false ;
462}
463
464void wxDC::SetPen( const wxPen &pen )
465{
466 if (!Ok() )
467 return;
468
469 MacVerifySetup() ;
470
471 if ( m_pen == pen )
472 return ;
473
474 m_pen = pen;
475/*
476 if (!m_pen.Ok())
477 return;
478*/
479 m_macPenInstalled = false ;
480}
481
482void wxDC::SetBrush( const wxBrush &brush )
483{
484 if (!Ok() )
485 return;
486 MacVerifySetup() ;
487
488 if (m_brush == brush)
489 return;
490
491 m_brush = brush;
492 m_macBrushInstalled = false ;
493}
494
495void wxDC::SetBackground( const wxBrush &brush )
496{
497 if (!Ok())
498 return;
499 MacVerifySetup() ;
500
501 if (m_backgroundBrush == brush)
502 return;
503
504 m_backgroundBrush = brush;
505
506 if (!m_backgroundBrush.Ok())
507 return;
508 m_macBrushInstalled = false ;
509}
510
511void wxDC::SetLogicalFunction( int function )
512{
513 if (m_logicalFunction == function)
514 return;
515
516 m_logicalFunction = function ;
517 m_macFontInstalled = false ;
518 m_macBrushInstalled = false ;
519 m_macPenInstalled = false ;
520}
521
2f1ae414
SC
522void wxDC::DoFloodFill( wxCoord x, wxCoord y, const wxColour& col,
523 int style )
519cb848
SC
524{
525}
526
2f1ae414 527bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
519cb848
SC
528{
529 return true ;
530}
531
2f1ae414 532void wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
519cb848
SC
533{
534 if (!Ok())
535 return;
536
537 MacVerifySetup() ;
538
539 if (m_pen.GetStyle() != wxTRANSPARENT)
540 {
541 MacInstallPen() ;
542 int offset = (m_pen.GetWidth() - 1) / 2 ;
543 long xx1 = XLOG2DEV(x1);
544 long yy1 = YLOG2DEV(y1);
545 long xx2 = XLOG2DEV(x2);
546 long yy2 = YLOG2DEV(y2);
547
548 ::MoveTo(xx1 - offset ,yy1 - offset);
549 ::LineTo(xx2 - offset , yy2 - offset );
550 };
551}
552
2f1ae414 553void wxDC::DoCrossHair( wxCoord x, wxCoord y )
519cb848
SC
554{
555}
556
2f1ae414
SC
557void wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
558 wxCoord x2, wxCoord y2,
559 wxCoord xc, wxCoord yc )
519cb848
SC
560{
561}
562
2f1ae414
SC
563void wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
564 double sa, double ea )
519cb848
SC
565{
566}
567
2f1ae414 568void wxDC::DoDrawPoint( wxCoord x, wxCoord y )
519cb848
SC
569{
570 if (!Ok())
571 return;
572
573 MacVerifySetup() ;
574
575 if (m_pen.GetStyle() != wxTRANSPARENT)
576 {
577 MacInstallPen() ;
578 long xx1 = XLOG2DEV(x);
579 long yy1 = YLOG2DEV(y);
580
581 ::MoveTo(xx1,yy1);
582 ::LineTo(xx1+1, yy1+1);
583 };
584}
585
2f1ae414
SC
586void wxDC::DoDrawLines(int n, wxPoint points[],
587 wxCoord xoffset, wxCoord yoffset)
519cb848
SC
588{
589 if (!Ok())
590 return;
591 MacVerifySetup() ;
592
593 if (m_pen.GetStyle() == wxTRANSPARENT)
594 return;
595
03e11df5 596 MacInstallPen() ;
519cb848 597
03e11df5 598 int offset = (m_pen.GetWidth() - 1 ) / 2 ;
519cb848
SC
599 long x1, x2 , y1 , y2 ;
600 x1 = XLOG2DEV(points[0].x + xoffset);
03e11df5
GD
601 y1 = YLOG2DEV(points[0].y + yoffset);
602 ::MoveTo(x1 - offset ,y1 - offset );
519cb848
SC
603
604 for (int i = 0; i < n-1; i++)
605 {
03e11df5
GD
606 x2 = XLOG2DEV(points[i+1].x + xoffset);
607 y2 = YLOG2DEV(points[i+1].y + yoffset);
608 ::LineTo(x2 - offset , y2 - offset );
519cb848
SC
609 }
610}
611
2f1ae414
SC
612void wxDC::DoDrawPolygon(int n, wxPoint points[],
613 wxCoord xoffset, wxCoord yoffset,
614 int fillStyle )
519cb848
SC
615{
616 if (!Ok())
617 return;
618 MacVerifySetup() ;
619
620 PolyHandle polygon = OpenPoly() ;
621 long x1, x2 , y1 , y2 ;
622 x1 = XLOG2DEV(points[0].x + xoffset);
03e11df5
GD
623 y1 = YLOG2DEV(points[0].y + yoffset);
624 ::MoveTo(x1,y1);
519cb848
SC
625
626 for (int i = 0; i < n-1; i++)
627 {
03e11df5
GD
628 x2 = XLOG2DEV(points[i+1].x + xoffset);
629 y2 = YLOG2DEV(points[i+1].y + yoffset);
630 ::LineTo(x2, y2);
519cb848
SC
631 }
632
633 ClosePoly() ;
634 if (m_brush.GetStyle() != wxTRANSPARENT)
635 {
636 MacInstallBrush() ;
637 ::PaintPoly( polygon ) ;
638 };
639
640 if (m_pen.GetStyle() != wxTRANSPARENT)
641 {
642 MacInstallPen() ;
643 ::FramePoly( polygon ) ;
644 };
645 KillPoly( polygon ) ;
646}
647
2f1ae414 648void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
519cb848
SC
649{
650 if (!Ok())
651 return;
652 MacVerifySetup() ;
653
654 long xx = XLOG2DEV(x);
655 long yy = YLOG2DEV(y);
656 long ww = m_signX * XLOG2DEVREL(width);
657 long hh = m_signY * YLOG2DEVREL(height);
658
659 // CMB: draw nothing if transformed w or h is 0
660 if (ww == 0 || hh == 0)
661 return;
662
663 // CMB: handle -ve width and/or height
664 if (ww < 0)
665 {
666 ww = -ww;
667 xx = xx - ww;
668 }
669
670 if (hh < 0)
671 {
672 hh = -hh;
673 yy = yy - hh;
674 }
675
676 Rect rect = { yy , xx , yy + hh , xx + ww } ;
677
678 if (m_brush.GetStyle() != wxTRANSPARENT)
679 {
680 MacInstallBrush() ;
681 ::PaintRect( &rect ) ;
682 };
683
684 if (m_pen.GetStyle() != wxTRANSPARENT)
685 {
686 MacInstallPen() ;
687 ::FrameRect( &rect ) ;
688 };
689}
690
2f1ae414
SC
691void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
692 wxCoord width, wxCoord height,
693 double radius)
519cb848
SC
694{
695 if (!Ok())
696 return;
697 MacVerifySetup() ;
698
699 if (radius < 0.0)
700 radius = - radius * ((width < height) ? width : height);
701
702 long xx = XLOG2DEV(x);
703 long yy = YLOG2DEV(y);
704 long ww = m_signX * XLOG2DEVREL(width);
705 long hh = m_signY * YLOG2DEVREL(height);
706
707 // CMB: draw nothing if transformed w or h is 0
708 if (ww == 0 || hh == 0)
709 return;
710
711 // CMB: handle -ve width and/or height
712 if (ww < 0)
713 {
714 ww = -ww;
715 xx = xx - ww;
716 }
717
718 if (hh < 0)
719 {
720 hh = -hh;
721 yy = yy - hh;
722 }
723
724 Rect rect = { yy , xx , yy + hh , xx + ww } ;
725
726 if (m_brush.GetStyle() != wxTRANSPARENT)
727 {
728 MacInstallBrush() ;
03e11df5 729 ::PaintRoundRect( &rect , int(radius * 2) , int(radius * 2) ) ;
519cb848
SC
730 };
731
732 if (m_pen.GetStyle() != wxTRANSPARENT)
733 {
734 MacInstallPen() ;
03e11df5 735 ::FrameRoundRect( &rect , int(radius * 2) , int(radius * 2) ) ;
519cb848
SC
736 };
737}
738
2f1ae414 739void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
519cb848
SC
740{
741 if (!Ok())
742 return;
743 MacVerifySetup() ;
744
745 long xx = XLOG2DEV(x);
746 long yy = YLOG2DEV(y);
747 long ww = m_signX * XLOG2DEVREL(width);
748 long hh = m_signY * YLOG2DEVREL(height);
749
750 // CMB: draw nothing if transformed w or h is 0
751 if (ww == 0 || hh == 0)
752 return;
753
754 // CMB: handle -ve width and/or height
755 if (ww < 0)
756 {
757 ww = -ww;
758 xx = xx - ww;
759 }
760
761 if (hh < 0)
762 {
763 hh = -hh;
764 yy = yy - hh;
765 }
766
767 Rect rect = { yy , xx , yy + hh , xx + ww } ;
768
769 if (m_brush.GetStyle() != wxTRANSPARENT)
770 {
771 MacInstallBrush() ;
772 ::PaintOval( &rect ) ;
773 };
774
775 if (m_pen.GetStyle() != wxTRANSPARENT)
776 {
777 MacInstallPen() ;
778 ::FrameOval( &rect ) ;
779 };
780}
781
782// ----------------------------------- spline code ----------------------------------------
783
784static void wx_quadratic_spline(double a1, double b1, double a2, double b2,
785 double a3, double b3, double a4, double b4);
786static void wx_clear_stack(void);
787static int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3,
788 double *y3, double *x4, double *y4);
789static void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3,
790 double x4, double y4);
791static bool wx_spline_add_point(double x, double y);
792static void wx_spline_draw_point_array(wxDC *dc);
793
794static wxList wx_spline_point_list;
795
796#define half(z1, z2) ((z1+z2)/2.0)
797#define THRESHOLD 5
798
799/* iterative version */
800
801static void wx_quadratic_spline(double a1, double b1, double a2, double b2, double a3, double b3, double a4,
802 double b4)
803{
804 register double xmid, ymid;
805 double x1, y1, x2, y2, x3, y3, x4, y4;
806
807 wx_clear_stack();
808 wx_spline_push(a1, b1, a2, b2, a3, b3, a4, b4);
809
810 while (wx_spline_pop(&x1, &y1, &x2, &y2, &x3, &y3, &x4, &y4)) {
811 xmid = (double)half(x2, x3);
812 ymid = (double)half(y2, y3);
813 if (fabs(x1 - xmid) < THRESHOLD && fabs(y1 - ymid) < THRESHOLD &&
814 fabs(xmid - x4) < THRESHOLD && fabs(ymid - y4) < THRESHOLD) {
815 wx_spline_add_point( x1, y1 );
816 wx_spline_add_point( xmid, ymid );
817 } else {
818 wx_spline_push(xmid, ymid, (double)half(xmid, x3), (double)half(ymid, y3),
819 (double)half(x3, x4), (double)half(y3, y4), x4, y4);
820 wx_spline_push(x1, y1, (double)half(x1, x2), (double)half(y1, y2),
821 (double)half(x2, xmid), (double)half(y2, ymid), xmid, ymid);
822 }
823 }
824}
825
826/* utilities used by spline drawing routines */
827
828typedef struct wx_spline_stack_struct {
829 double x1, y1, x2, y2, x3, y3, x4, y4;
830} Stack;
831
832#define SPLINE_STACK_DEPTH 20
833static Stack wx_spline_stack[SPLINE_STACK_DEPTH];
834static Stack *wx_stack_top;
835static int wx_stack_count;
836
837static void wx_clear_stack(void)
838{
839 wx_stack_top = wx_spline_stack;
840 wx_stack_count = 0;
841}
842
843static void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3, double x4, double y4)
844{
845 wx_stack_top->x1 = x1;
846 wx_stack_top->y1 = y1;
847 wx_stack_top->x2 = x2;
848 wx_stack_top->y2 = y2;
849 wx_stack_top->x3 = x3;
850 wx_stack_top->y3 = y3;
851 wx_stack_top->x4 = x4;
852 wx_stack_top->y4 = y4;
853 wx_stack_top++;
854 wx_stack_count++;
855}
856
857static int wx_spline_pop(double *x1, double *y1, double *x2, double *y2,
858 double *x3, double *y3, double *x4, double *y4)
859{
860 if (wx_stack_count == 0)
861 return (0);
862 wx_stack_top--;
863 wx_stack_count--;
864 *x1 = wx_stack_top->x1;
865 *y1 = wx_stack_top->y1;
866 *x2 = wx_stack_top->x2;
867 *y2 = wx_stack_top->y2;
868 *x3 = wx_stack_top->x3;
869 *y3 = wx_stack_top->y3;
870 *x4 = wx_stack_top->x4;
871 *y4 = wx_stack_top->y4;
872 return (1);
873}
874
875static bool wx_spline_add_point(double x, double y)
876{
877 wxPoint *point = new wxPoint ;
878 point->x = (int) x;
879 point->y = (int) y;
880 wx_spline_point_list.Append((wxObject*)point);
881 return TRUE;
882}
883
884static void wx_spline_draw_point_array(wxDC *dc)
885{
886 dc->DrawLines(&wx_spline_point_list, 0, 0 );
887 wxNode *node = wx_spline_point_list.First();
888 while (node)
889 {
890 wxPoint *point = (wxPoint *)node->Data();
891 delete point;
892 delete node;
893 node = wx_spline_point_list.First();
894 }
895}
896
2f1ae414 897void wxDC::DoDrawSpline(wxList *points)
519cb848
SC
898{
899 wxPoint *p;
900 double cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4;
901 double x1, y1, x2, y2;
902
903 wxNode *node = points->First();
904 p = (wxPoint *)node->Data();
905
906 x1 = p->x;
907 y1 = p->y;
908
909 node = node->Next();
910 p = (wxPoint *)node->Data();
911
912 x2 = p->x;
913 y2 = p->y;
914 cx1 = (double)((x1 + x2) / 2);
915 cy1 = (double)((y1 + y2) / 2);
916 cx2 = (double)((cx1 + x2) / 2);
917 cy2 = (double)((cy1 + y2) / 2);
918
919 wx_spline_add_point(x1, y1);
920
921 while ((node = node->Next()) != NULL)
922 {
923 p = (wxPoint *)node->Data();
924 x1 = x2;
925 y1 = y2;
926 x2 = p->x;
927 y2 = p->y;
928 cx4 = (double)(x1 + x2) / 2;
929 cy4 = (double)(y1 + y2) / 2;
930 cx3 = (double)(x1 + cx4) / 2;
931 cy3 = (double)(y1 + cy4) / 2;
932
933 wx_quadratic_spline(cx1, cy1, cx2, cy2, cx3, cy3, cx4, cy4);
934
935 cx1 = cx4;
936 cy1 = cy4;
937 cx2 = (double)(cx1 + x2) / 2;
938 cy2 = (double)(cy1 + y2) / 2;
939 }
940
941 wx_spline_add_point( cx1, cy1 );
942 wx_spline_add_point( x2, y2 );
943
944 wx_spline_draw_point_array( this );
945}
946
947
948
949bool wxDC::CanDrawBitmap(void) const
950{
951 return true ;
952}
953
954
2f1ae414
SC
955bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
956 wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask )
519cb848
SC
957{
958 if (!Ok()) return FALSE;
959 MacVerifySetup() ;
960
961 CGrafPtr sourcePort = (CGrafPtr) source->m_macPort ;
962 PixMapHandle bmappixels = GetGWorldPixMap( sourcePort ) ;
03e11df5
GD
963 RGBColor white = { 0xFFFF, 0xFFFF,0xFFFF} ;
964 RGBColor black = { 0,0,0} ;
965 RGBColor forecolor = m_textForegroundColour.GetPixel();
966 RGBColor backcolor = m_textBackgroundColour.GetPixel();
967 RGBForeColor( &forecolor ) ;
968 RGBBackColor( &backcolor ) ;
519cb848
SC
969
970 if ( LockPixels(bmappixels) )
971 {
972 Rect srcrect , dstrect ;
973 srcrect.top = source->YLOG2DEV(ysrc) ;
974 srcrect.left = source->XLOG2DEV(xsrc) ;
975 srcrect.right = source->XLOG2DEV(xsrc + width ) ;
976 srcrect.bottom = source->YLOG2DEV(ysrc + height) ;
977 dstrect.top = YLOG2DEV(ydest) ;
978 dstrect.left = XLOG2DEV(xdest) ;
979 dstrect.bottom = YLOG2DEV(ydest + height ) ;
980 dstrect.right = XLOG2DEV(xdest + width ) ;
8208e181
SC
981
982 short mode = (logical_func == wxCOPY ? srcCopy :
983 // logical_func == wxCLEAR ? WHITENESS :
984 // logical_func == wxSET ? BLACKNESS :
985 logical_func == wxINVERT ? hilite :
986 // logical_func == wxAND ? MERGECOPY :
987 logical_func == wxOR ? srcOr :
988 logical_func == wxSRC_INVERT ? notSrcCopy :
989 logical_func == wxXOR ? srcXor :
990 // logical_func == wxOR_REVERSE ? MERGEPAINT :
991 // logical_func == wxAND_REVERSE ? SRCERASE :
2f1ae414 992 // logical_func == wxSRC_OR ? srcOr :
8208e181
SC
993 // logical_func == wxSRC_AND ? SRCAND :
994 srcCopy );
995
996 if ( useMask && source->m_macMask )
997 {
998 wxASSERT( mode == srcCopy ) ;
999 if ( LockPixels( GetGWorldPixMap( source->m_macMask ) ) )
1000 {
2f1ae414
SC
1001 CopyMask( GetPortBitMapForCopyBits( sourcePort ) , GetPortBitMapForCopyBits( source->m_macMask ) ,
1002 GetPortBitMapForCopyBits( m_macPort ) ,
8208e181
SC
1003 &srcrect, &srcrect , &dstrect ) ;
1004 UnlockPixels( GetGWorldPixMap( source->m_macMask ) ) ;
1005 }
1006 }
1007 else
1008 {
2f1ae414 1009 CopyBits( GetPortBitMapForCopyBits( sourcePort ) , GetPortBitMapForCopyBits( m_macPort ) ,
8208e181
SC
1010 &srcrect, &dstrect, mode, NULL ) ;
1011 }
519cb848
SC
1012 UnlockPixels( bmappixels ) ;
1013 }
1014
1015 m_macPenInstalled = false ;
1016 m_macBrushInstalled = false ;
1017 m_macFontInstalled = false ;
1018
1019 return TRUE;
1020}
1021
2f1ae414
SC
1022void wxDC::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y,
1023 double angle)
1024{
1025}
1026void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y)
519cb848
SC
1027{
1028 if (!Ok())
1029 return;
1030 MacVerifySetup() ;
1031
1032 long xx = XLOG2DEV(x);
1033 long yy = YLOG2DEV(y);
1034
1035// if (m_pen.GetStyle() != wxTRANSPARENT)
1036 {
1037 MacInstallFont() ;
1038 /*
1039 Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
1040
1041 ::ClipRect( &clip ) ;
1042 */
1043
1044 FontInfo fi ;
1045 ::GetFontInfo( &fi ) ;
1046
1047 yy += fi.ascent ;
1048 ::MoveTo( xx , yy );
1049 if ( m_backgroundMode == wxTRANSPARENT )
1050 {
1051 ::TextMode( srcOr) ;
1052 }
1053 else
1054 {
1055 ::TextMode( srcCopy ) ;
1056 }
1057
1058 const char *text = NULL ;
1059 int length = 0 ;
1060 wxString macText ;
1061
1062 if ( wxApp::s_macDefaultEncodingIsPC )
1063 {
2f1ae414 1064 macText = wxMacMakeMacStringFromPC( strtext ) ;
519cb848
SC
1065 text = macText ;
1066 length = macText.Length() ;
1067 }
1068 else
1069 {
2f1ae414
SC
1070 text = strtext ;
1071 length = strtext.Length() ;
519cb848
SC
1072 }
1073
1074 int laststop = 0 ;
1075 int i = 0 ;
1076 int line = 0 ;
1077
1078 while( i < length )
1079 {
1080 if( text[i] == 13 || text[i] == 10)
1081 {
1082 ::DrawText( text , laststop , i - laststop ) ;
1083 line++ ;
1084 ::MoveTo( xx , yy + line*(fi.descent + fi.ascent + fi.leading) );
1085 laststop = i+1 ;
1086 }
1087 i++ ;
1088 }
1089
1090 ::DrawText( text , laststop , i - laststop ) ;
1091 ::TextMode( srcOr ) ;
1092 }
1093}
1094
1095bool wxDC::CanGetTextExtent(void) const
1096{
1097 if ( !Ok() )
1098 return false ;
1099
1100 return true ;
1101}
1102
2f1ae414
SC
1103void wxDC::DoGetTextExtent( const wxString &string, wxCoord *width, wxCoord *height,
1104 wxCoord *descent, wxCoord *externalLeading ,
1105 wxFont *theFont ) const
519cb848
SC
1106{
1107 if (!Ok())
1108 return;
1109
1110 MacVerifySetup() ;
1111
1112 wxFont formerFont = m_font ;
1113
1114 if ( theFont )
1115 {
1116 wxFontRefData * font = (wxFontRefData*) m_font.GetRefData() ;
1117
1118 if ( font )
1119 {
519cb848 1120 ::TextFont( font->m_macFontNum ) ;
2f1ae414 1121 ::TextSize( YLOG2DEVREL( font->m_macFontSize) ) ;
519cb848
SC
1122 ::TextFace( font->m_macFontStyle ) ;
1123 }
1124 }
1125 else
1126 {
1127 MacInstallFont() ;
1128 }
1129
1130 FontInfo fi ;
1131 ::GetFontInfo( &fi ) ;
1132
2f1ae414
SC
1133 if ( height )
1134 *height = YDEV2LOGREL( fi.descent + fi.ascent ) ;
1135 if ( descent )
1136 *descent =YDEV2LOGREL( fi.descent );
1137 if ( externalLeading )
1138 *externalLeading = YDEV2LOGREL( fi.leading ) ;
519cb848
SC
1139
1140 const char *text = NULL ;
1141 int length = 0 ;
1142 wxString macText ;
1143 if ( wxApp::s_macDefaultEncodingIsPC )
1144 {
1145 macText = wxMacMakeMacStringFromPC( string ) ;
1146 text = macText ;
1147 length = macText.Length() ;
1148 }
1149 else
1150 {
1151 text = string ;
1152 length = string.Length() ;
1153 }
1154
1155 int laststop = 0 ;
1156 int i = 0 ;
1157 int curwidth = 0 ;
2f1ae414 1158 if ( width )
519cb848 1159 {
2f1ae414
SC
1160 *width = 0 ;
1161
1162 while( i < length )
519cb848 1163 {
2f1ae414
SC
1164 if( text[i] == 13 || text[i] == 10)
1165 {
1166 if ( height )
1167 *height += YDEV2LOGREL( fi.descent + fi.ascent + fi.leading ) ;
1168 curwidth = ::TextWidth( text , laststop , i - laststop ) ;
1169 if ( curwidth > *width )
1170 *width = XDEV2LOGREL( curwidth ) ;
1171 laststop = i+1 ;
1172 }
1173 i++ ;
519cb848 1174 }
2f1ae414
SC
1175
1176 curwidth = ::TextWidth( text , laststop , i - laststop ) ;
1177 if ( curwidth > *width )
1178 *width = XDEV2LOGREL( curwidth ) ;
519cb848 1179 }
519cb848
SC
1180
1181 if ( theFont )
1182 {
1183 m_macFontInstalled = false ;
1184 }
1185}
1186
ee41971c 1187wxCoord wxDC::GetCharWidth(void) const
519cb848
SC
1188{
1189 if (!Ok())
1190 return 1;
1191
1192 MacVerifySetup() ;
1193
1194 MacInstallFont() ;
1195
1196 FontInfo fi ;
1197 ::GetFontInfo( &fi ) ;
1198
2f1ae414 1199 return YDEV2LOGREL((fi.descent + fi.ascent) / 2) ;
519cb848
SC
1200}
1201
ee41971c 1202wxCoord wxDC::GetCharHeight(void) const
519cb848
SC
1203{
1204 if (!Ok())
1205 return 1;
1206
1207 MacVerifySetup() ;
1208
1209 MacInstallFont() ;
1210
1211 FontInfo fi ;
1212 ::GetFontInfo( &fi ) ;
1213
2f1ae414 1214 return YDEV2LOGREL( fi.descent + fi.ascent );
519cb848
SC
1215}
1216
1217void wxDC::Clear(void)
1218{
1219 if (!Ok())
1220 return;
1221 MacVerifySetup() ;
1222 Rect rect = { -32767 , -32767 , 32767 , 32767 } ;
1223
1224 if (m_backgroundBrush.GetStyle() != wxTRANSPARENT)
1225 {
1226 MacInstallBrush() ;
1227 ::EraseRect( &rect ) ;
1228 };
1229}
1230
1231void wxDC::MacInstallFont() const
1232{
1233 if (!Ok())
1234 return;
1235 MacVerifySetup() ;
1236
1237 if ( m_macFontInstalled )
1238 return ;
2f1ae414
SC
1239 Pattern blackColor ;
1240
519cb848
SC
1241 wxFontRefData * font = (wxFontRefData*) m_font.GetRefData() ;
1242
1243 if ( font )
1244 {
1245 ::TextFont( font->m_macFontNum ) ;
03e11df5 1246 ::TextSize( short(m_scaleY * font->m_macFontSize) ) ;
519cb848
SC
1247 ::TextFace( font->m_macFontStyle ) ;
1248
1249 m_macFontInstalled = true ;
1250 m_macBrushInstalled = false ;
1251 m_macPenInstalled = false ;
03e11df5
GD
1252
1253 RGBColor forecolor = m_textForegroundColour.GetPixel();
1254 RGBColor backcolor = m_textBackgroundColour.GetPixel();
1255 ::RGBForeColor( &forecolor );
1256 ::RGBBackColor( &backcolor );
519cb848
SC
1257 }
1258 else
1259 {
1260 short fontnum ;
1261
1262 GetFNum( "\pGeneva" , &fontnum ) ;
1263 ::TextFont( fontnum ) ;
03e11df5 1264 ::TextSize( short(m_scaleY * 10) ) ;
519cb848
SC
1265 ::TextFace( 0 ) ;
1266
1267 // todo reset after spacing changes - or store the current spacing somewhere
1268
1269 m_macFontInstalled = true ;
1270 m_macBrushInstalled = false ;
1271 m_macPenInstalled = false ;
519cb848 1272
03e11df5
GD
1273 RGBColor forecolor = m_textForegroundColour.GetPixel();
1274 RGBColor backcolor = m_textBackgroundColour.GetPixel();
1275 ::RGBForeColor( &forecolor );
1276 ::RGBBackColor( &backcolor );
1277 }
519cb848
SC
1278
1279 short mode = patCopy ;
1280
1281 // todo :
1282
1283 switch( m_logicalFunction )
1284 {
1285 case wxCOPY: // src
1286 mode = patCopy ;
1287 break ;
1288 case wxINVERT: // NOT dst
2f1ae414 1289 ::PenPat(GetQDGlobalsBlack(&blackColor));
519cb848
SC
1290 mode = patXor ;
1291 break ;
1292 case wxXOR: // src XOR dst
1293 mode = patXor ;
1294 break ;
1295 case wxOR_REVERSE: // src OR (NOT dst)
1296 mode = notPatOr ;
1297 break ;
1298 case wxSRC_INVERT: // (NOT src)
1299 mode = notPatCopy ;
1300 break ;
1301
1302 // unsupported TODO
1303
1304 case wxCLEAR: // 0
1305 case wxAND_REVERSE:// src AND (NOT dst)
1306 case wxAND: // src AND dst
1307 case wxAND_INVERT: // (NOT src) AND dst
1308 case wxNO_OP: // dst
1309 case wxNOR: // (NOT src) AND (NOT dst)
1310 case wxEQUIV: // (NOT src) XOR dst
1311 case wxOR_INVERT: // (NOT src) OR dst
1312 case wxNAND: // (NOT src) OR (NOT dst)
1313 case wxOR: // src OR dst
1314 case wxSET: // 1
2f1ae414
SC
1315// case wxSRC_OR: // source _bitmap_ OR destination
1316// case wxSRC_AND: // source _bitmap_ AND destination
519cb848
SC
1317 break ;
1318 }
1319 ::PenMode( mode ) ;
1320}
1321
1322static void wxMacGetHatchPattern(int hatchStyle, Pattern *pattern)
1323{
1324 int thePatListID = sysPatListID;
1325 int theIndex;
1326 switch(hatchStyle)
1327 {
1328 case wxBDIAGONAL_HATCH:
1329 theIndex = 34; // WCH: this is not good
1330 break;
1331 case wxFDIAGONAL_HATCH:
1332 theIndex = 26;
1333 break;
1334 case wxCROSS_HATCH:
1335 theIndex = 5;
1336 break;
1337 case wxHORIZONTAL_HATCH:
1338 theIndex = 25;
1339 break;
1340 case wxVERTICAL_HATCH:
1341 theIndex = 6;
1342 break;
1343 case wxCROSSDIAG_HATCH:
1344 theIndex = 4; // WCH: this is not good
1345 break;
1346 default:
1347 theIndex = 1; // solid pattern
1348 break;
1349 }
1350 GetIndPattern( pattern, thePatListID, theIndex);
1351}
1352
1353void wxDC::MacInstallPen() const
1354{
1355 if (!Ok())
1356 return;
1357 MacVerifySetup() ;
1358
2f1ae414
SC
1359 Pattern blackColor;
1360
519cb848
SC
1361 if ( m_macPenInstalled )
1362 return ;
1363
03e11df5
GD
1364 RGBColor forecolor = m_pen.GetColour().GetPixel();
1365 RGBColor backcolor = m_backgroundBrush.GetColour().GetPixel();
1366 ::RGBForeColor( &forecolor );
1367 ::RGBBackColor( &backcolor );
519cb848
SC
1368
1369 ::PenNormal() ;
1370 int penWidth = m_pen.GetWidth();
1371 ::PenSize(penWidth, penWidth);
1372
1373 int penStyle = m_pen.GetStyle();
1374
1375 if (penStyle == wxSOLID)
03e11df5 1376 {
2f1ae414 1377 ::PenPat(GetQDGlobalsBlack(&blackColor));
03e11df5 1378 }
519cb848
SC
1379 else if (IS_HATCH(penStyle))
1380 {
1381 Pattern pat ;
1382 wxMacGetHatchPattern(penStyle, &pat);
1383 ::PenPat(&pat);
1384 }
1385 else
1386 {
2f1ae414 1387 ::PenPat(GetQDGlobalsBlack(&blackColor));
519cb848
SC
1388 }
1389
1390 short mode = patCopy ;
1391
1392 // todo :
1393
1394 switch( m_logicalFunction )
1395 {
1396 case wxCOPY: // src
1397 mode = patCopy ;
1398 break ;
1399 case wxINVERT: // NOT dst
2f1ae414 1400 ::PenPat(GetQDGlobalsBlack(&blackColor));
519cb848
SC
1401 mode = patXor ;
1402 break ;
1403 case wxXOR: // src XOR dst
1404 mode = patXor ;
1405 break ;
1406 case wxOR_REVERSE: // src OR (NOT dst)
1407 mode = notPatOr ;
1408 break ;
1409 case wxSRC_INVERT: // (NOT src)
1410 mode = notPatCopy ;
1411 break ;
1412
1413 // unsupported TODO
1414
1415 case wxCLEAR: // 0
1416 case wxAND_REVERSE:// src AND (NOT dst)
1417 case wxAND: // src AND dst
1418 case wxAND_INVERT: // (NOT src) AND dst
1419 case wxNO_OP: // dst
1420 case wxNOR: // (NOT src) AND (NOT dst)
1421 case wxEQUIV: // (NOT src) XOR dst
1422 case wxOR_INVERT: // (NOT src) OR dst
1423 case wxNAND: // (NOT src) OR (NOT dst)
1424 case wxOR: // src OR dst
1425 case wxSET: // 1
2f1ae414
SC
1426// case wxSRC_OR: // source _bitmap_ OR destination
1427// case wxSRC_AND: // source _bitmap_ AND destination
519cb848
SC
1428 break ;
1429 }
1430 ::PenMode( mode ) ;
1431 m_macPenInstalled = true ;
1432 m_macBrushInstalled = false ;
1433 m_macFontInstalled = false ;
1434}
1435
1436void wxDC::MacInstallBrush() const
1437{
1438 if (!Ok())
1439 return;
1440 MacVerifySetup() ;
2f1ae414 1441 Pattern blackColor, whiteColor ;
519cb848
SC
1442 if ( m_macBrushInstalled )
1443 return ;
1444
1445 // foreground
1446
03e11df5
GD
1447 RGBColor forecolor = m_brush.GetColour().GetPixel();
1448 RGBColor backcolor = m_backgroundBrush.GetColour().GetPixel();
1449 ::RGBForeColor( &forecolor );
1450 ::RGBBackColor( &backcolor );
519cb848
SC
1451
1452 int brushStyle = m_brush.GetStyle();
1453 if (brushStyle == wxSOLID)
2f1ae414 1454 ::PenPat(GetQDGlobalsBlack(&blackColor));
519cb848
SC
1455 else if (IS_HATCH(brushStyle))
1456 {
1457 Pattern pat ;
1458 wxMacGetHatchPattern(brushStyle, &pat);
1459 ::PenPat(&pat);
1460 }
1461 else
1462 {
2f1ae414 1463 ::PenPat(GetQDGlobalsBlack(&blackColor));
519cb848
SC
1464 }
1465
1466
1467 // background
1468
1469 brushStyle = m_backgroundBrush.GetStyle();
1470 if (brushStyle == wxSOLID)
2f1ae414 1471 ::BackPat(GetQDGlobalsWhite(&whiteColor));
519cb848
SC
1472 else if (IS_HATCH(brushStyle))
1473 {
1474 Pattern pat ;
1475 wxMacGetHatchPattern(brushStyle, &pat);
1476 ::BackPat(&pat);
1477 }
1478 else
1479 {
2f1ae414 1480 ::BackPat(GetQDGlobalsWhite(&whiteColor));
519cb848
SC
1481 }
1482
1483 short mode = patCopy ;
1484
1485 // todo :
1486
1487 switch( m_logicalFunction )
1488 {
1489 case wxCOPY: // src
1490 mode = patCopy ;
1491 break ;
1492 case wxINVERT: // NOT dst
2f1ae414 1493 ::PenPat(GetQDGlobalsBlack(&blackColor));
519cb848
SC
1494 mode = patXor ;
1495 break ;
1496 case wxXOR: // src XOR dst
1497 mode = patXor ;
1498 break ;
1499 case wxOR_REVERSE: // src OR (NOT dst)
1500 mode = notPatOr ;
1501 break ;
1502 case wxSRC_INVERT: // (NOT src)
1503 mode = notPatCopy ;
1504 break ;
1505
1506 // unsupported TODO
1507
1508 case wxCLEAR: // 0
1509 case wxAND_REVERSE:// src AND (NOT dst)
1510 case wxAND: // src AND dst
1511 case wxAND_INVERT: // (NOT src) AND dst
1512 case wxNO_OP: // dst
1513 case wxNOR: // (NOT src) AND (NOT dst)
1514 case wxEQUIV: // (NOT src) XOR dst
1515 case wxOR_INVERT: // (NOT src) OR dst
1516 case wxNAND: // (NOT src) OR (NOT dst)
1517 case wxOR: // src OR dst
1518 case wxSET: // 1
2f1ae414
SC
1519// case wxSRC_OR: // source _bitmap_ OR destination
1520// case wxSRC_AND: // source _bitmap_ AND destination
519cb848
SC
1521 break ;
1522 }
1523 ::PenMode( mode ) ;
1524 m_macBrushInstalled = true ;
1525 m_macPenInstalled = false ;
1526 m_macFontInstalled = false ;
1527}
1528
2f1ae414
SC
1529// ---------------------------------------------------------------------------
1530// coordinates transformations
1531// ---------------------------------------------------------------------------
519cb848 1532
2f1ae414
SC
1533
1534wxCoord wxDCBase::DeviceToLogicalX(wxCoord x) const
1535{
1536 return ((wxDC *)this)->XDEV2LOG(x);
1537}
1538
1539wxCoord wxDCBase::DeviceToLogicalY(wxCoord y) const
1540{
1541 return ((wxDC *)this)->YDEV2LOG(y);
1542}
1543
1544wxCoord wxDCBase::DeviceToLogicalXRel(wxCoord x) const
1545{
1546 return ((wxDC *)this)->XDEV2LOGREL(x);
1547}
1548
1549wxCoord wxDCBase::DeviceToLogicalYRel(wxCoord y) const
1550{
1551 return ((wxDC *)this)->YDEV2LOGREL(y);
1552}
1553
1554wxCoord wxDCBase::LogicalToDeviceX(wxCoord x) const
1555{
1556 return ((wxDC *)this)->XLOG2DEV(x);
1557}
1558
1559wxCoord wxDCBase::LogicalToDeviceY(wxCoord y) const
1560{
1561 return ((wxDC *)this)->YLOG2DEV(y);
1562}
1563
1564wxCoord wxDCBase::LogicalToDeviceXRel(wxCoord x) const
1565{
1566 return ((wxDC *)this)->XLOG2DEVREL(x);
1567}
1568
1569wxCoord wxDCBase::LogicalToDeviceYRel(wxCoord y) const
1570{
1571 return ((wxDC *)this)->YLOG2DEVREL(y);
1572}