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