1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/mac/carbon/dccg.cpp
4 // Author: Stefan Csomor
8 // Copyright: (c) Stefan Csomor
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
12 #include "wx/wxprec.h"
16 #if wxMAC_USE_CORE_GRAPHICS
21 #include "wx/dcmemory.h"
22 #include "wx/dcprint.h"
23 #include "wx/region.h"
27 #include "wx/mac/uma.h"
33 // in case our functions were defined outside std, we make it known all the same
39 #include "wx/mac/private.h"
41 IMPLEMENT_ABSTRACT_CLASS(wxDC
, wxObject
)
43 #ifndef wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
44 #define wxMAC_USE_CORE_GRAPHICS_BLEND_MODES 0
47 #if MAC_OS_X_VERSION_MAX_ALLOWED <= MAC_OS_X_VERSION_10_4
48 typedef float CGFloat
;
51 //-----------------------------------------------------------------------------
53 //-----------------------------------------------------------------------------
55 #if !defined( __DARWIN__ ) || defined(__MWERKS__)
57 const double M_PI
= 3.14159265358979 ;
61 const double RAD2DEG
= 180.0 / M_PI
;
62 const short kEmulatedMode
= -1 ;
63 const short kUnsupportedMode
= -2 ;
65 extern TECObjectRef s_TECNativeCToUnicode
;
69 // The textctrl implementation still needs that (needs what?) for the non-HIView implementation
71 wxMacWindowClipper::wxMacWindowClipper( const wxWindow
* win
) :
72 wxMacPortSaver( (GrafPtr
) GetWindowPort( (WindowRef
) win
->MacGetTopLevelWindowRef() ) )
74 m_newPort
= (GrafPtr
) GetWindowPort( (WindowRef
) win
->MacGetTopLevelWindowRef() ) ;
75 m_formerClip
= NewRgn() ;
76 m_newClip
= NewRgn() ;
77 GetClip( m_formerClip
) ;
81 // guard against half constructed objects, this just leads to a empty clip
85 win
->MacWindowToRootWindow( &x
, &y
) ;
87 // get area including focus rect
88 CopyRgn( (RgnHandle
) ((wxWindow
*)win
)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip
) ;
89 if ( !EmptyRgn( m_newClip
) )
90 OffsetRgn( m_newClip
, x
, y
) ;
93 SetClip( m_newClip
) ;
97 wxMacWindowClipper::~wxMacWindowClipper()
99 SetPort( m_newPort
) ;
100 SetClip( m_formerClip
) ;
101 DisposeRgn( m_newClip
) ;
102 DisposeRgn( m_formerClip
) ;
105 wxMacWindowStateSaver::wxMacWindowStateSaver( const wxWindow
* win
) :
106 wxMacWindowClipper( win
)
108 // the port is already set at this point
109 m_newPort
= (GrafPtr
) GetWindowPort( (WindowRef
) win
->MacGetTopLevelWindowRef() ) ;
110 GetThemeDrawingState( &m_themeDrawingState
) ;
113 wxMacWindowStateSaver::~wxMacWindowStateSaver()
115 SetPort( m_newPort
) ;
116 SetThemeDrawingState( m_themeDrawingState
, true ) ;
119 // minimal implementation only used for appearance drawing < 10.3
121 wxMacPortSetter::wxMacPortSetter( const wxDC
* dc
) :
122 m_ph( (GrafPtr
) dc
->m_macPort
)
124 wxASSERT( dc
->Ok() ) ;
127 // dc->MacSetupPort(&m_ph) ;
130 wxMacPortSetter::~wxMacPortSetter()
132 // m_dc->MacCleanupPort(&m_ph) ;
135 //-----------------------------------------------------------------------------
137 //-----------------------------------------------------------------------------
139 static inline double dmin(double a
, double b
) { return a
< b
? a
: b
; }
140 static inline double dmax(double a
, double b
) { return a
> b
? a
: b
; }
141 static inline double DegToRad(double deg
) { return (deg
* M_PI
) / 180.0; }
143 //-----------------------------------------------------------------------------
144 // device context implementation
146 // more and more of the dc functionality should be implemented by calling
147 // the appropricate wxMacCGContext, but we will have to do that step by step
148 // also coordinate conversions should be moved to native matrix ops
149 //-----------------------------------------------------------------------------
151 // we always stock two context states, one at entry, to be able to preserve the
152 // state we were called with, the other one after changing to HI Graphics orientation
153 // (this one is used for getting back clippings etc)
155 //-----------------------------------------------------------------------------
156 // wxGraphicPath implementation
157 //-----------------------------------------------------------------------------
159 wxMacCGPath::wxMacCGPath()
161 m_path
= CGPathCreateMutable() ;
164 wxMacCGPath::~wxMacCGPath()
166 CGPathRelease( m_path
) ;
169 // opens (starts) a new subpath
170 void wxMacCGPath::MoveToPoint( wxCoord x1
, wxCoord y1
)
172 CGPathMoveToPoint( m_path
, NULL
, x1
, y1
) ;
175 void wxMacCGPath::AddLineToPoint( wxCoord x1
, wxCoord y1
)
177 CGPathAddLineToPoint( m_path
, NULL
, x1
, y1
) ;
180 void wxMacCGPath::AddQuadCurveToPoint( wxCoord cx1
, wxCoord cy1
, wxCoord x1
, wxCoord y1
)
182 CGPathAddQuadCurveToPoint( m_path
, NULL
, cx1
, cy1
, x1
, y1
);
185 void wxMacCGPath::AddRectangle( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
187 CGRect cgRect
= { { x
, y
} , { w
, h
} } ;
188 CGPathAddRect( m_path
, NULL
, cgRect
) ;
191 void wxMacCGPath::AddCircle( wxCoord x
, wxCoord y
, wxCoord r
)
193 CGPathAddArc( m_path
, NULL
, x
, y
, r
, 0.0 , 2 * M_PI
, true ) ;
196 // closes the current subpath
197 void wxMacCGPath::CloseSubpath()
199 CGPathCloseSubpath( m_path
) ;
202 CGPathRef
wxMacCGPath::GetPath() const
207 void wxMacCGPath::AddArcToPoint( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
, wxCoord r
)
209 CGPathAddArcToPoint( m_path
, NULL
, x1
, y1
, x2
, y2
, r
);
212 void wxMacCGPath::AddArc( wxCoord x
, wxCoord y
, wxCoord r
, double startAngle
, double endAngle
, bool clockwise
)
214 CGPathAddArc( m_path
, NULL
, x
, y
, r
, startAngle
, endAngle
, clockwise
);
217 //-----------------------------------------------------------------------------
218 // wxGraphicContext implementation
219 //-----------------------------------------------------------------------------
221 wxMacCGContext::wxMacCGContext( CGrafPtr port
)
225 m_mode
= kCGPathFill
;
226 m_macATSUIStyle
= NULL
;
229 wxMacCGContext::wxMacCGContext( CGContextRef cgcontext
)
232 m_cgContext
= cgcontext
;
233 m_mode
= kCGPathFill
;
234 m_macATSUIStyle
= NULL
;
235 CGContextSaveGState( m_cgContext
) ;
236 CGContextSaveGState( m_cgContext
) ;
239 wxMacCGContext::wxMacCGContext()
243 m_mode
= kCGPathFill
;
244 m_macATSUIStyle
= NULL
;
247 wxMacCGContext::~wxMacCGContext()
251 CGContextSynchronize( m_cgContext
) ;
252 CGContextRestoreGState( m_cgContext
) ;
253 CGContextRestoreGState( m_cgContext
) ;
257 CGContextRelease( m_cgContext
) ;
261 void wxMacCGContext::Clip( const wxRegion
®ion
)
263 // ClipCGContextToRegion ( m_cgContext, &bounds , (RgnHandle) dc->m_macCurrentClipRgn ) ;
266 void wxMacCGContext::StrokePath( const wxGraphicPath
*p
)
268 const wxMacCGPath
* path
= dynamic_cast< const wxMacCGPath
*>( p
) ;
269 CGContextAddPath( m_cgContext
, path
->GetPath() ) ;
270 CGContextStrokePath( m_cgContext
) ;
273 void wxMacCGContext::DrawPath( const wxGraphicPath
*p
, int fillStyle
)
275 const wxMacCGPath
* path
= dynamic_cast< const wxMacCGPath
*>( p
) ;
276 CGPathDrawingMode mode
= m_mode
;
278 if ( fillStyle
== wxODDEVEN_RULE
)
280 if ( mode
== kCGPathFill
)
281 mode
= kCGPathEOFill
;
282 else if ( mode
== kCGPathFillStroke
)
283 mode
= kCGPathEOFillStroke
;
286 CGContextAddPath( m_cgContext
, path
->GetPath() ) ;
287 CGContextDrawPath( m_cgContext
, mode
) ;
290 void wxMacCGContext::FillPath( const wxGraphicPath
*p
, const wxColor
&fillColor
, int fillStyle
)
292 const wxMacCGPath
* path
= dynamic_cast< const wxMacCGPath
*>( p
) ;
293 CGContextSaveGState( m_cgContext
) ;
295 RGBColor col
= MAC_WXCOLORREF( fillColor
.GetPixel() ) ;
296 CGContextSetRGBFillColor( m_cgContext
, col
.red
/ 65536.0 , col
.green
/ 65536.0 , col
.blue
/ 65536.0 , 1.0 ) ;
297 CGPathDrawingMode mode
= kCGPathFill
;
299 if ( fillStyle
== wxODDEVEN_RULE
)
300 mode
= kCGPathEOFill
;
302 CGContextBeginPath( m_cgContext
) ;
303 CGContextAddPath( m_cgContext
, path
->GetPath() ) ;
304 CGContextClosePath( m_cgContext
) ;
305 CGContextDrawPath( m_cgContext
, mode
) ;
307 CGContextRestoreGState( m_cgContext
) ;
310 wxGraphicPath
* wxMacCGContext::CreatePath()
312 // make sure that we now have a real cgref, before doing
313 // anything with paths
314 CGContextRef cg
= GetNativeContext() ;
317 return new wxMacCGPath() ;
320 // in case we only got a QDPort only create a cgref now
322 CGContextRef
wxMacCGContext::GetNativeContext()
324 if ( m_cgContext
== NULL
)
327 GetPortBounds( (CGrafPtr
) m_qdPort
, &bounds
) ;
328 OSStatus status
= CreateCGContextForPort((CGrafPtr
) m_qdPort
, &m_cgContext
) ;
329 CGContextSaveGState( m_cgContext
) ;
331 wxASSERT_MSG( status
== noErr
, wxT("Cannot nest wxDCs on the same window") ) ;
333 CGContextTranslateCTM( m_cgContext
, 0 , bounds
.bottom
- bounds
.top
) ;
334 CGContextScaleCTM( m_cgContext
, 1 , -1 ) ;
336 CGContextSaveGState( m_cgContext
) ;
338 SetBrush( m_brush
) ;
344 void wxMacCGContext::SetNativeContext( CGContextRef cg
)
346 // we allow either setting or clearing but not replacing
347 wxASSERT( m_cgContext
== NULL
|| cg
== NULL
) ;
350 CGContextSaveGState( cg
) ;
354 void wxMacCGContext::Translate( wxCoord dx
, wxCoord dy
)
356 CGContextTranslateCTM( m_cgContext
, dx
, dy
);
359 void wxMacCGContext::Scale( wxCoord xScale
, wxCoord yScale
)
361 CGContextScaleCTM( m_cgContext
, xScale
, yScale
) ;
364 void wxMacCGContext::DrawBitmap( const wxBitmap
&bmp
, wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
366 CGImageRef image
= (CGImageRef
)( bmp
.CGImageCreate() ) ;
367 HIRect r
= CGRectMake( x
, y
, w
, h
) ;
368 HIViewDrawCGImage( m_cgContext
, &r
, image
) ;
369 CGImageRelease( image
) ;
372 void wxMacCGContext::DrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
)
374 CGRect r
= CGRectMake( 00 , 00 , w
, h
) ;
375 CGContextSaveGState( m_cgContext
);
376 CGContextTranslateCTM( m_cgContext
, x
, y
+ h
);
377 CGContextScaleCTM( m_cgContext
, 1, -1 );
378 PlotIconRefInContext( m_cgContext
, &r
, kAlignNone
, kTransformNone
,
379 NULL
, kPlotIconRefNormalFlags
, MAC_WXHICON( icon
.GetHICON() ) ) ;
380 CGContextRestoreGState( m_cgContext
) ;
383 void wxMacCGContext::PushState()
385 CGContextSaveGState( m_cgContext
);
388 void wxMacCGContext::PopState()
390 CGContextRestoreGState( m_cgContext
);
393 void wxMacCGContext::SetTextColor( const wxColour
&col
)
395 m_textForegroundColor
= col
;
399 #pragma mark wxMacCGPattern, ImagePattern, HatchPattern classes
401 // CGPattern wrapper class: always allocate on heap, never call destructor
408 // is guaranteed to be called only with a non-Null CGContextRef
409 virtual void Render( CGContextRef ctxRef
) = 0 ;
411 operator CGPatternRef() const { return m_patternRef
; }
414 virtual ~wxMacCGPattern()
416 // as this is called only when the m_patternRef is been released;
417 // don't release it again
420 static void _Render( void *info
, CGContextRef ctxRef
)
422 wxMacCGPattern
* self
= (wxMacCGPattern
*) info
;
423 if ( self
&& ctxRef
)
424 self
->Render( ctxRef
) ;
427 static void _Dispose( void *info
)
429 wxMacCGPattern
* self
= (wxMacCGPattern
*) info
;
433 CGPatternRef m_patternRef
;
435 static const CGPatternCallbacks ms_Callbacks
;
438 const CGPatternCallbacks
wxMacCGPattern::ms_Callbacks
= { 0, &wxMacCGPattern::_Render
, &wxMacCGPattern::_Dispose
};
440 class ImagePattern
: public wxMacCGPattern
443 ImagePattern( const wxBitmap
* bmp
, CGAffineTransform transform
)
445 wxASSERT( bmp
&& bmp
->Ok() ) ;
447 Init( (CGImageRef
) bmp
->CGImageCreate() , transform
) ;
450 // ImagePattern takes ownership of CGImageRef passed in
451 ImagePattern( CGImageRef image
, CGAffineTransform transform
)
456 Init( image
, transform
) ;
459 virtual void Render( CGContextRef ctxRef
)
462 HIViewDrawCGImage( ctxRef
, &m_imageBounds
, m_image
);
466 void Init( CGImageRef image
, CGAffineTransform transform
)
471 m_imageBounds
= CGRectMake( 0.0, 0.0, (CGFloat
)CGImageGetWidth( m_image
), (CGFloat
)CGImageGetHeight( m_image
) ) ;
472 m_patternRef
= CGPatternCreate(
473 this , m_imageBounds
, transform
,
474 m_imageBounds
.size
.width
, m_imageBounds
.size
.height
,
475 kCGPatternTilingNoDistortion
, true , &wxMacCGPattern::ms_Callbacks
) ;
479 virtual ~ImagePattern()
482 CGImageRelease( m_image
) ;
486 CGRect m_imageBounds
;
489 class HatchPattern
: public wxMacCGPattern
492 HatchPattern( int hatchstyle
, CGAffineTransform transform
)
494 m_hatch
= hatchstyle
;
495 m_imageBounds
= CGRectMake( 0.0, 0.0, 8.0 , 8.0 ) ;
496 m_patternRef
= CGPatternCreate(
497 this , m_imageBounds
, transform
,
498 m_imageBounds
.size
.width
, m_imageBounds
.size
.height
,
499 kCGPatternTilingNoDistortion
, false , &wxMacCGPattern::ms_Callbacks
) ;
502 void StrokeLineSegments( CGContextRef ctxRef
, const CGPoint pts
[] , size_t count
)
504 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
505 if ( UMAGetSystemVersion() >= 0x1040 )
507 CGContextStrokeLineSegments( ctxRef
, pts
, count
) ;
512 CGContextBeginPath( ctxRef
);
513 for (size_t i
= 0; i
< count
; i
+= 2)
515 CGContextMoveToPoint(ctxRef
, pts
[i
].x
, pts
[i
].y
);
516 CGContextAddLineToPoint(ctxRef
, pts
[i
+1].x
, pts
[i
+1].y
);
518 CGContextStrokePath(ctxRef
);
522 virtual void Render( CGContextRef ctxRef
)
526 case wxBDIAGONAL_HATCH
:
530 { 8.0 , 0.0 } , { 0.0 , 8.0 }
532 StrokeLineSegments( ctxRef
, pts
, 2 ) ;
536 case wxCROSSDIAG_HATCH
:
540 { 0.0 , 0.0 } , { 8.0 , 8.0 } ,
541 { 8.0 , 0.0 } , { 0.0 , 8.0 }
543 StrokeLineSegments( ctxRef
, pts
, 4 ) ;
547 case wxFDIAGONAL_HATCH
:
551 { 0.0 , 0.0 } , { 8.0 , 8.0 }
553 StrokeLineSegments( ctxRef
, pts
, 2 ) ;
561 { 0.0 , 4.0 } , { 8.0 , 4.0 } ,
562 { 4.0 , 0.0 } , { 4.0 , 8.0 } ,
564 StrokeLineSegments( ctxRef
, pts
, 4 ) ;
568 case wxHORIZONTAL_HATCH
:
572 { 0.0 , 4.0 } , { 8.0 , 4.0 } ,
574 StrokeLineSegments( ctxRef
, pts
, 2 ) ;
578 case wxVERTICAL_HATCH
:
582 { 4.0 , 0.0 } , { 4.0 , 8.0 } ,
584 StrokeLineSegments( ctxRef
, pts
, 2 ) ;
594 virtual ~HatchPattern() {}
596 CGRect m_imageBounds
;
602 void wxMacCGContext::SetPen( const wxPen
&pen
)
605 if ( m_cgContext
== NULL
)
608 bool fill
= m_brush
.GetStyle() != wxTRANSPARENT
;
609 bool stroke
= pen
.GetStyle() != wxTRANSPARENT
;
612 // we can benchmark performance; should go into a setting eventually
613 CGContextSetShouldAntialias( m_cgContext
, false ) ;
619 m_mode
= kCGPathFill
; // just a default
623 CGContextSetRGBStrokeColor( m_cgContext
, pen
.GetColour().Red() / 255.0 , pen
.GetColour().Green() / 255.0 ,
624 pen
.GetColour().Blue() / 255.0 , pen
.GetColour().Alpha() / 255.0 ) ;
626 // TODO: * m_dc->m_scaleX
627 CGFloat penWidth
= pen
.GetWidth();
630 CGContextSetLineWidth( m_cgContext
, penWidth
) ;
633 switch ( pen
.GetCap() )
636 cap
= kCGLineCapRound
;
639 case wxCAP_PROJECTING
:
640 cap
= kCGLineCapSquare
;
644 cap
= kCGLineCapButt
;
648 cap
= kCGLineCapButt
;
653 switch ( pen
.GetJoin() )
656 join
= kCGLineJoinBevel
;
660 join
= kCGLineJoinMiter
;
664 join
= kCGLineJoinRound
;
668 join
= kCGLineJoinMiter
;
672 m_mode
= kCGPathStroke
;
675 const CGFloat
*lengths
= NULL
;
676 CGFloat
*userLengths
= NULL
;
678 const CGFloat dashUnit
= penWidth
< 1.0 ? 1.0 : penWidth
;
680 const CGFloat dotted
[] = { dashUnit
, dashUnit
+ 2.0 };
681 const CGFloat short_dashed
[] = { 9.0 , 6.0 };
682 const CGFloat dashed
[] = { 19.0 , 9.0 };
683 const CGFloat dotted_dashed
[] = { 9.0 , 6.0 , 3.0 , 3.0 };
685 switch ( pen
.GetStyle() )
692 count
= WXSIZEOF(dotted
);
697 count
= WXSIZEOF(dashed
) ;
701 lengths
= short_dashed
;
702 count
= WXSIZEOF(short_dashed
) ;
706 lengths
= dotted_dashed
;
707 count
= WXSIZEOF(dotted_dashed
);
712 count
= pen
.GetDashes( &dashes
) ;
713 if ((dashes
!= NULL
) && (count
> 0))
715 userLengths
= new CGFloat
[count
] ;
716 for ( int i
= 0 ; i
< count
; ++i
)
718 userLengths
[i
] = dashes
[i
] * dashUnit
;
720 if ( i
% 2 == 1 && userLengths
[i
] < dashUnit
+ 2.0 )
721 userLengths
[i
] = dashUnit
+ 2.0 ;
722 else if ( i
% 2 == 0 && userLengths
[i
] < dashUnit
)
723 userLengths
[i
] = dashUnit
;
726 lengths
= userLengths
;
731 CGFloat alphaArray
[1] = { 1.0 } ;
732 wxBitmap
* bmp
= pen
.GetStipple() ;
733 if ( bmp
&& bmp
->Ok() )
735 wxMacCFRefHolder
<CGColorSpaceRef
> patternSpace( CGColorSpaceCreatePattern( NULL
) ) ;
736 CGContextSetStrokeColorSpace( m_cgContext
, patternSpace
) ;
737 wxMacCFRefHolder
<CGPatternRef
> pattern( *( new ImagePattern( bmp
, CGContextGetCTM( m_cgContext
) ) ) );
738 CGContextSetStrokePattern( m_cgContext
, pattern
, alphaArray
) ;
745 wxMacCFRefHolder
<CGColorSpaceRef
> patternSpace( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ) ;
746 CGContextSetStrokeColorSpace( m_cgContext
, patternSpace
) ;
747 wxMacCFRefHolder
<CGPatternRef
> pattern( *( new HatchPattern( pen
.GetStyle() , CGContextGetCTM( m_cgContext
) ) ) );
749 CGFloat colorArray
[4] = { pen
.GetColour().Red() / 255.0 , pen
.GetColour().Green() / 255.0 ,
750 pen
.GetColour().Blue() / 255.0 , pen
.GetColour().Alpha() / 255.0 } ;
752 CGContextSetStrokePattern( m_cgContext
, pattern
, colorArray
) ;
757 if ((lengths
!= NULL
) && (count
> 0))
759 CGContextSetLineDash( m_cgContext
, 0 , lengths
, count
) ;
760 // force the line cap, otherwise we get artifacts (overlaps) and just solid lines
761 cap
= kCGLineCapButt
;
765 CGContextSetLineDash( m_cgContext
, 0 , NULL
, 0 ) ;
768 CGContextSetLineCap( m_cgContext
, cap
) ;
769 CGContextSetLineJoin( m_cgContext
, join
) ;
771 delete[] userLengths
;
774 if ( fill
&& stroke
)
775 m_mode
= kCGPathFillStroke
;
779 void wxMacCGContext::SetBrush( const wxBrush
&brush
)
782 if ( m_cgContext
== NULL
)
785 bool fill
= brush
.GetStyle() != wxTRANSPARENT
;
786 bool stroke
= m_pen
.GetStyle() != wxTRANSPARENT
;
789 // we can benchmark performance, should go into a setting later
790 CGContextSetShouldAntialias( m_cgContext
, false ) ;
796 m_mode
= kCGPathFill
; // just a default
800 if ( brush
.GetStyle() == wxSOLID
)
802 CGContextSetRGBFillColor( m_cgContext
, brush
.GetColour().Red() / 255.0 , brush
.GetColour().Green() / 255.0 ,
803 brush
.GetColour().Blue() / 255.0 , brush
.GetColour().Alpha() / 255.0 ) ;
805 else if ( brush
.IsHatch() )
807 wxMacCFRefHolder
<CGColorSpaceRef
> patternSpace( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ) ;
808 CGContextSetFillColorSpace( m_cgContext
, patternSpace
) ;
809 wxMacCFRefHolder
<CGPatternRef
> pattern( *( new HatchPattern( brush
.GetStyle() , CGContextGetCTM( m_cgContext
) ) ) );
811 CGFloat colorArray
[4] = { brush
.GetColour().Red() / 255.0 , brush
.GetColour().Green() / 255.0 ,
812 brush
.GetColour().Blue() / 255.0 , brush
.GetColour().Alpha() / 255.0 } ;
814 CGContextSetFillPattern( m_cgContext
, pattern
, colorArray
) ;
818 // now brush is a bitmap
819 CGFloat alphaArray
[1] = { 1.0 } ;
820 wxBitmap
* bmp
= brush
.GetStipple() ;
821 if ( bmp
&& bmp
->Ok() )
823 wxMacCFRefHolder
<CGColorSpaceRef
> patternSpace( CGColorSpaceCreatePattern( NULL
) ) ;
824 CGContextSetFillColorSpace( m_cgContext
, patternSpace
) ;
825 wxMacCFRefHolder
<CGPatternRef
> pattern( *( new ImagePattern( bmp
, CGContextGetCTM( m_cgContext
) ) ) );
826 CGContextSetFillPattern( m_cgContext
, pattern
, alphaArray
) ;
830 m_mode
= kCGPathFill
;
833 if ( fill
&& stroke
)
834 m_mode
= kCGPathFillStroke
;
836 m_mode
= kCGPathStroke
;
840 void wxMacCGContext::DrawText( const wxString
&str
, wxCoord x
, wxCoord y
, double angle
)
842 OSStatus status
= noErr
;
843 ATSUTextLayout atsuLayout
;
844 UniCharCount chars
= str
.length() ;
845 UniChar
* ubuf
= NULL
;
847 #if SIZEOF_WCHAR_T == 4
848 wxMBConvUTF16 converter
;
850 size_t unicharlen
= converter
.WC2MB( NULL
, str
.wc_str() , 0 ) ;
851 ubuf
= (UniChar
*) malloc( unicharlen
+ 2 ) ;
852 converter
.WC2MB( (char*) ubuf
, str
.wc_str(), unicharlen
+ 2 ) ;
854 const wxWCharBuffer wchar
= str
.wc_str( wxConvLocal
) ;
855 size_t unicharlen
= converter
.WC2MB( NULL
, wchar
.data() , 0 ) ;
856 ubuf
= (UniChar
*) malloc( unicharlen
+ 2 ) ;
857 converter
.WC2MB( (char*) ubuf
, wchar
.data() , unicharlen
+ 2 ) ;
859 chars
= unicharlen
/ 2 ;
862 ubuf
= (UniChar
*) str
.wc_str() ;
864 wxWCharBuffer wchar
= str
.wc_str( wxConvLocal
) ;
865 chars
= wxWcslen( wchar
.data() ) ;
866 ubuf
= (UniChar
*) wchar
.data() ;
870 status
= ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr
) ubuf
, 0 , chars
, chars
, 1 ,
871 &chars
, (ATSUStyle
*) &m_macATSUIStyle
, &atsuLayout
) ;
873 wxASSERT_MSG( status
== noErr
, wxT("couldn't create the layout of the rotated text") );
875 status
= ::ATSUSetTransientFontMatching( atsuLayout
, true ) ;
876 wxASSERT_MSG( status
== noErr
, wxT("couldn't setup transient font matching") );
878 int iAngle
= int( angle
);
879 if ( abs(iAngle
) > 0 )
881 Fixed atsuAngle
= IntToFixed( iAngle
) ;
882 ATSUAttributeTag atsuTags
[] =
884 kATSULineRotationTag
,
886 ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
890 ATSUAttributeValuePtr atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
894 status
= ::ATSUSetLayoutControls(atsuLayout
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
),
895 atsuTags
, atsuSizes
, atsuValues
) ;
899 ATSUAttributeTag atsuTags
[] =
903 ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
905 sizeof( CGContextRef
) ,
907 ATSUAttributeValuePtr atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
911 status
= ::ATSUSetLayoutControls(atsuLayout
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
),
912 atsuTags
, atsuSizes
, atsuValues
) ;
915 ATSUTextMeasurement textBefore
, textAfter
;
916 ATSUTextMeasurement ascent
, descent
;
918 status
= ::ATSUGetUnjustifiedBounds( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
,
919 &textBefore
, &textAfter
, &ascent
, &descent
);
921 wxASSERT_MSG( status
== noErr
, wxT("couldn't measure the rotated text") );
926 if ( m_backgroundMode == wxSOLID )
928 wxGraphicPath* path = m_graphicContext->CreatePath() ;
929 path->MoveToPoint( drawX , drawY ) ;
930 path->AddLineToPoint(
931 (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent)) ,
932 (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent)) ) ;
933 path->AddLineToPoint(
934 (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ,
935 (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent) - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ) ;
936 path->AddLineToPoint(
937 (int) (drawX + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ,
938 (int) (drawY - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ) ;
940 m_graphicContext->FillPath( path , m_textBackgroundColour ) ;
944 x
+= (int)(sin(angle
/ RAD2DEG
) * FixedToInt(ascent
));
945 y
+= (int)(cos(angle
/ RAD2DEG
) * FixedToInt(ascent
));
947 status
= ::ATSUMeasureTextImage( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
,
948 IntToFixed(x
) , IntToFixed(y
) , &rect
);
949 wxASSERT_MSG( status
== noErr
, wxT("couldn't measure the rotated text") );
951 CGContextSaveGState(m_cgContext
);
952 CGContextTranslateCTM(m_cgContext
, x
, y
);
953 CGContextScaleCTM(m_cgContext
, 1, -1);
954 status
= ::ATSUDrawText( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
,
955 IntToFixed(0) , IntToFixed(0) );
957 wxASSERT_MSG( status
== noErr
, wxT("couldn't draw the rotated text") );
959 CGContextRestoreGState(m_cgContext
) ;
961 ::ATSUDisposeTextLayout(atsuLayout
);
963 #if SIZEOF_WCHAR_T == 4
968 void wxMacCGContext::GetTextExtent( const wxString
&str
, wxCoord
*width
, wxCoord
*height
,
969 wxCoord
*descent
, wxCoord
*externalLeading
) const
971 wxCHECK_RET( m_macATSUIStyle
!= NULL
, wxT("wxDC(cg)::DoGetTextExtent - no valid font set") ) ;
973 OSStatus status
= noErr
;
975 ATSUTextLayout atsuLayout
;
976 UniCharCount chars
= str
.length() ;
977 UniChar
* ubuf
= NULL
;
979 #if SIZEOF_WCHAR_T == 4
980 wxMBConvUTF16 converter
;
982 size_t unicharlen
= converter
.WC2MB( NULL
, str
.wc_str() , 0 ) ;
983 ubuf
= (UniChar
*) malloc( unicharlen
+ 2 ) ;
984 converter
.WC2MB( (char*) ubuf
, str
.wc_str(), unicharlen
+ 2 ) ;
986 const wxWCharBuffer wchar
= str
.wc_str( wxConvLocal
) ;
987 size_t unicharlen
= converter
.WC2MB( NULL
, wchar
.data() , 0 ) ;
988 ubuf
= (UniChar
*) malloc( unicharlen
+ 2 ) ;
989 converter
.WC2MB( (char*) ubuf
, wchar
.data() , unicharlen
+ 2 ) ;
991 chars
= unicharlen
/ 2 ;
994 ubuf
= (UniChar
*) str
.wc_str() ;
996 wxWCharBuffer wchar
= str
.wc_str( wxConvLocal
) ;
997 chars
= wxWcslen( wchar
.data() ) ;
998 ubuf
= (UniChar
*) wchar
.data() ;
1002 status
= ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr
) ubuf
, 0 , chars
, chars
, 1 ,
1003 &chars
, (ATSUStyle
*) &m_macATSUIStyle
, &atsuLayout
) ;
1005 wxASSERT_MSG( status
== noErr
, wxT("couldn't create the layout of the text") );
1007 ATSUTextMeasurement textBefore
, textAfter
;
1008 ATSUTextMeasurement textAscent
, textDescent
;
1010 status
= ::ATSUGetUnjustifiedBounds( atsuLayout
, kATSUFromTextBeginning
, kATSUToTextEnd
,
1011 &textBefore
, &textAfter
, &textAscent
, &textDescent
);
1014 *height
= FixedToInt(textAscent
+ textDescent
) ;
1016 *descent
= FixedToInt(textDescent
) ;
1017 if ( externalLeading
)
1018 *externalLeading
= 0 ;
1020 *width
= FixedToInt(textAfter
- textBefore
) ;
1022 ::ATSUDisposeTextLayout(atsuLayout
);
1025 void wxMacCGContext::GetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const
1028 widths
.Add(0, text
.length());
1033 ATSUTextLayout atsuLayout
;
1034 UniCharCount chars
= text
.length() ;
1035 UniChar
* ubuf
= NULL
;
1037 #if SIZEOF_WCHAR_T == 4
1038 wxMBConvUTF16 converter
;
1040 size_t unicharlen
= converter
.WC2MB( NULL
, text
.wc_str() , 0 ) ;
1041 ubuf
= (UniChar
*) malloc( unicharlen
+ 2 ) ;
1042 converter
.WC2MB( (char*) ubuf
, text
.wc_str(), unicharlen
+ 2 ) ;
1044 const wxWCharBuffer wchar
= text
.wc_str( wxConvLocal
) ;
1045 size_t unicharlen
= converter
.WC2MB( NULL
, wchar
.data() , 0 ) ;
1046 ubuf
= (UniChar
*) malloc( unicharlen
+ 2 ) ;
1047 converter
.WC2MB( (char*) ubuf
, wchar
.data() , unicharlen
+ 2 ) ;
1049 chars
= unicharlen
/ 2 ;
1052 ubuf
= (UniChar
*) text
.wc_str() ;
1054 wxWCharBuffer wchar
= text
.wc_str( wxConvLocal
) ;
1055 chars
= wxWcslen( wchar
.data() ) ;
1056 ubuf
= (UniChar
*) wchar
.data() ;
1061 status
= ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr
) ubuf
, 0 , chars
, chars
, 1 ,
1062 &chars
, (ATSUStyle
*) &m_macATSUIStyle
, &atsuLayout
) ;
1064 for ( int pos
= 0; pos
< (int)chars
; pos
++ )
1066 unsigned long actualNumberOfBounds
= 0;
1067 ATSTrapezoid glyphBounds
;
1069 // We get a single bound, since the text should only require one. If it requires more, there is an issue
1071 result
= ATSUGetGlyphBounds( atsuLayout
, 0, 0, kATSUFromTextBeginning
, pos
+ 1,
1072 kATSUseDeviceOrigins
, 1, &glyphBounds
, &actualNumberOfBounds
);
1073 if (result
!= noErr
|| actualNumberOfBounds
!= 1 )
1076 widths
[pos
] = FixedToInt( glyphBounds
.upperRight
.x
- glyphBounds
.upperLeft
.x
);
1077 //unsigned char uch = s[i];
1080 ::ATSUDisposeTextLayout(atsuLayout
);
1083 void wxMacCGContext::SetFont( const wxFont
&font
)
1085 if ( m_macATSUIStyle
)
1087 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUIStyle
);
1088 m_macATSUIStyle
= NULL
;
1095 status
= ATSUCreateAndCopyStyle( (ATSUStyle
) font
.MacGetATSUStyle() , (ATSUStyle
*) &m_macATSUIStyle
) ;
1097 wxASSERT_MSG( status
== noErr
, wxT("couldn't create ATSU style") ) ;
1099 // we need the scale here ...
1101 Fixed atsuSize
= IntToFixed( int( /*m_scaleY*/ 1 * font
.MacGetFontSize()) ) ;
1102 RGBColor atsuColor
= MAC_WXCOLORREF( m_textForegroundColor
.GetPixel() ) ;
1103 ATSUAttributeTag atsuTags
[] =
1108 ByteCount atsuSizes
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
1111 sizeof( RGBColor
) ,
1113 ATSUAttributeValuePtr atsuValues
[sizeof(atsuTags
) / sizeof(ATSUAttributeTag
)] =
1119 status
= ::ATSUSetAttributes(
1120 (ATSUStyle
)m_macATSUIStyle
, sizeof(atsuTags
) / sizeof(ATSUAttributeTag
) ,
1121 atsuTags
, atsuSizes
, atsuValues
);
1123 wxASSERT_MSG( status
== noErr
, wxT("couldn't modify ATSU style") ) ;
1134 m_mm_to_pix_x
= mm2pt
;
1135 m_mm_to_pix_y
= mm2pt
;
1137 m_externalDeviceOriginX
= 0;
1138 m_externalDeviceOriginY
= 0;
1139 m_logicalScaleX
= 1.0;
1140 m_logicalScaleY
= 1.0;
1145 m_needComputeScaleX
=
1146 m_needComputeScaleY
= false;
1149 m_macLocalOrigin
.x
=
1150 m_macLocalOrigin
.y
= 0 ;
1152 m_pen
= *wxBLACK_PEN
;
1153 m_font
= *wxNORMAL_FONT
;
1154 m_brush
= *wxWHITE_BRUSH
;
1156 m_macATSUIStyle
= NULL
;
1157 m_graphicContext
= NULL
;
1162 if ( m_macATSUIStyle
)
1164 ::ATSUDisposeStyle((ATSUStyle
)m_macATSUIStyle
);
1165 m_macATSUIStyle
= NULL
;
1168 delete m_graphicContext
;
1171 void wxDC::DoDrawBitmap( const wxBitmap
&bmp
, wxCoord x
, wxCoord y
, bool useMask
)
1173 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawBitmap - invalid DC") );
1174 wxCHECK_RET( bmp
.Ok(), wxT("wxDC(cg)::DoDrawBitmap - invalid bitmap") );
1176 wxCoord xx
= XLOG2DEVMAC(x
);
1177 wxCoord yy
= YLOG2DEVMAC(y
);
1178 wxCoord w
= bmp
.GetWidth();
1179 wxCoord h
= bmp
.GetHeight();
1180 wxCoord ww
= XLOG2DEVREL(w
);
1181 wxCoord hh
= YLOG2DEVREL(h
);
1183 m_graphicContext
->DrawBitmap( bmp
, xx
, yy
, ww
, hh
) ;
1186 void wxDC::DoDrawIcon( const wxIcon
&icon
, wxCoord x
, wxCoord y
)
1188 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawIcon - invalid DC") );
1189 wxCHECK_RET( icon
.Ok(), wxT("wxDC(cg)::DoDrawIcon - invalid icon") );
1191 wxCoord xx
= XLOG2DEVMAC(x
);
1192 wxCoord yy
= YLOG2DEVMAC(y
);
1193 wxCoord w
= icon
.GetWidth();
1194 wxCoord h
= icon
.GetHeight();
1195 wxCoord ww
= XLOG2DEVREL(w
);
1196 wxCoord hh
= YLOG2DEVREL(h
);
1198 m_graphicContext
->DrawIcon( icon
, xx
, yy
, ww
, hh
) ;
1201 void wxDC::DoSetClippingRegion( wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
1203 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoSetClippingRegion - invalid DC") );
1205 wxCoord xx
, yy
, ww
, hh
;
1206 xx
= XLOG2DEVMAC(x
);
1207 yy
= YLOG2DEVMAC(y
);
1208 ww
= XLOG2DEVREL(width
);
1209 hh
= YLOG2DEVREL(height
);
1211 CGContextRef cgContext
= ((wxMacCGContext
*)(m_graphicContext
))->GetNativeContext() ;
1212 CGRect clipRect
= CGRectMake( xx
, yy
, ww
, hh
) ;
1213 CGContextClipToRect( cgContext
, clipRect
) ;
1215 // SetRectRgn( (RgnHandle) m_macCurrentClipRgn , xx , yy , xx + ww , yy + hh ) ;
1216 // SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
1220 m_clipX1
= wxMax( m_clipX1
, xx
);
1221 m_clipY1
= wxMax( m_clipY1
, yy
);
1222 m_clipX2
= wxMin( m_clipX2
, (xx
+ ww
) );
1223 m_clipY2
= wxMin( m_clipY2
, (yy
+ hh
) );
1235 // TODO: as soon as we don't reset the context for each operation anymore
1236 // we have to update the context as well
1239 void wxDC::DoSetClippingRegionAsRegion( const wxRegion
®ion
)
1241 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoSetClippingRegionAsRegion - invalid DC") );
1245 DestroyClippingRegion();
1250 region
.GetBox( x
, y
, w
, h
);
1251 wxCoord xx
, yy
, ww
, hh
;
1252 xx
= XLOG2DEVMAC(x
);
1253 yy
= YLOG2DEVMAC(y
);
1254 ww
= XLOG2DEVREL(w
);
1255 hh
= YLOG2DEVREL(h
);
1257 // if we have a scaling that we cannot map onto native regions
1258 // we must use the box
1259 if ( ww
!= w
|| hh
!= h
)
1261 wxDC::DoSetClippingRegion( x
, y
, w
, h
);
1266 CopyRgn( (RgnHandle
) region
.GetWXHRGN() , (RgnHandle
) m_macCurrentClipRgn
) ;
1267 if ( xx
!= x
|| yy
!= y
)
1268 OffsetRgn( (RgnHandle
) m_macCurrentClipRgn
, xx
- x
, yy
- y
) ;
1269 SectRgn( (RgnHandle
)m_macCurrentClipRgn
, (RgnHandle
)m_macBoundaryClipRgn
, (RgnHandle
)m_macCurrentClipRgn
) ;
1274 m_clipX1
= wxMax( m_clipX1
, xx
);
1275 m_clipY1
= wxMax( m_clipY1
, yy
);
1276 m_clipX2
= wxMin( m_clipX2
, (xx
+ ww
) );
1277 m_clipY2
= wxMin( m_clipY2
, (yy
+ hh
) );
1291 void wxDC::DestroyClippingRegion()
1293 // CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
1295 CGContextRef cgContext
= ((wxMacCGContext
*)(m_graphicContext
))->GetNativeContext() ;
1296 CGContextRestoreGState( cgContext
);
1297 CGContextSaveGState( cgContext
);
1299 m_graphicContext
->SetPen( m_pen
) ;
1300 m_graphicContext
->SetBrush( m_brush
) ;
1305 void wxDC::DoGetSizeMM( int* width
, int* height
) const
1311 *width
= long( double(w
) / (m_scaleX
* m_mm_to_pix_x
) );
1313 *height
= long( double(h
) / (m_scaleY
* m_mm_to_pix_y
) );
1316 void wxDC::SetTextForeground( const wxColour
&col
)
1318 wxCHECK_RET( Ok(), wxT("wxDC(cg)::SetTextForeground - invalid DC") );
1320 if ( col
!= m_textForegroundColour
)
1322 m_textForegroundColour
= col
;
1323 m_graphicContext
->SetTextColor( col
) ;
1327 void wxDC::SetTextBackground( const wxColour
&col
)
1329 wxCHECK_RET( Ok(), wxT("wxDC(cg)::SetTextBackground - invalid DC") );
1331 m_textBackgroundColour
= col
;
1334 void wxDC::SetMapMode( int mode
)
1339 SetLogicalScale( twips2mm
* m_mm_to_pix_x
, twips2mm
* m_mm_to_pix_y
);
1343 SetLogicalScale( pt2mm
* m_mm_to_pix_x
, pt2mm
* m_mm_to_pix_y
);
1347 SetLogicalScale( m_mm_to_pix_x
, m_mm_to_pix_y
);
1351 SetLogicalScale( m_mm_to_pix_x
/ 10.0, m_mm_to_pix_y
/ 10.0 );
1356 SetLogicalScale( 1.0, 1.0 );
1360 if (mode
!= wxMM_TEXT
)
1362 m_needComputeScaleX
=
1363 m_needComputeScaleY
= true;
1367 void wxDC::SetUserScale( double x
, double y
)
1369 // allow negative ? -> no
1372 ComputeScaleAndOrigin();
1375 void wxDC::SetLogicalScale( double x
, double y
)
1378 m_logicalScaleX
= x
;
1379 m_logicalScaleY
= y
;
1380 ComputeScaleAndOrigin();
1383 void wxDC::SetLogicalOrigin( wxCoord x
, wxCoord y
)
1385 m_logicalOriginX
= x
* m_signX
; // is this still correct ?
1386 m_logicalOriginY
= y
* m_signY
;
1387 ComputeScaleAndOrigin();
1390 void wxDC::SetDeviceOrigin( wxCoord x
, wxCoord y
)
1392 m_externalDeviceOriginX
= x
;
1393 m_externalDeviceOriginY
= y
;
1394 ComputeScaleAndOrigin();
1397 void wxDC::SetAxisOrientation( bool xLeftRight
, bool yBottomUp
)
1399 m_signX
= (xLeftRight
? 1 : -1);
1400 m_signY
= (yBottomUp
? -1 : 1);
1401 ComputeScaleAndOrigin();
1404 wxSize
wxDC::GetPPI() const
1406 return wxSize(72, 72);
1409 int wxDC::GetDepth() const
1414 void wxDC::ComputeScaleAndOrigin()
1416 // CMB: copy scale to see if it changes
1417 double origScaleX
= m_scaleX
;
1418 double origScaleY
= m_scaleY
;
1419 m_scaleX
= m_logicalScaleX
* m_userScaleX
;
1420 m_scaleY
= m_logicalScaleY
* m_userScaleY
;
1421 m_deviceOriginX
= m_externalDeviceOriginX
;
1422 m_deviceOriginY
= m_externalDeviceOriginY
;
1424 // CMB: if scale has changed call SetPen to recalulate the line width
1425 if (m_scaleX
!= origScaleX
|| m_scaleY
!= origScaleY
)
1427 // this is a bit artificial, but we need to force wxDC to think
1428 // the pen has changed
1429 wxPen
pen( GetPen() );
1436 void wxDC::SetPalette( const wxPalette
& palette
)
1440 void wxDC::SetBackgroundMode( int mode
)
1442 m_backgroundMode
= mode
;
1445 void wxDC::SetFont( const wxFont
&font
)
1448 if ( m_graphicContext
)
1449 m_graphicContext
->SetFont( font
) ;
1452 void wxDC::SetPen( const wxPen
&pen
)
1458 if ( m_graphicContext
)
1460 if ( m_pen
.GetStyle() == wxSOLID
|| m_pen
.GetStyle() == wxTRANSPARENT
)
1462 m_graphicContext
->SetPen( m_pen
) ;
1466 // we have to compensate for moved device origins etc. otherwise patterned pens are standing still
1467 // eg when using a wxScrollWindow and scrolling around
1468 int origX
= XLOG2DEVMAC( 0 ) ;
1469 int origY
= YLOG2DEVMAC( 0 ) ;
1470 m_graphicContext
->Translate( origX
, origY
) ;
1471 m_graphicContext
->SetPen( m_pen
) ;
1472 m_graphicContext
->Translate( -origX
, -origY
) ;
1477 void wxDC::SetBrush( const wxBrush
&brush
)
1479 if (m_brush
== brush
)
1483 if ( m_graphicContext
)
1485 if ( brush
.GetStyle() == wxSOLID
|| brush
.GetStyle() == wxTRANSPARENT
)
1487 m_graphicContext
->SetBrush( m_brush
) ;
1491 // we have to compensate for moved device origins etc. otherwise patterned brushes are standing still
1492 // eg when using a wxScrollWindow and scrolling around
1493 int origX
= XLOG2DEVMAC(0) ;
1494 int origY
= YLOG2DEVMAC(0) ;
1495 m_graphicContext
->Translate( origX
, origY
) ;
1496 m_graphicContext
->SetBrush( m_brush
) ;
1497 m_graphicContext
->Translate( -origX
, -origY
) ;
1502 void wxDC::SetBackground( const wxBrush
&brush
)
1504 if (m_backgroundBrush
== brush
)
1507 m_backgroundBrush
= brush
;
1508 if (!m_backgroundBrush
.Ok())
1512 void wxDC::SetLogicalFunction( int function
)
1514 if (m_logicalFunction
== function
)
1517 m_logicalFunction
= function
;
1518 #if wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
1519 CGContextRef cgContext
= ((wxMacCGContext
*)(m_graphicContext
))->GetNativeContext() ;
1520 if ( m_logicalFunction
== wxCOPY
)
1521 CGContextSetBlendMode( cgContext
, kCGBlendModeNormal
) ;
1522 else if ( m_logicalFunction
== wxINVERT
)
1523 CGContextSetBlendMode( cgContext
, kCGBlendModeExclusion
) ;
1525 CGContextSetBlendMode( cgContext
, kCGBlendModeNormal
) ;
1529 extern bool wxDoFloodFill(wxDC
*dc
, wxCoord x
, wxCoord y
,
1530 const wxColour
& col
, int style
);
1532 bool wxDC::DoFloodFill(wxCoord x
, wxCoord y
,
1533 const wxColour
& col
, int style
)
1535 return wxDoFloodFill(this, x
, y
, col
, style
);
1538 bool wxDC::DoGetPixel( wxCoord x
, wxCoord y
, wxColour
*col
) const
1540 wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoGetPixel - invalid DC") );
1542 wxMacPortSaver
helper((CGrafPtr
)m_macPort
) ;
1545 // NB: GetCPixel is a deprecated QD call, and a slow one at that
1547 XLOG2DEVMAC(x
) + m_macLocalOriginInPort
.x
- m_macLocalOrigin
.x
,
1548 YLOG2DEVMAC(y
) + m_macLocalOriginInPort
.y
- m_macLocalOrigin
.y
, &colour
);
1550 // convert from Mac colour to wx
1551 col
->Set( colour
.red
>> 8, colour
.green
>> 8, colour
.blue
>> 8 );
1556 void wxDC::DoDrawLine( wxCoord x1
, wxCoord y1
, wxCoord x2
, wxCoord y2
)
1558 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawLine - invalid DC") );
1560 #if !wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
1561 if ( m_logicalFunction
!= wxCOPY
)
1565 wxCoord xx1
= XLOG2DEVMAC(x1
) ;
1566 wxCoord yy1
= YLOG2DEVMAC(y1
) ;
1567 wxCoord xx2
= XLOG2DEVMAC(x2
) ;
1568 wxCoord yy2
= YLOG2DEVMAC(y2
) ;
1570 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1571 path
->MoveToPoint( xx1
, yy1
) ;
1572 path
->AddLineToPoint( xx2
, yy2
) ;
1573 path
->CloseSubpath() ;
1574 m_graphicContext
->StrokePath( path
) ;
1577 CalcBoundingBox(x1
, y1
);
1578 CalcBoundingBox(x2
, y2
);
1581 void wxDC::DoCrossHair( wxCoord x
, wxCoord y
)
1583 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoCrossHair - invalid DC") );
1585 if ( m_logicalFunction
!= wxCOPY
)
1591 wxCoord xx
= XLOG2DEVMAC(x
);
1592 wxCoord yy
= YLOG2DEVMAC(y
);
1594 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1595 path
->MoveToPoint( XLOG2DEVMAC(0), yy
) ;
1596 path
->AddLineToPoint( XLOG2DEVMAC(w
), yy
) ;
1597 path
->CloseSubpath() ;
1598 path
->MoveToPoint( xx
, YLOG2DEVMAC(0) ) ;
1599 path
->AddLineToPoint( xx
, YLOG2DEVMAC(h
) ) ;
1600 path
->CloseSubpath() ;
1601 m_graphicContext
->StrokePath( path
) ;
1604 CalcBoundingBox(x
, y
);
1605 CalcBoundingBox(x
+ w
, y
+ h
);
1608 void wxDC::DoDrawArc( wxCoord x1
, wxCoord y1
,
1609 wxCoord x2
, wxCoord y2
,
1610 wxCoord xc
, wxCoord yc
)
1612 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawArc - invalid DC") );
1614 if ( m_logicalFunction
!= wxCOPY
)
1617 wxCoord xx1
= XLOG2DEVMAC(x1
);
1618 wxCoord yy1
= YLOG2DEVMAC(y1
);
1619 wxCoord xx2
= XLOG2DEVMAC(x2
);
1620 wxCoord yy2
= YLOG2DEVMAC(y2
);
1621 wxCoord xxc
= XLOG2DEVMAC(xc
);
1622 wxCoord yyc
= YLOG2DEVMAC(yc
);
1624 double dx
= xx1
- xxc
;
1625 double dy
= yy1
- yyc
;
1626 double radius
= sqrt((double)(dx
* dx
+ dy
* dy
));
1627 wxCoord rad
= (wxCoord
)radius
;
1629 if (xx1
== xx2
&& yy1
== yy2
)
1634 else if (radius
== 0.0)
1640 sa
= (xx1
- xxc
== 0) ?
1641 (yy1
- yyc
< 0) ? 90.0 : -90.0 :
1642 -atan2(double(yy1
- yyc
), double(xx1
- xxc
)) * RAD2DEG
;
1643 ea
= (xx2
- xxc
== 0) ?
1644 (yy2
- yyc
< 0) ? 90.0 : -90.0 :
1645 -atan2(double(yy2
- yyc
), double(xx2
- xxc
)) * RAD2DEG
;
1648 bool fill
= m_brush
.GetStyle() != wxTRANSPARENT
;
1650 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1651 m_graphicContext
->PushState() ;
1652 m_graphicContext
->Translate( xxc
, yyc
) ;
1653 m_graphicContext
->Scale( 1, -1 ) ;
1655 path
->MoveToPoint( 0, 0 ) ;
1656 path
->AddArc( 0, 0, rad
, DegToRad(sa
) , DegToRad(ea
), false ) ;
1658 path
->AddLineToPoint( 0, 0 ) ;
1659 m_graphicContext
->DrawPath( path
) ;
1660 m_graphicContext
->PopState() ;
1664 void wxDC::DoDrawEllipticArc( wxCoord x
, wxCoord y
, wxCoord w
, wxCoord h
,
1665 double sa
, double ea
)
1667 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawEllipticArc - invalid DC") );
1669 if ( m_logicalFunction
!= wxCOPY
)
1672 wxCoord xx
= XLOG2DEVMAC(x
);
1673 wxCoord yy
= YLOG2DEVMAC(y
);
1674 wxCoord ww
= m_signX
* XLOG2DEVREL(w
);
1675 wxCoord hh
= m_signY
* YLOG2DEVREL(h
);
1677 // handle -ve width and/or height
1689 bool fill
= m_brush
.GetStyle() != wxTRANSPARENT
;
1691 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1692 m_graphicContext
->PushState() ;
1693 m_graphicContext
->Translate( xx
+ ww
/ 2, yy
+ hh
/ 2 ) ;
1694 m_graphicContext
->Scale( 1 * ww
/ 2 , -1 * hh
/ 2 ) ;
1696 path
->MoveToPoint( 0, 0 ) ;
1697 path
->AddArc( 0, 0, 1 , DegToRad(sa
) , DegToRad(ea
), false ) ;
1699 path
->AddLineToPoint( 0, 0 ) ;
1700 m_graphicContext
->DrawPath( path
) ;
1701 m_graphicContext
->PopState() ;
1705 void wxDC::DoDrawPoint( wxCoord x
, wxCoord y
)
1707 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawPoint - invalid DC") );
1709 DoDrawLine( x
, y
, x
+ 1 , y
+ 1 ) ;
1712 void wxDC::DoDrawLines(int n
, wxPoint points
[],
1713 wxCoord xoffset
, wxCoord yoffset
)
1715 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawLines - invalid DC") );
1717 #if !wxMAC_USE_CORE_GRAPHICS_BLEND_MODES
1718 if ( m_logicalFunction
!= wxCOPY
)
1722 wxCoord x1
, x2
, y1
, y2
;
1723 x1
= XLOG2DEVMAC(points
[0].x
+ xoffset
);
1724 y1
= YLOG2DEVMAC(points
[0].y
+ yoffset
);
1725 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1726 path
->MoveToPoint( x1
, y1
) ;
1727 for (int i
= 1; i
< n
; i
++)
1729 x2
= XLOG2DEVMAC(points
[i
].x
+ xoffset
);
1730 y2
= YLOG2DEVMAC(points
[i
].y
+ yoffset
);
1732 path
->AddLineToPoint( x2
, y2
) ;
1735 m_graphicContext
->StrokePath( path
) ;
1740 void wxDC::DoDrawSpline(wxList
*points
)
1742 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawSpline - invalid DC") );
1744 if ( m_logicalFunction
!= wxCOPY
)
1747 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1749 wxList::compatibility_iterator node
= points
->GetFirst();
1750 if (node
== wxList::compatibility_iterator())
1754 wxPoint
*p
= (wxPoint
*)node
->GetData();
1759 node
= node
->GetNext();
1760 p
= (wxPoint
*)node
->GetData();
1764 wxCoord cx1
= ( x1
+ x2
) / 2;
1765 wxCoord cy1
= ( y1
+ y2
) / 2;
1767 path
->MoveToPoint( XLOG2DEVMAC( x1
) , YLOG2DEVMAC( y1
) ) ;
1768 path
->AddLineToPoint( XLOG2DEVMAC( cx1
) , YLOG2DEVMAC( cy1
) ) ;
1771 while ((node
= node
->GetNext()) != NULL
)
1773 while ((node
= node
->GetNext()))
1774 #endif // !wxUSE_STL
1776 p
= (wxPoint
*)node
->GetData();
1781 wxCoord cx4
= (x1
+ x2
) / 2;
1782 wxCoord cy4
= (y1
+ y2
) / 2;
1784 path
->AddQuadCurveToPoint(
1785 XLOG2DEVMAC( x1
) , YLOG2DEVMAC( y1
) ,
1786 XLOG2DEVMAC( cx4
) , YLOG2DEVMAC( cy4
) ) ;
1792 path
->AddLineToPoint( XLOG2DEVMAC( x2
) , YLOG2DEVMAC( y2
) ) ;
1794 m_graphicContext
->StrokePath( path
) ;
1799 void wxDC::DoDrawPolygon( int n
, wxPoint points
[],
1800 wxCoord xoffset
, wxCoord yoffset
,
1803 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawPolygon - invalid DC") );
1805 if ( n
<= 0 || (m_brush
.GetStyle() == wxTRANSPARENT
&& m_pen
.GetStyle() == wxTRANSPARENT
) )
1807 if ( m_logicalFunction
!= wxCOPY
)
1810 wxCoord x1
, x2
, y1
, y2
;
1811 x2
= x1
= XLOG2DEVMAC(points
[0].x
+ xoffset
);
1812 y2
= y1
= YLOG2DEVMAC(points
[0].y
+ yoffset
);
1814 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1815 path
->MoveToPoint( x1
, y1
) ;
1816 for (int i
= 1; i
< n
; i
++)
1818 x2
= XLOG2DEVMAC(points
[i
].x
+ xoffset
);
1819 y2
= YLOG2DEVMAC(points
[i
].y
+ yoffset
);
1821 path
->AddLineToPoint( x2
, y2
) ;
1824 if ( x1
!= x2
|| y1
!= y2
)
1825 path
->AddLineToPoint( x1
, y1
) ;
1827 path
->CloseSubpath() ;
1828 m_graphicContext
->DrawPath( path
, fillStyle
) ;
1833 void wxDC::DoDrawRectangle(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
1835 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawRectangle - invalid DC") );
1837 if ( m_logicalFunction
!= wxCOPY
)
1840 wxCoord xx
= XLOG2DEVMAC(x
);
1841 wxCoord yy
= YLOG2DEVMAC(y
);
1842 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
1843 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
1845 // CMB: draw nothing if transformed w or h is 0
1846 if (ww
== 0 || hh
== 0)
1849 // CMB: handle -ve width and/or height
1861 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1862 path
->AddRectangle( xx
, yy
, ww
, hh
) ;
1863 m_graphicContext
->DrawPath( path
) ;
1867 void wxDC::DoDrawRoundedRectangle(wxCoord x
, wxCoord y
,
1868 wxCoord width
, wxCoord height
,
1871 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawRoundedRectangle - invalid DC") );
1873 if ( m_logicalFunction
!= wxCOPY
)
1877 radius
= - radius
* ((width
< height
) ? width
: height
);
1878 wxCoord xx
= XLOG2DEVMAC(x
);
1879 wxCoord yy
= YLOG2DEVMAC(y
);
1880 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
1881 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
1883 // CMB: draw nothing if transformed w or h is 0
1884 if (ww
== 0 || hh
== 0)
1887 // CMB: handle -ve width and/or height
1899 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1902 path
->AddRectangle( xx
, yy
, ww
, hh
) ;
1903 m_graphicContext
->DrawPath( path
) ;
1907 m_graphicContext
->PushState() ;
1908 m_graphicContext
->Translate( xx
, yy
) ;
1909 m_graphicContext
->Scale( radius
, radius
) ;
1910 double fw
= ww
/ radius
;
1911 double fh
= hh
/ radius
;
1912 path
->MoveToPoint(fw
, fh
/ 2);
1913 path
->AddArcToPoint(fw
, fh
, fw
/ 2, fh
, 1);
1914 path
->AddArcToPoint(0, fh
, 0, fh
/ 2, 1);
1915 path
->AddArcToPoint(0, 0, fw
/ 2, 0, 1);
1916 path
->AddArcToPoint(fw
, 0, fw
, fh
/ 2, 1);
1917 path
->CloseSubpath();
1918 m_graphicContext
->DrawPath( path
) ;
1919 m_graphicContext
->PopState() ;
1924 void wxDC::DoDrawEllipse(wxCoord x
, wxCoord y
, wxCoord width
, wxCoord height
)
1926 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawEllipse - invalid DC") );
1928 if ( m_logicalFunction
!= wxCOPY
)
1931 wxCoord xx
= XLOG2DEVMAC(x
);
1932 wxCoord yy
= YLOG2DEVMAC(y
);
1933 wxCoord ww
= m_signX
* XLOG2DEVREL(width
);
1934 wxCoord hh
= m_signY
* YLOG2DEVREL(height
);
1936 // CMB: draw nothing if transformed w or h is 0
1937 if (ww
== 0 || hh
== 0)
1940 // CMB: handle -ve width and/or height
1952 wxGraphicPath
* path
= m_graphicContext
->CreatePath() ;
1953 m_graphicContext
->PushState() ;
1954 m_graphicContext
->Translate(xx
+ ww
/ 2, yy
+ hh
/ 2);
1955 m_graphicContext
->Scale(ww
/ 2 , hh
/ 2);
1956 path
->AddArc( 0, 0, 1, 0 , 2 * M_PI
, false ) ;
1957 m_graphicContext
->DrawPath( path
) ;
1958 m_graphicContext
->PopState() ;
1962 bool wxDC::CanDrawBitmap() const
1968 wxCoord xdest
, wxCoord ydest
, wxCoord width
, wxCoord height
,
1969 wxDC
*source
, wxCoord xsrc
, wxCoord ysrc
, int logical_func
, bool useMask
,
1970 wxCoord xsrcMask
, wxCoord ysrcMask
)
1972 wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoBlit - invalid DC") );
1973 wxCHECK_MSG( source
->Ok(), false, wxT("wxDC(cg)::DoBlit - invalid source DC") );
1975 if ( logical_func
== wxNO_OP
)
1978 if (xsrcMask
== -1 && ysrcMask
== -1)
1984 wxCoord yysrc
= source
->YLOG2DEVMAC(ysrc
) ;
1985 wxCoord xxsrc
= source
->XLOG2DEVMAC(xsrc
) ;
1986 wxCoord wwsrc
= source
->XLOG2DEVREL(width
) ;
1987 wxCoord hhsrc
= source
->YLOG2DEVREL(height
) ;
1989 wxCoord yydest
= YLOG2DEVMAC(ydest
) ;
1990 wxCoord xxdest
= XLOG2DEVMAC(xdest
) ;
1991 wxCoord wwdest
= XLOG2DEVREL(width
) ;
1992 wxCoord hhdest
= YLOG2DEVREL(height
) ;
1994 wxMemoryDC
* memdc
= dynamic_cast<wxMemoryDC
*>(source
) ;
1995 if ( memdc
&& logical_func
== wxCOPY
)
1997 wxBitmap blit
= memdc
->GetSelectedObject() ;
1999 wxASSERT_MSG( blit
.Ok() , wxT("Invalid bitmap for blitting") ) ;
2001 wxCoord bmpwidth
= blit
.GetWidth();
2002 wxCoord bmpheight
= blit
.GetHeight();
2004 if ( xxsrc
!= 0 || yysrc
!= 0 || bmpwidth
!= wwsrc
|| bmpheight
!= hhsrc
)
2006 wwsrc
= wxMin( wwsrc
, bmpwidth
- xxsrc
) ;
2007 hhsrc
= wxMin( hhsrc
, bmpheight
- yysrc
) ;
2008 if ( wwsrc
> 0 && hhsrc
> 0 )
2010 if ( xxsrc
>= 0 && yysrc
>= 0 )
2012 wxRect
subrect( xxsrc
, yysrc
, wwsrc
, hhsrc
) ;
2013 // TODO we perhaps could add a DrawSubBitmap call to dc for performance reasons
2014 blit
= blit
.GetSubBitmap( subrect
) ;
2018 // in this case we'd probably have to adjust the different coordinates, but
2019 // we have to find out proper contract first
2020 blit
= wxNullBitmap
;
2025 blit
= wxNullBitmap
;
2031 m_graphicContext
->DrawBitmap( blit
, xxdest
, yydest
, wwdest
, hhdest
) ;
2036 wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ;
2043 void wxDC::DoDrawRotatedText(const wxString
& str
, wxCoord x
, wxCoord y
,
2046 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawRotatedText - invalid DC") );
2047 // wxCHECK_RET( m_macATSUIStyle != NULL, wxT("wxDC(cg)::DoDrawRotatedText - no valid font set") );
2049 if ( str
.length() == 0 )
2051 if ( m_logicalFunction
!= wxCOPY
)
2054 int drawX
= XLOG2DEVMAC(x
) ;
2055 int drawY
= YLOG2DEVMAC(y
) ;
2057 m_graphicContext
->DrawText( str
, drawX
,drawY
, angle
) ;
2060 void wxDC::DoDrawText(const wxString
& strtext
, wxCoord x
, wxCoord y
)
2062 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawText - invalid DC") );
2064 DoDrawRotatedText( strtext
, x
, y
, 0.0 ) ;
2067 bool wxDC::CanGetTextExtent() const
2069 wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::CanGetTextExtent - invalid DC") );
2074 void wxDC::DoGetTextExtent( const wxString
&str
, wxCoord
*width
, wxCoord
*height
,
2075 wxCoord
*descent
, wxCoord
*externalLeading
,
2076 wxFont
*theFont
) const
2078 wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoGetTextExtent - invalid DC") );
2080 wxFont formerFont
= m_font
;
2083 m_graphicContext
->SetFont( *theFont
) ;
2086 wxCoord h
, d
, e
, w
;
2088 m_graphicContext
->GetTextExtent( str
, &w
, &h
, &d
, &e
) ;
2091 *height
= YDEV2LOGREL( h
) ;
2093 *descent
=YDEV2LOGREL( d
);
2094 if ( externalLeading
)
2095 *externalLeading
= YDEV2LOGREL( e
);
2097 *width
= XDEV2LOGREL( w
) ;
2101 m_graphicContext
->SetFont( m_font
) ;
2105 bool wxDC::DoGetPartialTextExtents(const wxString
& text
, wxArrayInt
& widths
) const
2107 wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoGetPartialTextExtents - invalid DC") );
2109 m_graphicContext
->GetPartialTextExtents( text
, widths
) ;
2110 for ( size_t i
= 0 ; i
< widths
.GetCount() ; ++i
)
2111 widths
[i
] = XDEV2LOGREL( widths
[i
] );
2116 wxCoord
wxDC::GetCharWidth(void) const
2119 DoGetTextExtent( wxT("g") , &width
, NULL
, NULL
, NULL
, NULL
) ;
2124 wxCoord
wxDC::GetCharHeight(void) const
2127 DoGetTextExtent( wxT("g") , NULL
, &height
, NULL
, NULL
, NULL
) ;
2132 void wxDC::Clear(void)
2134 wxCHECK_RET( Ok(), wxT("wxDC(cg)::Clear - invalid DC") );
2136 if (m_backgroundBrush
.Ok() && m_backgroundBrush
.GetStyle() != wxTRANSPARENT
)
2138 HIRect rect
= CGRectMake( -10000 , -10000 , 20000 , 20000 ) ;
2139 CGContextRef cg
= ((wxMacCGContext
*)(m_graphicContext
))->GetNativeContext() ;
2140 switch ( m_backgroundBrush
.MacGetBrushKind() )
2142 case kwxMacBrushTheme
:
2144 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
2145 if ( HIThemeSetFill
!= 0 )
2147 HIThemeSetFill( m_backgroundBrush
.MacGetTheme(), NULL
, cg
, kHIThemeOrientationNormal
);
2148 CGContextFillRect(cg
, rect
);
2155 GetThemeBrushAsColor( m_backgroundBrush
.MacGetTheme(), 32, true, &color
);
2156 CGContextSetRGBFillColor( cg
, (CGFloat
) color
.red
/ 65536,
2157 (CGFloat
) color
.green
/ 65536, (CGFloat
) color
.blue
/ 65536, 1 );
2158 CGContextFillRect( cg
, rect
);
2161 // reset to normal value
2162 RGBColor col
= MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
2163 CGContextSetRGBFillColor( cg
, col
.red
/ 65536.0, col
.green
/ 65536.0, col
.blue
/ 65536.0, 1.0 );
2167 case kwxMacBrushThemeBackground
:
2169 wxFAIL_MSG( wxT("There shouldn't be theme backgrounds under Quartz") ) ;
2171 #if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
2172 if ( UMAGetSystemVersion() >= 0x1030 )
2174 HIThemeBackgroundDrawInfo drawInfo
;
2175 drawInfo
.version
= 0 ;
2176 drawInfo
.state
= kThemeStateActive
;
2177 drawInfo
.kind
= m_backgroundBrush
.MacGetThemeBackground( NULL
) ;
2178 if ( drawInfo
.kind
== kThemeBackgroundMetal
)
2180 HIThemeDrawBackground( &rect
, &drawInfo
, cg
, kHIThemeOrientationNormal
) ;
2181 HIThemeApplyBackground( &rect
, &drawInfo
, cg
, kHIThemeOrientationNormal
) ;
2188 case kwxMacBrushColour
:
2190 // FIXME: doesn't correctly render stippled brushes !!
2191 // FIXME: should this be replaced by ::SetBrush() ??
2193 RGBColor col
= MAC_WXCOLORREF( m_backgroundBrush
.GetColour().GetPixel()) ;
2194 CGContextSetRGBFillColor( cg
, col
.red
/ 65536.0 , col
.green
/ 65536.0 , col
.blue
/ 65536.0 , 1.0 ) ;
2195 CGContextFillRect(cg
, rect
);
2197 // reset to normal value
2198 col
= MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
2199 CGContextSetRGBFillColor( cg
, col
.red
/ 65536.0 , col
.green
/ 65536.0 , col
.blue
/ 65536.0 , 1.0 ) ;
2204 wxFAIL_MSG( wxT("unknown brush kind") ) ;
2212 // ---------------------------------------------------------------------------
2213 // coordinates transformations
2214 // ---------------------------------------------------------------------------
2216 wxCoord
wxDCBase::DeviceToLogicalX(wxCoord x
) const
2218 return ((wxDC
*)this)->XDEV2LOG(x
);
2221 wxCoord
wxDCBase::DeviceToLogicalY(wxCoord y
) const
2223 return ((wxDC
*)this)->YDEV2LOG(y
);
2226 wxCoord
wxDCBase::DeviceToLogicalXRel(wxCoord x
) const
2228 return ((wxDC
*)this)->XDEV2LOGREL(x
);
2231 wxCoord
wxDCBase::DeviceToLogicalYRel(wxCoord y
) const
2233 return ((wxDC
*)this)->YDEV2LOGREL(y
);
2236 wxCoord
wxDCBase::LogicalToDeviceX(wxCoord x
) const
2238 return ((wxDC
*)this)->XLOG2DEV(x
);
2241 wxCoord
wxDCBase::LogicalToDeviceY(wxCoord y
) const
2243 return ((wxDC
*)this)->YLOG2DEV(y
);
2246 wxCoord
wxDCBase::LogicalToDeviceXRel(wxCoord x
) const
2248 return ((wxDC
*)this)->XLOG2DEVREL(x
);
2251 wxCoord
wxDCBase::LogicalToDeviceYRel(wxCoord y
) const
2253 return ((wxDC
*)this)->YLOG2DEVREL(y
);
2256 #endif // wxMAC_USE_CORE_GRAPHICS