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