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