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