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