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