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