]> git.saurik.com Git - wxWidgets.git/blame - src/cocoa/dc.mm
Workaround for #15404: wxRichTextCtrl: caret does not disappear when focus is lost...
[wxWidgets.git] / src / cocoa / dc.mm
CommitLineData
a24aff65 1/////////////////////////////////////////////////////////////////////////////
891d0563
DE
2// Name: src/cocoa/dc.mm
3// Purpose: wxDC
4// Author: David Elliott
a24aff65 5// Modified by:
891d0563 6// Created: 2003/04/01
891d0563 7// Copyright: (c) 2003 David Elliott
526954c5 8// Licence: wxWindows licence
a24aff65
DE
9/////////////////////////////////////////////////////////////////////////////
10
449c5673 11#include "wx/wxprec.h"
da80ae71 12
938156b2 13#include "wx/cocoa/dc.h"
da80ae71 14
449c5673
DE
15#ifndef WX_PRECOMP
16 #include "wx/log.h"
18680f86 17 #include "wx/math.h" //math constants
449c5673 18#endif //WX_PRECOMP
a24aff65 19
7fc77f30 20#include "wx/cocoa/autorelease.h"
b0c0a393 21#include "wx/cocoa/string.h"
6a5c31c2 22#include "wx/cocoa/ObjcRef.h"
7fc77f30 23
891d0563
DE
24#import <AppKit/NSBezierPath.h>
25#import <AppKit/NSTextStorage.h>
26#import <AppKit/NSLayoutManager.h>
27#import <AppKit/NSTextContainer.h>
28#import <AppKit/NSGraphicsContext.h>
29#import <AppKit/NSAffineTransform.h>
30#import <AppKit/NSColor.h>
f910a887 31#import <AppKit/NSTypesetter.h>
1fd17880 32#import <AppKit/NSImage.h>
891d0563 33
d8418952 34#include "wx/listimpl.cpp"
fe8f7943
DE
35WX_DEFINE_LIST(wxCocoaDCStack);
36
938156b2
DE
37IMPLEMENT_ABSTRACT_CLASS(wxCocoaDCImpl, wxDCImpl)
38
39WX_NSTextStorage wxCocoaDCImpl::sm_cocoaNSTextStorage = nil;
40WX_NSLayoutManager wxCocoaDCImpl::sm_cocoaNSLayoutManager = nil;
41WX_NSTextContainer wxCocoaDCImpl::sm_cocoaNSTextContainer = nil;
42wxCocoaDCStack wxCocoaDCImpl::sm_cocoaDCStack;
891d0563 43
5eb5a0ac
DE
44inline void CocoaSetPenForNSBezierPath(wxPen &pen, NSBezierPath *bezpath)
45{
46 [pen.GetNSColor() set];
4799f3ba 47 const CGFloat *pattern;
5eb5a0ac
DE
48 [bezpath setLineDash:pattern count:pen.GetCocoaLineDash(&pattern) phase:0.0];
49 [bezpath setLineWidth:pen.GetWidth()];
50 switch(pen.GetJoin())
51 {
52 case wxJOIN_BEVEL:
53 [bezpath setLineJoinStyle:NSBevelLineJoinStyle];
54 break;
55 case wxJOIN_ROUND:
56 [bezpath setLineJoinStyle:NSRoundLineJoinStyle];
57 break;
58 case wxJOIN_MITER:
59 [bezpath setLineJoinStyle:NSMiterLineJoinStyle];
60 break;
61 }
62 switch(pen.GetCap())
63 {
64 case wxCAP_ROUND:
65 [bezpath setLineCapStyle:NSRoundLineCapStyle];
66 break;
67 case wxCAP_PROJECTING:
68 [bezpath setLineCapStyle:NSSquareLineCapStyle];
69 break;
70 case wxCAP_BUTT:
71 [bezpath setLineCapStyle:NSButtLineCapStyle];
72 break;
73 }
74}
75
938156b2 76void wxCocoaDCImpl::CocoaInitializeTextSystem()
891d0563 77{
6a5c31c2
DE
78 wxAutoNSAutoreleasePool pool;
79
2b030203 80 wxASSERT_MSG(!sm_cocoaNSTextStorage && !sm_cocoaNSLayoutManager && !sm_cocoaNSTextContainer,wxT("Text system already initalized! BAD PROGRAMMER!"));
891d0563 81
6a5c31c2
DE
82 // FIXME: Never released
83 sm_cocoaNSTextStorage = wxGCSafeRetain([[[NSTextStorage alloc] init] autorelease]);
84
85 // FIXME: Never released
86 sm_cocoaNSLayoutManager = wxGCSafeRetain([[[NSLayoutManager alloc] init] autorelease]);
891d0563 87
891d0563
DE
88 [sm_cocoaNSTextStorage addLayoutManager:sm_cocoaNSLayoutManager];
89 // NSTextStorage retains NSLayoutManager, but so do we
90 // [sm_cocoaNSLayoutManager release]; [sm_cocoaNSLayoutManager retain];
91
92 // NOTE: initWithContainerSize is the designated initializer, but the
93 // Apple CircleView sample gets away with just calling init, which
94 // is all we really need for our purposes.
6a5c31c2
DE
95 // FIXME: Never released
96 sm_cocoaNSTextContainer = wxGCSafeRetain([[[NSTextContainer alloc] init] autorelease]);
891d0563
DE
97 [sm_cocoaNSLayoutManager addTextContainer:sm_cocoaNSTextContainer];
98 // NSLayoutManager retains NSTextContainer, but so do we
99 // [sm_cocoaNSTextContainer release]; [sm_cocoaNSTextContainer retain];
100}
101
938156b2 102void wxCocoaDCImpl::CocoaShutdownTextSystem()
891d0563
DE
103{
104 [sm_cocoaNSTextContainer release]; sm_cocoaNSTextContainer = nil;
105 [sm_cocoaNSLayoutManager release]; sm_cocoaNSLayoutManager = nil;
106 [sm_cocoaNSTextStorage release]; sm_cocoaNSTextStorage = nil;
107}
108
938156b2 109void wxCocoaDCImpl::CocoaUnwindStackAndLoseFocus()
fe8f7943 110{
7ce8248b 111 wxCocoaDCStack::compatibility_iterator ourNode=sm_cocoaDCStack.Find(this);
fe8f7943
DE
112 if(ourNode)
113 {
7ce8248b 114 wxCocoaDCStack::compatibility_iterator node=sm_cocoaDCStack.GetFirst();
fe8f7943
DE
115 for(;node!=ourNode; node=sm_cocoaDCStack.GetFirst())
116 {
938156b2 117 wxCocoaDCImpl *dc = node->GetData();
fe8f7943
DE
118 wxASSERT(dc);
119 wxASSERT(dc!=this);
120 if(!dc->CocoaUnlockFocus())
121 {
2b030203 122 wxFAIL_MSG(wxT("Unable to unlock focus on higher-level DC!"));
fe8f7943 123 }
7ce8248b 124 sm_cocoaDCStack.Erase(node);
fe8f7943
DE
125 }
126 wxASSERT(node==ourNode);
127 wxASSERT(ourNode->GetData() == this);
128 ourNode->GetData()->CocoaUnlockFocus();
7ce8248b 129 sm_cocoaDCStack.Erase(ourNode);
fe8f7943
DE
130 }
131}
132
938156b2 133bool wxCocoaDCImpl::CocoaUnwindStackAndTakeFocus()
fe8f7943 134{
7ce8248b 135 wxCocoaDCStack::compatibility_iterator node=sm_cocoaDCStack.GetFirst();
fe8f7943
DE
136 for(;node;node = sm_cocoaDCStack.GetFirst())
137 {
938156b2 138 wxCocoaDCImpl *dc = node->GetData();
fe8f7943
DE
139 wxASSERT(dc);
140 // If we're on the stack, then it's unwound enough and we have focus
141 if(dc==this)
142 return true;
143 // If unable to unlockFocus (e.g. wxPaintDC) stop here
144 if(!dc->CocoaUnlockFocus())
145 break;
7ce8248b 146 sm_cocoaDCStack.Erase(node);
fe8f7943
DE
147 }
148 return CocoaLockFocus();
149}
150
938156b2
DE
151wxCocoaDCImpl::wxCocoaDCImpl(wxDC *owner)
152: wxDCImpl(owner)
891d0563 153{
db8512fe 154 m_cocoaWxToBoundsTransform = nil;
5eb5a0ac 155 m_pen = *wxBLACK_PEN;
891d0563
DE
156}
157
938156b2 158wxCocoaDCImpl::~wxDC(void)
891d0563 159{
1a1e9ff1 160 [m_cocoaWxToBoundsTransform release];
891d0563
DE
161}
162
938156b2 163bool wxCocoaDCImpl::CocoaLockFocus()
fe8f7943
DE
164{
165 return false;
166}
167
938156b2 168bool wxCocoaDCImpl::CocoaUnlockFocus()
fe8f7943
DE
169{
170 return false;
171}
172
938156b2 173/*static*/ WX_NSAffineTransform wxCocoaDCImpl::CocoaGetWxToBoundsTransform(bool isFlipped, float height)
fe8f7943 174{
4db3c8ac 175 NSAffineTransform *transform = nil;
fe8f7943 176 // This transform flips the graphics since wxDC uses top-left origin
4db3c8ac 177 if(!isFlipped)
fe8f7943
DE
178 {
179 // The transform is auto released
4db3c8ac 180 transform = [NSAffineTransform transform];
fe8f7943
DE
181 /* x' = 1x + 0y + 0
182 y' = 0x + -1y + window's height
183 */
184 NSAffineTransformStruct matrix = {
185 1, 0
186 , 0, -1
4db3c8ac 187 , 0, height
fe8f7943
DE
188 };
189 [transform setTransformStruct: matrix];
fe8f7943 190 }
4db3c8ac
DE
191 return transform;
192}
193
938156b2 194void wxCocoaDCImpl::CocoaApplyTransformations()
4db3c8ac
DE
195{
196 [m_cocoaWxToBoundsTransform concat];
197 // TODO: Apply device/logical/user position/scaling transformations
fe8f7943
DE
198}
199
938156b2 200void wxCocoaDCImpl::CocoaUnapplyTransformations()
3e21fc05
DE
201{
202 // NOTE: You *must* call this with focus held.
203 // Undo all transforms so we're back in true Cocoa coords with
204 // no scaling or flipping.
205 NSAffineTransform *invertTransform;
206 invertTransform = [m_cocoaWxToBoundsTransform copy];
207 [invertTransform invert];
208 [invertTransform concat];
f48ab29b 209 [invertTransform release];
3e21fc05
DE
210}
211
938156b2 212bool wxCocoaDCImpl::CocoaGetBounds(void *rectData)
3e21fc05
DE
213{
214 // We don't know what we are so we can't return anything.
215 return false;
216}
217
938156b2 218void wxCocoaDCImpl::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
891d0563 219{
1b1f8b2d 220 wxAutoNSAutoreleasePool pool;
fe8f7943 221 if(!CocoaTakeFocus()) return;
891d0563 222 NSBezierPath *bezpath = [NSBezierPath bezierPathWithRect:NSMakeRect(x,y,width,height)];
5eb5a0ac 223 CocoaSetPenForNSBezierPath(m_pen,bezpath);
891d0563 224 [bezpath stroke];
c3b0c2c3
DE
225 [m_brush.GetNSColor() set];
226 [bezpath fill];
891d0563
DE
227}
228
938156b2 229void wxCocoaDCImpl::DoDrawLine(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2)
891d0563 230{
1b1f8b2d 231 wxAutoNSAutoreleasePool pool;
fe8f7943 232 if(!CocoaTakeFocus()) return;
891d0563
DE
233 NSBezierPath *bezpath = [NSBezierPath bezierPath];
234 [bezpath moveToPoint:NSMakePoint(x1,y1)];
235 [bezpath lineToPoint:NSMakePoint(x2,y2)];
c3b0c2c3 236
5eb5a0ac 237 CocoaSetPenForNSBezierPath(m_pen,bezpath);
891d0563
DE
238 [bezpath stroke];
239}
240
938156b2 241void wxCocoaDCImpl::DoGetTextExtent(const wxString& text, wxCoord *x, wxCoord *y, wxCoord *descent, wxCoord *externalLeading, const wxFont *theFont) const
891d0563 242{
7fc77f30 243 wxAutoNSAutoreleasePool pool;
891d0563 244// FIXME: Cache this so it can be used for DoDrawText
2b030203 245 wxASSERT_MSG(sm_cocoaNSTextStorage && sm_cocoaNSLayoutManager && sm_cocoaNSTextContainer, wxT("Text system has not been initialized. BAD PROGRAMMER!"));
891d0563 246 NSAttributedString *attributedString = [[NSAttributedString alloc]
b0c0a393 247 initWithString:wxNSStringWithWxString(text.c_str())];
891d0563
DE
248 [sm_cocoaNSTextStorage setAttributedString:attributedString];
249 [attributedString release];
250
251 NSRange glyphRange = [sm_cocoaNSLayoutManager glyphRangeForTextContainer:sm_cocoaNSTextContainer];
252 NSRect usedRect = [sm_cocoaNSLayoutManager usedRectForTextContainer:sm_cocoaNSTextContainer];
253 if(x)
dc483f61 254 *x=(int)usedRect.size.width;
891d0563 255 if(y)
dc483f61 256 *y=(int)usedRect.size.height;
891d0563
DE
257 if(descent)
258 *descent=0;
259 if(externalLeading)
260 *externalLeading=0;
261}
262
938156b2 263void wxCocoaDCImpl::DoDrawText(const wxString& text, wxCoord x, wxCoord y)
891d0563 264{
1b1f8b2d 265 wxAutoNSAutoreleasePool pool;
fe8f7943 266 if(!CocoaTakeFocus()) return;
2b030203 267 wxASSERT_MSG(sm_cocoaNSTextStorage && sm_cocoaNSLayoutManager && sm_cocoaNSTextContainer, wxT("Text system has not been initialized. BAD PROGRAMMER!"));
891d0563 268 NSAttributedString *attributedString = [[NSAttributedString alloc]
b0c0a393 269 initWithString:wxNSStringWithWxString(text.c_str())];
891d0563
DE
270 [sm_cocoaNSTextStorage setAttributedString:attributedString];
271 [attributedString release];
272
c0440c78
DE
273 // Set the color (and later font) attributes
274 NSColor *fgColor = m_textForegroundColour.GetNSColor();
275 NSColor *bgColor = m_textBackgroundColour.GetNSColor();
276 if(!fgColor)
277 fgColor = [NSColor clearColor];
278 if(!bgColor)
279 bgColor = [NSColor clearColor];
280 NSDictionary *attrDict = [[NSDictionary alloc] initWithObjectsAndKeys:
281 fgColor, NSForegroundColorAttributeName,
282 bgColor, NSBackgroundColorAttributeName,
283 nil];
284 [sm_cocoaNSTextStorage addAttributes: attrDict range:NSMakeRange(0,[sm_cocoaNSTextStorage length])];
285 [attrDict release];
286
891d0563
DE
287 NSRange glyphRange = [sm_cocoaNSLayoutManager glyphRangeForTextContainer:sm_cocoaNSTextContainer];
288 NSRect usedRect = [sm_cocoaNSLayoutManager usedRectForTextContainer:sm_cocoaNSTextContainer];
13fc3db4
DE
289 // NOTE: We'll crash trying to get the location of glyphAtIndex:0 if
290 // there is no length or we don't start at zero
291 if(!glyphRange.length)
292 return;
2b030203 293 wxASSERT_MSG(glyphRange.location==0,wxT("glyphRange must begin at zero"));
891d0563
DE
294
295 NSAffineTransform *transform = [NSAffineTransform transform];
296 [transform translateXBy:x yBy:y];
297
298 NSAffineTransform *flipTransform = [NSAffineTransform transform];
299 /* x' = 1x + 0y + 0
300 y' = 0x + -1y + window's height
301 */
302 NSAffineTransformStruct matrix = {
303 1, 0
304 , 0, -1
305 , 0, usedRect.size.height
306 };
307 [flipTransform setTransformStruct: matrix];
308
309 NSGraphicsContext *context = [NSGraphicsContext currentContext];
310 [context saveGraphicsState];
311 [transform concat];
312 [flipTransform concat];
c3b0c2c3 313 #if 0
891d0563 314 // Draw+fill a rectangle so we can see where the shit is supposed to be.
48580976 315 wxLogTrace(wxTRACE_COCOA,wxT("(%f,%f) (%fx%f)"),usedRect.origin.x,usedRect.origin.y,usedRect.size.width,usedRect.size.height);
891d0563
DE
316 NSBezierPath *bezpath = [NSBezierPath bezierPathWithRect:NSMakeRect(0,0,usedRect.size.width,usedRect.size.height)];
317 [[NSColor blackColor] set];
318 [bezpath stroke];
319 [[NSColor blueColor] set];
320 [bezpath fill];
c3b0c2c3 321 #endif
891d0563
DE
322
323 NSPoint layoutLocation = [sm_cocoaNSLayoutManager locationForGlyphAtIndex:0];
324 layoutLocation.x = 0.0;
325 layoutLocation.y *= -1.0;
e7e97a59
DE
326
327 // Save the location as is for underlining
328 NSPoint underlineLocation = layoutLocation;
329
330 // Offset the location by the baseline for drawing the glyphs.
891d0563 331 layoutLocation.y += [[sm_cocoaNSLayoutManager typesetter] baselineOffsetInLayoutManager:sm_cocoaNSLayoutManager glyphIndex:0];
e7e97a59 332
c0440c78
DE
333 if(m_backgroundMode==wxSOLID)
334 [sm_cocoaNSLayoutManager drawBackgroundForGlyphRange:glyphRange atPoint:NSZeroPoint];
891d0563
DE
335 [sm_cocoaNSLayoutManager drawGlyphsForGlyphRange:glyphRange atPoint:layoutLocation];
336
e7e97a59
DE
337 int underlineStyle = GetFont().GetUnderlined() ? NSUnderlineStyleSingle : NSUnderlineStyleNone;
338 NSRange lineGlyphRange;
339 NSRect lineRect = [sm_cocoaNSLayoutManager lineFragmentRectForGlyphAtIndex:0 effectiveRange:&lineGlyphRange];
340
341 [sm_cocoaNSLayoutManager underlineGlyphRange:glyphRange underlineType:underlineStyle
342 lineFragmentRect:lineRect lineFragmentGlyphRange:lineGlyphRange
343 containerOrigin:underlineLocation];
344
891d0563
DE
345 [context restoreGraphicsState];
346}
347
348///////////////////////////////////////////////////////////////////////////
349// cut here, the rest is stubs
350///////////////////////////////////////////////////////////////////////////
a24aff65 351
a24aff65
DE
352//-----------------------------------------------------------------------------
353// wxDC
354//-----------------------------------------------------------------------------
355
938156b2 356void wxCocoaDCImpl::DoDrawIcon( const wxIcon &WXUNUSED(icon), int WXUNUSED(x), int WXUNUSED(y) )
a24aff65
DE
357{
358};
359
938156b2 360void wxCocoaDCImpl::DoDrawPoint( int x, int y )
da80ae71 361{
a24aff65
DE
362};
363
4787c92d 364void wxCocoaDCImpl::DoDrawPolygon( int, const wxPoint *, int, int, wxPolygonFillMode)
a24aff65
DE
365{
366};
367
4787c92d 368void wxCocoaDCImpl::DoDrawLines( int, const wxPoint *, int, int )
a24aff65
DE
369{
370}
371
938156b2 372int wxCocoaDCImpl::GetDepth() const
a24aff65
DE
373{
374 return 0;
375}
376
938156b2 377wxSize wxCocoaDCImpl::GetPPI() const
a24aff65
DE
378{
379 return wxSize(0,0);
380}
381
938156b2 382bool wxCocoaDCImpl::CanGetTextExtent() const
a24aff65
DE
383{
384 return false;
385}
386
938156b2 387wxCoord wxCocoaDCImpl::GetCharHeight() const
a24aff65
DE
388{
389 return 0;
390}
391
938156b2 392wxCoord wxCocoaDCImpl::GetCharWidth() const
a24aff65
DE
393{
394 return 0;
395}
396
938156b2 397bool wxCocoaDCImpl::CanDrawBitmap() const
a24aff65 398{
1fd17880 399 return true;
a24aff65
DE
400}
401
938156b2 402bool wxCocoaDCImpl::DoGetPixel(wxCoord x, wxCoord y, wxColour *col) const
a24aff65
DE
403{
404 return false;
405}
406
938156b2 407void wxCocoaDCImpl::DoDrawArc(wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2, wxCoord xc, wxCoord yc)
a24aff65
DE
408{
409}
da80ae71 410
938156b2 411void wxCocoaDCImpl::SetFont(const wxFont& font)
e7e97a59
DE
412{
413 m_font = font;
414}
415
938156b2 416void wxCocoaDCImpl::SetPen(const wxPen& pen)
a24aff65 417{
5eb5a0ac 418 m_pen = pen;
a24aff65
DE
419}
420
938156b2 421void wxCocoaDCImpl::SetBrush(const wxBrush& brush)
a24aff65 422{
c3b0c2c3 423 m_brush = brush;
a24aff65
DE
424}
425
938156b2 426void wxCocoaDCImpl::DoSetClippingRegionAsRegion(const wxRegion& region)
a24aff65
DE
427{
428}
429
938156b2 430void wxCocoaDCImpl::DoSetClippingRegion(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
a24aff65
DE
431{
432}
433
938156b2 434void wxCocoaDCImpl::DestroyClippingRegion()
a24aff65
DE
435{
436}
437
938156b2 438void wxCocoaDCImpl::DoDrawRoundedRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height, double radius)
a24aff65
DE
439{
440}
441
938156b2 442void wxCocoaDCImpl::DoDrawRotatedText(const wxString& text, wxCoord x, wxCoord y, double angle)
a24aff65
DE
443{
444}
445
938156b2 446void wxCocoaDCImpl::DoDrawEllipticArc(wxCoord x, wxCoord y, wxCoord w, wxCoord h, double sa, double ea)
a24aff65
DE
447{
448}
449
938156b2 450void wxCocoaDCImpl::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
a24aff65
DE
451{
452}
453
938156b2 454void wxCocoaDCImpl::DoDrawBitmap(const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask)
a24aff65 455{
1b1f8b2d 456 wxAutoNSAutoreleasePool pool;
fe8f7943 457 if(!CocoaTakeFocus()) return;
a1b806b9 458 if(!bmp.IsOk())
1fd17880
DE
459 return;
460
461#if 0
462 // Draw a rect so we can see where it's supposed to be
48580976 463 wxLogTrace(wxTRACE_COCOA,wxT("image at (%d,%d) size %dx%d"),x,y,bmp.GetWidth(),bmp.GetHeight());
1fd17880
DE
464 NSBezierPath *bezpath = [NSBezierPath bezierPathWithRect:NSMakeRect(x,y,bmp.GetWidth(),bmp.GetHeight())];
465 [[NSColor blackColor] set];
466 [bezpath stroke];
467 [[NSColor blueColor] set];
468 [bezpath fill];
469#endif // 0
470
471 NSAffineTransform *transform = [NSAffineTransform transform];
472 [transform translateXBy:x yBy:y];
473
474 NSAffineTransform *flipTransform = [NSAffineTransform transform];
475 /* x' = 1x + 0y + 0
476 y' = 0x + -1y + window's height
477 */
478 NSAffineTransformStruct matrix = {
479 1, 0
480 , 0, -1
481 , 0, bmp.GetHeight()
482 };
483 [flipTransform setTransformStruct: matrix];
484
485 NSGraphicsContext *context = [NSGraphicsContext currentContext];
486 [context saveGraphicsState];
487 [transform concat];
488 [flipTransform concat];
489
a00daa65
DE
490 NSImage *nsimage = [bmp.GetNSImage(useMask) retain];
491
1fd17880
DE
492 [nsimage drawAtPoint: NSMakePoint(0,0)
493 fromRect: NSMakeRect(0.0,0.0,bmp.GetWidth(),bmp.GetHeight())
a00daa65 494 operation: NSCompositeSourceOver
1fd17880 495 fraction: 1.0];
da80ae71 496
1fd17880
DE
497 [nsimage release];
498 [context restoreGraphicsState];
a24aff65
DE
499}
500
89efaf2b 501bool wxCocoaDCImpl::DoFloodFill(wxCoord x, wxCoord y, const wxColour& col, wxFloodFillStyle style)
a24aff65
DE
502{
503 return false;
504}
505
938156b2 506void wxCocoaDCImpl::DoCrossHair(wxCoord x, wxCoord y)
a24aff65
DE
507{
508}
509
a24aff65 510
89efaf2b 511bool wxCocoaDCImpl::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height, wxDC *source, wxCoord xsrc, wxCoord ysrc, wxRasterOperationMode rop, bool useMask , wxCoord xsrcMask, wxCoord ysrcMask)
2c23fe91
DE
512{
513 if(!CocoaTakeFocus()) return false;
514 if(!source) return false;
938156b2
DE
515 wxCocoaDCImpl *sourceImpl = static_cast<wxCocoaDCImpl*>(source->GetImpl());
516 return sourceImpl->CocoaDoBlitOnFocusedDC(xdest,ydest,width,height,
2c23fe91
DE
517 xsrc, ysrc, rop, useMask, xsrcMask, ysrcMask);
518}
519
938156b2 520bool wxCocoaDCImpl::CocoaDoBlitOnFocusedDC(wxCoord xdest, wxCoord ydest,
2c23fe91
DE
521 wxCoord width, wxCoord height, wxCoord xsrc, wxCoord ysrc,
522 int logicalFunc, bool useMask, wxCoord xsrcMask, wxCoord ysrcMask)
a24aff65
DE
523{
524 return false;
525}
526
938156b2 527void wxCocoaDCImpl::DoGetSize( int* width, int* height ) const
a24aff65
DE
528{
529 *width = m_maxX-m_minX;
530 *height = m_maxY-m_minY;
531};
532
938156b2 533void wxCocoaDCImpl::DoGetSizeMM( int* width, int* height ) const
a24aff65
DE
534{
535 int w = 0;
536 int h = 0;
938156b2 537 DoGetSize( &w, &h );
a24aff65
DE
538};
539
938156b2 540void wxCocoaDCImpl::SetTextForeground( const wxColour &col )
a24aff65 541{
a1b806b9 542// if (!IsOk()) return;
a24aff65
DE
543 m_textForegroundColour = col;
544};
545
938156b2 546void wxCocoaDCImpl::SetTextBackground( const wxColour &col )
a24aff65 547{
a1b806b9 548// if (!IsOk()) return;
a24aff65
DE
549 m_textBackgroundColour = col;
550};
551
938156b2 552void wxCocoaDCImpl::Clear()
a24aff65 553{
3e21fc05
DE
554 if(!CocoaTakeFocus()) return;
555
556 NSRect boundsRect;
557 if(!CocoaGetBounds(&boundsRect)) return;
558
559 NSGraphicsContext *context = [NSGraphicsContext currentContext];
560 [context saveGraphicsState];
561
562 // Undo all transforms so when we draw our bounds rect we
563 // really overwrite our bounds rect.
564 CocoaUnapplyTransformations();
565
566 [m_backgroundBrush.GetNSColor() set];
567 [NSBezierPath fillRect:boundsRect];
568
569 [context restoreGraphicsState];
a24aff65
DE
570}
571
938156b2 572void wxCocoaDCImpl::SetBackground(const wxBrush& brush)
a24aff65 573{
7bc429ef 574 m_backgroundBrush = brush;
a24aff65
DE
575}
576
938156b2 577void wxCocoaDCImpl::SetPalette(const wxPalette&)
a24aff65
DE
578{
579}
580
89efaf2b 581void wxCocoaDCImpl::SetLogicalFunction(wxRasterOperationMode)
a24aff65
DE
582{
583}
584
585
89efaf2b 586void wxCocoaDCImpl::SetMapMode( wxMappingMode mode )
a24aff65 587{
da80ae71 588 switch (mode)
a24aff65
DE
589 {
590 case wxMM_TWIPS:
591 break;
592 case wxMM_POINTS:
593 break;
594 case wxMM_METRIC:
595 break;
596 case wxMM_LOMETRIC:
597 break;
598 default:
599 case wxMM_TEXT:
600 SetLogicalScale( 1.0, 1.0 );
601 break;
602 };
603 if (mode != wxMM_TEXT)
604 {
605 };
606};
607
938156b2 608void wxCocoaDCImpl::SetUserScale( double x, double y )
a24aff65
DE
609{
610 // allow negative ? -> no
611 m_userScaleX = x;
612 m_userScaleY = y;
613 ComputeScaleAndOrigin();
614};
615
938156b2 616void wxCocoaDCImpl::SetLogicalScale( double x, double y )
a24aff65
DE
617{
618 // allow negative ?
619 m_logicalScaleX = x;
620 m_logicalScaleY = y;
621 ComputeScaleAndOrigin();
622};
623
938156b2 624void wxCocoaDCImpl::SetLogicalOrigin( wxCoord x, wxCoord y )
a24aff65
DE
625{
626 m_logicalOriginX = x * m_signX; // is this still correct ?
627 m_logicalOriginY = y * m_signY;
628 ComputeScaleAndOrigin();
629};
630
938156b2 631void wxCocoaDCImpl::SetDeviceOrigin( wxCoord x, wxCoord y )
a24aff65
DE
632{
633 ComputeScaleAndOrigin();
634};
635
938156b2 636void wxCocoaDCImpl::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
a24aff65
DE
637{
638 m_signX = (xLeftRight ? 1 : -1);
639 m_signY = (yBottomUp ? -1 : 1);
640 ComputeScaleAndOrigin();
641};
642
938156b2 643void wxCocoaDCImpl::ComputeScaleAndOrigin(void)
a24aff65
DE
644{
645 // CMB: copy scale to see if it changes
646 double origScaleX = m_scaleX;
647 double origScaleY = m_scaleY;
648
649 m_scaleX = m_logicalScaleX * m_userScaleX;
650 m_scaleY = m_logicalScaleY * m_userScaleY;
651
da80ae71 652 // CMB: if scale has changed call SetPen to recalulate the line width
a24aff65
DE
653 if (m_scaleX != origScaleX || m_scaleY != origScaleY)
654 {
938156b2 655#if 0
a24aff65
DE
656 // this is a bit artificial, but we need to force wxDC to think
657 // the pen has changed
10c5f652 658 const wxPen* pen = & GetPen();
a24aff65
DE
659 wxPen tempPen;
660 m_pen = tempPen;
661 SetPen(* pen);
938156b2 662#endif
a24aff65
DE
663 }
664};