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