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