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