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