]> git.saurik.com Git - wxWidgets.git/blob - src/mac/carbon/dc.cpp
adapted to mac
[wxWidgets.git] / src / mac / carbon / dc.cpp
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
19 IMPLEMENT_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
33 long wxDC::m_macCurrentPortId = 1 ;
34
35 //-----------------------------------------------------------------------------
36 // wxDC
37 //-----------------------------------------------------------------------------
38
39 wxDC::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
66 m_mappingMode = wxMM_TEXT;
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;
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 ) ;
102 };
103
104 wxDC::~wxDC(void)
105 {
106 if ( m_macPort )
107 {
108 ::SetOrigin( 0 , 0 ) ;
109 ::ClipRect( &m_macPort->portRect ) ;
110 ::PenNormal() ;
111 ::SetPort( m_macOrigPort ) ;
112 }
113 ++m_macCurrentPortId ;
114 };
115
116 void 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
128 void 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
199 void wxDC::DrawIcon( const wxIcon &icon, long x, long y, bool useMask )
200 {
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 }
218 };
219
220 void wxDC::DrawPoint( wxPoint& point )
221 {
222 DrawPoint( point.x, point.y );
223 };
224
225 void 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
241 void 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
257 void 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
273 void 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
280 void wxDC::SetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
281 {
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);
303 long y2 = YLOG2DEV(m_clipY2);
304
305 Rect clip = { y1 , x1 , y2 , x2 } ;
306
307 ::ClipRect( &clip ) ;
308
309 };
310
311 void wxDC::SetClippingRegion(const wxRect& rect)
312 {
313 SetClippingRegion(rect.x, rect.y, rect.width, rect.height);
314 }
315
316 void wxDC::DestroyClippingRegion(void)
317 {
318 MacVerifySetup() ;
319 m_clipping = FALSE;
320 // Rect clip = { -32000 , -32000 , 32000 , 32000 } ;
321 ::ClipRect(&m_macClipRect);
322 };
323
324 void 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
337 void 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
350 void 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
358 void wxDC::GetSize( int* width, int* height ) const
359 {
360 *width = m_maxX-m_minX;
361 *height = m_maxY-m_minY;
362 };
363
364 void 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
373 void wxDC::SetTextForeground( const wxColour &col )
374 {
375 if (!Ok()) return;
376 m_textForegroundColour = col;
377 m_macFontInstalled = false ;
378 };
379
380 void wxDC::SetTextBackground( const wxColour &col )
381 {
382 if (!Ok()) return;
383 m_textBackgroundColour = col;
384 m_macFontInstalled = false ;
385 };
386
387 void wxDC::SetMapMode( int mode )
388 {
389 switch (mode)
390 {
391 case wxMM_TWIPS:
392 SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
393 break;
394 case wxMM_POINTS:
395 SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
396 break;
397 case wxMM_METRIC:
398 SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
399 break;
400 case wxMM_LOMETRIC:
401 SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
402 break;
403 default:
404 case wxMM_TEXT:
405 SetLogicalScale( 1.0, 1.0 );
406 break;
407 };
408 if (mode != wxMM_TEXT)
409 {
410 m_needComputeScaleX = TRUE;
411 m_needComputeScaleY = TRUE;
412 };
413 };
414
415 void wxDC::SetUserScale( double x, double y )
416 {
417 // allow negative ? -> no
418 m_userScaleX = x;
419 m_userScaleY = y;
420 ComputeScaleAndOrigin();
421 };
422
423 void wxDC::GetUserScale( double *x, double *y )
424 {
425 if (x) *x = m_userScaleX;
426 if (y) *y = m_userScaleY;
427 };
428
429 void wxDC::SetLogicalScale( double x, double y )
430 {
431 // allow negative ?
432 m_logicalScaleX = x;
433 m_logicalScaleY = y;
434 ComputeScaleAndOrigin();
435 };
436
437 void wxDC::GetLogicalScale( double *x, double *y )
438 {
439 if (x) *x = m_logicalScaleX;
440 if (y) *y = m_logicalScaleY;
441 };
442
443 void 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
450 void wxDC::GetLogicalOrigin( long *x, long *y )
451 {
452 if (x) *x = m_logicalOriginX;
453 if (y) *y = m_logicalOriginY;
454 };
455
456 void wxDC::SetDeviceOrigin( long x, long y )
457 {
458 m_externalDeviceOriginX = x;
459 m_externalDeviceOriginY = y;
460 ComputeScaleAndOrigin();
461 };
462
463 void 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
471 void wxDC::SetInternalDeviceOrigin( long x, long y )
472 {
473 m_internalDeviceOriginX = x;
474 m_internalDeviceOriginY = y;
475 ComputeScaleAndOrigin();
476 };
477
478 void wxDC::GetInternalDeviceOrigin( long *x, long *y )
479 {
480 if (x) *x = m_internalDeviceOriginX;
481 if (y) *y = m_internalDeviceOriginY;
482 };
483
484 void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
485 {
486 m_signX = (xLeftRight ? 1 : -1);
487 m_signY = (yBottomUp ? -1 : 1);
488 ComputeScaleAndOrigin();
489 };
490
491 long wxDC::DeviceToLogicalX(long x) const
492 {
493 return XDEV2LOG(x);
494 };
495
496 long wxDC::DeviceToLogicalY(long y) const
497 {
498 return YDEV2LOG(y);
499 };
500
501 long wxDC::DeviceToLogicalXRel(long x) const
502 {
503 return XDEV2LOGREL(x);
504 };
505
506 long wxDC::DeviceToLogicalYRel(long y) const
507 {
508 return YDEV2LOGREL(y);
509 };
510
511 long wxDC::LogicalToDeviceX(long x) const
512 {
513 return XLOG2DEV(x);
514 };
515
516 long wxDC::LogicalToDeviceY(long y) const
517 {
518 return YLOG2DEV(y);
519 };
520
521 long wxDC::LogicalToDeviceXRel(long x) const
522 {
523 return XLOG2DEVREL(x);
524 };
525
526 long wxDC::LogicalToDeviceYRel(long y) const
527 {
528 return YLOG2DEVREL(y);
529 };
530
531 void 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
539 void 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
563 void wxDC::SetPalette( const wxPalette& palette )
564 {
565 }
566
567 void wxDC::SetBackgroundMode( int mode )
568 {
569 m_backgroundMode = mode ;
570 }
571
572 void 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
583 void 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
601 void 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
614 void 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
630 void 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
641 void wxDC::FloodFill( long x1, long y1, const wxColour& col, int style )
642 {
643 }
644
645 bool wxDC::GetPixel( long x1, long y1, wxColour *col ) const
646 {
647 return true ;
648 }
649
650 void 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
671 void wxDC::CrossHair( long x, long y )
672 {
673 }
674
675 void wxDC::DrawArc( long x1, long y1, long x2, long y2, long xc, long yc )
676 {
677 }
678
679 void wxDC::DrawEllipticArc( long x, long y, long width, long height, double sa, double ea )
680 {
681 }
682
683 void 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
701 void 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
726 void 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
761 void 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
804 void 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
850 void 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
895 static void wx_quadratic_spline(double a1, double b1, double a2, double b2,
896 double a3, double b3, double a4, double b4);
897 static void wx_clear_stack(void);
898 static int wx_spline_pop(double *x1, double *y1, double *x2, double *y2, double *x3,
899 double *y3, double *x4, double *y4);
900 static void wx_spline_push(double x1, double y1, double x2, double y2, double x3, double y3,
901 double x4, double y4);
902 static bool wx_spline_add_point(double x, double y);
903 static void wx_spline_draw_point_array(wxDC *dc);
904
905 static wxList wx_spline_point_list;
906
907 #define half(z1, z2) ((z1+z2)/2.0)
908 #define THRESHOLD 5
909
910 /* iterative version */
911
912 static 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
939 typedef struct wx_spline_stack_struct {
940 double x1, y1, x2, y2, x3, y3, x4, y4;
941 } Stack;
942
943 #define SPLINE_STACK_DEPTH 20
944 static Stack wx_spline_stack[SPLINE_STACK_DEPTH];
945 static Stack *wx_stack_top;
946 static int wx_stack_count;
947
948 static void wx_clear_stack(void)
949 {
950 wx_stack_top = wx_spline_stack;
951 wx_stack_count = 0;
952 }
953
954 static 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
968 static 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
986 static 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
995 static 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
1008 void 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
1060 bool wxDC::CanDrawBitmap(void) const
1061 {
1062 return true ;
1063 }
1064
1065
1066 bool 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
1117 void 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
1186 bool wxDC::CanGetTextExtent(void) const
1187 {
1188 if ( !Ok() )
1189 return false ;
1190
1191 return true ;
1192 }
1193
1194 void 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
1274 wxCoord wxDC::GetCharWidth(void) const
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
1289 wxCoord wxDC::GetCharHeight(void) const
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
1304 void 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
1318 void 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
1404 static 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
1435 void 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
1512 void 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