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