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