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