// Licence: wxWindows licence
/////////////////////////////////////////////////////////////////////////////
-#ifdef __GNUG__
-#pragma implementation "dc.h"
-#endif
-
#include "wx/wxprec.h"
#include "wx/dc.h"
#include "wx/log.h"
-#if __MSL__ >= 0x6000
-#include "math.h"
-using namespace std ;
+#ifdef __MSL__
+ #if __MSL__ >= 0x6000
+ #include "math.h"
+ // in case our functions were defined outside std, we make it known all the same
+ namespace std { }
+ using namespace std ;
+ #endif
#endif
#include "wx/mac/private.h"
const double M_PI = 3.14159265358979 ;
#endif
#endif
+
const double RAD2DEG = 180.0 / M_PI;
const short kEmulatedMode = -1 ;
const short kUnsupportedMode = -2 ;
extern TECObjectRef s_TECNativeCToUnicode ;
-// TODO Update
-// The text ctrl implementation still needs that for the non hiview implementation
+// TODO: update
+// The textctrl implementation still needs that (needs what?) for the non-HIView implementation
+//
wxMacWindowClipper::wxMacWindowClipper( const wxWindow* win ) :
wxMacPortSaver( (GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) )
{
- m_newPort =(GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) ;
+ m_newPort = (GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) ;
m_formerClip = NewRgn() ;
m_newClip = NewRgn() ;
GetClip( m_formerClip ) ;
-
+
if ( win )
{
// guard against half constructed objects, this just leads to a empty clip
- if( win->GetPeer() )
+ if ( win->GetPeer() )
{
int x = 0 , y = 0;
- win->MacWindowToRootWindow( &x,&y ) ;
+ win->MacWindowToRootWindow( &x, &y ) ;
// get area including focus rect
CopyRgn( (RgnHandle) ((wxWindow*)win)->MacGetVisibleRegion(true).GetWXHRGN() , m_newClip ) ;
if ( !EmptyRgn( m_newClip ) )
wxMacWindowClipper( win )
{
// the port is already set at this point
- m_newPort =(GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) ;
+ m_newPort = (GrafPtr) GetWindowPort((WindowRef) win->MacGetTopLevelWindowRef()) ;
GetThemeDrawingState( &m_themeDrawingState ) ;
}
{
wxASSERT( dc->Ok() ) ;
m_dc = dc ;
+
// dc->MacSetupPort(&m_ph) ;
}
+
wxMacPortSetter::~wxMacPortSetter()
{
// m_dc->MacCleanupPort(&m_ph) ;
CGPathRelease( m_path ) ;
}
-// Starts a new subpath at
+// opens (starts) a new subpath
void wxMacCGPath::MoveToPoint( wxCoord x1 , wxCoord y1 )
{
CGPathMoveToPoint( m_path , NULL , x1 , y1 ) ;
CGPathAddLineToPoint( m_path , NULL , x1 , y1 ) ;
}
+void wxMacCGPath::AddQuadCurveToPoint( wxCoord cx1, wxCoord cy1, wxCoord x1, wxCoord y1 )
+{
+ CGPathAddQuadCurveToPoint( m_path , NULL , cx1 , cy1 , x1 , y1 );
+}
+
void wxMacCGPath::AddRectangle( wxCoord x, wxCoord y, wxCoord w, wxCoord h )
{
CGRect cgRect = { { x , y } , { w , h } } ;
CGContextRestoreGState( m_cgContext ) ;
CGContextRestoreGState( m_cgContext ) ;
}
+
if ( m_qdPort )
CGContextRelease( m_cgContext ) ;
}
void wxMacCGContext::Clip( const wxRegion ®ion )
{
-// ClipCGContextToRegion ( m_cgContext, &bounds , (RgnHandle) dc->m_macCurrentClipRgn ) ;
+// ClipCGContextToRegion ( m_cgContext, &bounds , (RgnHandle) dc->m_macCurrentClipRgn ) ;
}
void wxMacCGContext::StrokePath( const wxGraphicPath *p )
{
const wxMacCGPath* path = dynamic_cast< const wxMacCGPath*>( p ) ;
CGPathDrawingMode mode = m_mode ;
+
if ( fillStyle == wxODDEVEN_RULE )
{
if ( mode == kCGPathFill )
else if ( mode == kCGPathFillStroke )
mode = kCGPathEOFillStroke ;
}
+
CGContextAddPath( m_cgContext , path->GetPath() ) ;
CGContextDrawPath( m_cgContext , mode ) ;
}
// anything with paths
CGContextRef cg = GetNativeContext() ;
cg = NULL ;
+
return new wxMacCGPath() ;
}
CGContextRef wxMacCGContext::GetNativeContext()
{
- if( m_cgContext == NULL )
+ if ( m_cgContext == NULL )
{
Rect bounds ;
GetPortBounds( (CGrafPtr) m_qdPort , &bounds ) ;
CGContextSaveGState( m_cgContext ) ;
wxASSERT_MSG( status == noErr , wxT("Cannot nest wxDCs on the same window") ) ;
+
CGContextTranslateCTM( m_cgContext , 0 , bounds.bottom - bounds.top ) ;
CGContextScaleCTM( m_cgContext , 1 , -1 ) ;
SetPen( m_pen ) ;
SetBrush( m_brush ) ;
}
+
return m_cgContext ;
}
{
// we allow either setting or clearing but not replacing
wxASSERT( m_cgContext == NULL || cg == NULL ) ;
+
if ( cg )
CGContextSaveGState( cg ) ;
m_cgContext = cg ;
}
#pragma mark -
+#pragma mark wxMacCGPattern, ImagePattern, HatchPattern classes
-// Experimental support for dashes and patterned brushes
-// uncomment the following lines to enable it
+// CGPattern wrapper class: always allocate on heap, never call destructor
-// #define _NEW_GC_DASHES_
-// #define _NEW_GC_SUPPORT_
-
-#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
-#define kCGColorSpaceGenericRGB CFSTR("kCGColorSpaceGenericRGB")
-#endif
-
-void EstablishPatternColorSpace(
- CGContextRef ctxRef,
- bool useMultibit,
- bool useFill )
+class wxMacCGPattern
{
- CGColorSpaceRef baseSpace, patternSpace;
-
- if (ctxRef == NULL)
- return;
-
- baseSpace = NULL;
- patternSpace = NULL;
-
- if (useMultibit)
- {
- patternSpace = CGColorSpaceCreatePattern( NULL );
-
- if (useFill)
- CGContextSetFillColorSpace( ctxRef, patternSpace );
- else
- CGContextSetStrokeColorSpace( ctxRef, patternSpace );
- }
- else
- {
- baseSpace = CGColorSpaceCreateWithName( kCGColorSpaceGenericRGB );
- patternSpace = CGColorSpaceCreatePattern( baseSpace );
-
- if (useFill)
- CGContextSetFillColorSpace( ctxRef, patternSpace );
- else
- CGContextSetStrokeColorSpace( ctxRef, patternSpace );
- }
-
- // NB: the context owns these now, and this code is finished with them
- if (patternSpace != NULL)
- CGColorSpaceRelease( patternSpace );
- if (baseSpace != NULL)
- CGColorSpaceRelease( baseSpace );
-}
-
-void ImagePatternRender(
- void *info,
- CGContextRef ctxRef )
-{
- if (ctxRef == NULL)
- return;
-
- CGImageRef imageRef = (CGImageRef)info;
- if (imageRef != NULL)
- {
- CGRect boundsR = CGRectMake( 0.0, 0.0, (float)CGImageGetWidth( imageRef ), (float)CGImageGetHeight( imageRef ) );
- CGContextDrawImage( ctxRef, boundsR, imageRef );
- }
-}
+public :
+ wxMacCGPattern() {}
-void ImagePatternDispose(
- void *info )
-{
- CGImageRef imageRef = (CGImageRef)info;
- if (imageRef != NULL)
- CGImageRelease( imageRef );
-}
+ // is guaranteed to be called only with a non-Null CGContextRef
+ virtual void Render( CGContextRef ctxRef ) = 0 ;
-// specifies the struct version value and the callback functions for draw and release
-static const CGPatternCallbacks sImagePatternCallback = { 0, &ImagePatternRender, &ImagePatternDispose };
+ operator CGPatternRef() const { return m_patternRef ; }
-long CreatePatternFromBitmap(
- CGPatternRef *patternRef,
- const wxBitmap *rasterInfo,
- bool useMultibit )
-{
- CGRect boundsR;
- CGImageRef imageRef;
- long errorStatus, widthV, heightV, depthV;
+protected :
+ virtual ~wxMacCGPattern()
+ {
+ // as this is called only when the m_patternRef is been released;
+ // don't release it again
+ }
- if (patternRef == NULL)
- return (-1);
+ static void _Render( void *info, CGContextRef ctxRef )
+ {
+ wxMacCGPattern* self = (wxMacCGPattern*) info ;
+ if ( self && ctxRef )
+ self->Render( ctxRef ) ;
+ }
- *patternRef = NULL;
- imageRef = NULL;
- errorStatus = 0;
+ static void _Dispose( void *info )
+ {
+ wxMacCGPattern* self = (wxMacCGPattern*) info ;
+ delete self ;
+ }
- if ((rasterInfo == NULL) || !rasterInfo->Ok())
- errorStatus = (-2);
+ CGPatternRef m_patternRef ;
- if (errorStatus == 0)
- {
- // build a usable bounding CGRect from the wxBitmap's bounds wxRect
- widthV = rasterInfo->GetWidth();
- heightV = rasterInfo->GetHeight();
- if ((widthV <= 0) || (heightV <= 0))
- errorStatus = (-3);
- }
+ static const CGPatternCallbacks ms_Callbacks ;
+} ;
- if (errorStatus == 0)
- {
- depthV = rasterInfo->GetDepth();
-// isColored = (depthV > 1);
+const CGPatternCallbacks wxMacCGPattern::ms_Callbacks = { 0, &wxMacCGPattern::_Render, &wxMacCGPattern::_Dispose };
- // FIXME: this is often <= 0 - why???
-// if (depthV <= 1)
-// errorStatus = (-4);
- }
+class ImagePattern : public wxMacCGPattern
+{
+public :
+ ImagePattern( const wxBitmap* bmp , CGAffineTransform transform )
+ {
+ wxASSERT( bmp && bmp->Ok() ) ;
- if (errorStatus == 0)
- {
- imageRef = (CGImageRef)(rasterInfo->CGImageCreate());
- if (imageRef == NULL)
- errorStatus = (-5);
- }
+ Init( (CGImageRef) bmp->CGImageCreate() , transform ) ;
+ }
+
+ // ImagePattern takes ownership of CGImageRef passed in
+ ImagePattern( CGImageRef image , CGAffineTransform transform )
+ {
+ if ( image )
+ CFRetain( image ) ;
- if (errorStatus == 0)
- {
- // FIXME: switch when this routine belongs to a DC class...
- boundsR = CGRectMake( 0.0, 0.0, (float)widthV, (float)heightV );
-// boundsR = CGRectMake( 0.0, 0.0, (float)XLOG2DEVREL( widthV ), (float)XLOG2DEVREL( heightV ) );
+ Init( image , transform ) ;
+ }
+
+ virtual void Render( CGContextRef ctxRef )
+ {
+ if (m_image != NULL)
+ HIViewDrawCGImage( ctxRef, &m_imageBounds, m_image );
+ }
- *patternRef = CGPatternCreate(
- (void*)imageRef,
- boundsR,
- CGAffineTransformIdentity,
- boundsR.size.width,
- boundsR.size.height,
- kCGPatternTilingNoDistortion,
- (int)useMultibit,
- &sImagePatternCallback );
+protected :
+ void Init( CGImageRef image, CGAffineTransform transform )
+ {
+ m_image = image ;
+ if ( m_image )
+ {
+ m_imageBounds = CGRectMake( 0.0, 0.0, (float)CGImageGetWidth( m_image ), (float)CGImageGetHeight( m_image ) ) ;
+ m_patternRef = CGPatternCreate( this , m_imageBounds, transform ,
+ m_imageBounds.size.width, m_imageBounds.size.height,
+ kCGPatternTilingNoDistortion, true , &wxMacCGPattern::ms_Callbacks ) ;
+ }
+ }
- if (*patternRef == (CGPatternRef)NULL)
- errorStatus = (-6);
- }
+ ~ImagePattern()
+ {
+ if ( m_image )
+ CGImageRelease( m_image ) ;
+ }
- return errorStatus;
-}
+ CGImageRef m_image ;
+ CGRect m_imageBounds ;
+} ;
-long CreatePatternFromDashes(
- CGPatternRef *patternRef,
- const wxDash *sourceDash,
- int count,
- bool useMultibit )
+class HatchPattern : public wxMacCGPattern
{
- long errorStatus;
-
- if (patternRef == NULL)
- return (-1);
-
- *patternRef = NULL;
- if ((sourceDash == NULL) || (count <= 0))
- return (-2);
-
- wxBitmap dashBits( (char*)sourceDash, 8, count, 1 );
- errorStatus = CreatePatternFromBitmap( patternRef, &dashBits, useMultibit );
-
- return errorStatus;
-}
+public :
+ HatchPattern( int hatchstyle, CGAffineTransform transform )
+ {
+ m_hatch = hatchstyle ;
+ m_imageBounds = CGRectMake( 0.0, 0.0, 8.0 , 8.0 ) ;
+ m_patternRef = CGPatternCreate( this , m_imageBounds, transform ,
+ m_imageBounds.size.width, m_imageBounds.size.height,
+ kCGPatternTilingNoDistortion, false , &wxMacCGPattern::ms_Callbacks ) ;
+ }
+
+ void StrokeLineSegments( CGContextRef ctxRef , const CGPoint pts[] , size_t count )
+ {
+#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_4
+ if ( UMAGetSystemVersion() >= 0x1040 )
+ {
+ CGContextStrokeLineSegments( ctxRef , pts , count ) ;
+ }
+ else
+#endif
+ {
+ CGContextBeginPath( ctxRef );
+ for (size_t i = 0; i < count; i += 2)
+ {
+ CGContextMoveToPoint(ctxRef, pts[i].x, pts[i].y);
+ CGContextAddLineToPoint(ctxRef, pts[i+1].x, pts[i+1].y);
+ }
+ CGContextStrokePath(ctxRef);
+ }
+ }
-long CreatePatternFromBrush(
- CGPatternRef *patternRef,
- const wxBrush &sourceBrush,
- bool useMultibit )
-{
- long errorStatus;
+ virtual void Render( CGContextRef ctxRef )
+ {
+ switch ( m_hatch )
+ {
+ case wxBDIAGONAL_HATCH :
+ {
+ CGPoint pts[] =
+ {
+ { 8.0 , 0.0 } , { 0.0 , 8.0 }
+ };
+ StrokeLineSegments( ctxRef , pts , 2 ) ;
+ }
+ break ;
- if (patternRef == NULL)
- return (-1);
+ case wxCROSSDIAG_HATCH :
+ {
+ CGPoint pts[] =
+ {
+ { 0.0 , 0.0 } , { 8.0 , 8.0 } ,
+ { 8.0 , 0.0 } , { 0.0 , 8.0 }
+ };
+ StrokeLineSegments( ctxRef , pts , 4 ) ;
+ }
+ break ;
- *patternRef = NULL;
- errorStatus = CreatePatternFromBitmap( patternRef, sourceBrush.GetStipple(), useMultibit );
+ case wxFDIAGONAL_HATCH :
+ {
+ CGPoint pts[] =
+ {
+ { 0.0 , 0.0 } , { 8.0 , 8.0 }
+ };
+ StrokeLineSegments( ctxRef , pts , 2 ) ;
+ }
+ break ;
- return errorStatus;
-}
+ case wxCROSS_HATCH :
+ {
+ CGPoint pts[] =
+ {
+ { 0.0 , 4.0 } , { 8.0 , 4.0 } ,
+ { 4.0 , 0.0 } , { 4.0 , 8.0 } ,
+ };
+ StrokeLineSegments( ctxRef , pts , 4 ) ;
+ }
+ break ;
-long CreatePatternFromPen(
- CGPatternRef *patternRef,
- const wxPen &sourcePen,
- bool useMultibit )
-{
- long errorStatus;
+ case wxHORIZONTAL_HATCH :
+ {
+ CGPoint pts[] =
+ {
+ { 0.0 , 4.0 } , { 8.0 , 4.0 } ,
+ };
+ StrokeLineSegments( ctxRef , pts , 2 ) ;
+ }
+ break ;
- if (patternRef == NULL)
- return (-1);
+ case wxVERTICAL_HATCH :
+ {
+ CGPoint pts[] =
+ {
+ { 4.0 , 0.0 } , { 4.0 , 8.0 } ,
+ };
+ StrokeLineSegments( ctxRef , pts , 2 ) ;
+ }
+ break ;
- *patternRef = NULL;
- errorStatus = CreatePatternFromBitmap( patternRef, sourcePen.GetStipple(), useMultibit );
+ default:
+ break;
+ }
+ }
+
+protected :
+ ~HatchPattern() {}
- return errorStatus;
-}
+ CGRect m_imageBounds ;
+ int m_hatch ;
+} ;
-// ------------
#pragma mark -
-// FIXME: the NEW_GC_SUPPORT part this routine is unfinished and needs lots of work !!
-//
void wxMacCGContext::SetPen( const wxPen &pen )
{
m_pen = pen ;
if ( m_cgContext == NULL )
return ;
+
bool fill = m_brush.GetStyle() != wxTRANSPARENT ;
bool stroke = pen.GetStyle() != wxTRANSPARENT ;
// we can benchmark performance, should go into a setting later
CGContextSetShouldAntialias( m_cgContext , false ) ;
#endif
+
if ( fill | stroke )
{
- // setup brushes
+ // set up brushes
m_mode = kCGPathFill ; // just a default
- if ( fill )
- {
- m_mode = kCGPathFill ;
- }
if ( stroke )
{
-#if defined(_NEW_GC_SUPPORT_)
- // new candidate
- {
- CGPatternRef patternRef;
- float alphaArray[1];
- long result;
- bool hasSetPattern, useMultibit;
-
- hasSetPattern = false;
- useMultibit = true;
- result = CreatePatternFromPen( &patternRef, pen, useMultibit );
- if (result == 0)
- {
- EstablishPatternColorSpace( m_cgContext, useMultibit, false );
-
- alphaArray[0] = 1.0;
- CGContextSetStrokePattern( m_cgContext, patternRef, alphaArray );
- CGPatternRelease( patternRef );
-
- hasSetPattern = true;
-
-//wxLogDebug( wxT("CreatePatternFromPen succeeded!") );
- }
-
- // NB: the (-2) result is from wxPen instances that don't have a stipple wxBitmap
- if (result < (-2))
- wxLogDebug( wxT("CreatePatternFromPen failed: result [%ld]"), result );
-
- if (!hasSetPattern)
- {
- RGBColor col;
-
-#if 1
- col = MAC_WXCOLORREF( pen.GetColour().GetPixel() );
-#else
- GetThemeBrushAsColor( pen.MacGetTheme(), 32, true, &col );
-#endif
-
- CGContextSetRGBStrokeColor(
- m_cgContext, (float) col.red / 65536.0,
- (float) col.green / 65536.0, (float) col.blue / 65536.0, 1.0 );
- }
- }
-
-#else
- // original implementation
RGBColor col = MAC_WXCOLORREF( pen.GetColour().GetPixel() ) ;
CGContextSetRGBStrokeColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
-#endif
+
+ // TODO * m_dc->m_scaleX
+ float penWidth = pen.GetWidth();
+ if (penWidth <= 0.0)
+ penWidth = 0.1;
+ CGContextSetLineWidth( m_cgContext , penWidth ) ;
CGLineCap cap ;
- switch( pen.GetCap() )
+ switch ( pen.GetCap() )
{
case wxCAP_ROUND :
cap = kCGLineCapRound ;
break ;
+
case wxCAP_PROJECTING :
cap = kCGLineCapSquare ;
break ;
+
case wxCAP_BUTT :
cap = kCGLineCapButt ;
break ;
+
default :
cap = kCGLineCapButt ;
break ;
}
- CGContextSetLineCap( m_cgContext , cap ) ;
CGLineJoin join ;
- switch( pen.GetJoin() )
+ switch ( pen.GetJoin() )
{
case wxJOIN_BEVEL :
join = kCGLineJoinBevel ;
break ;
+
case wxJOIN_MITER :
join = kCGLineJoinMiter ;
break ;
+
case wxJOIN_ROUND :
join = kCGLineJoinRound ;
break ;
+
default :
join = kCGLineJoinMiter ;
break;
}
- CGContextSetLineJoin( m_cgContext , join ) ;
-
- /* TODO * m_dc->m_scaleX */
- float penWidth = pen.GetWidth();
- if (penWidth <= 0.0)
- penWidth = 0.1;
- CGContextSetLineWidth( m_cgContext , penWidth ) ;
m_mode = kCGPathStroke ;
int count = 0 ;
-
-#if defined(_NEW_GC_DASHES_)
- const char *dashData = NULL ;
- char *userDashData = NULL ;
- float alphaArray[1];
-
- const char dotted[] = { 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55, 0xAA, 0x55 };
- const char dashed[] = { 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0xFF, 0x00, 0x00 };
- const char short_dashed[] = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00 };
- const char dotted_dashed[] = { 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0xFF, 0x00 };
-
- switch (pen.GetStyle())
- {
- case wxSOLID:
- // default, undashed pen
- break;
-
- case wxDOT:
- dashData = dotted;
- count = WXSIZEOF(dotted);
- break;
- case wxLONG_DASH:
- dashData = dashed;
- count = WXSIZEOF(dashed);
- break;
- case wxSHORT_DASH:
- dashData = short_dashed;
- count = WXSIZEOF(short_dashed);
- break;
- case wxDOT_DASH:
- dashData = dotted_dashed;
- count = WXSIZEOF(dotted_dashed);
- break;
- case wxUSER_DASH:
- count = pen.GetDashes( (wxDash**)&userDashData );
- dashData = userDashData;
- break;
-
- default :
- break;
- }
-
- if ((dashData != NULL) && (count > 0))
- {
- CGPatternRef patternRef;
- RGBColor col;
- long result;
- bool useMultibit;
-
- useMultibit = true;
- result = CreatePatternFromDashes( &patternRef, (const wxDash*)dashData, count, useMultibit );
- if (result == 0)
- {
- col = MAC_WXCOLORREF( pen.GetColour().GetPixel() );
- CGContextSetRGBStrokeColor(
- m_cgContext, (float) col.red / 65536.0,
- (float) col.green / 65536.0, (float) col.blue / 65536.0, 1.0 );
-
- EstablishPatternColorSpace( m_cgContext, useMultibit, false );
-
- alphaArray[0] = 1.0;
- CGContextSetStrokePattern( m_cgContext, patternRef, alphaArray );
- CGPatternRelease( patternRef );
- }
-
- if (result != 0)
- wxLogDebug( wxT("CreatePatternFromDashes failed: result [%ld]"), result );
- }
-#else
+
const float *lengths = NULL ;
float *userLengths = NULL ;
-
- const float dotted[] = { 3 , 3 };
- const float dashed[] = { 19 , 9 };
- const float short_dashed[] = { 9 , 6 };
- const float dotted_dashed[] = { 9 , 6 , 3 , 3 };
-
- switch( pen.GetStyle() )
+
+ const float dashUnit = penWidth < 1.0 ? 1.0 : penWidth;
+
+ const float dotted[] = { dashUnit , dashUnit + 2.0 };
+ const float short_dashed[] = { 9.0 , 6.0 };
+ const float dashed[] = { 19.0 , 9.0 };
+ const float dotted_dashed[] = { 9.0 , 6.0 , 3.0 , 3.0 };
+
+ switch ( pen.GetStyle() )
{
case wxSOLID :
break ;
+
case wxDOT :
lengths = dotted ;
count = WXSIZEOF(dotted);
break ;
+
case wxLONG_DASH :
lengths = dashed ;
count = WXSIZEOF(dashed) ;
break ;
+
case wxSHORT_DASH :
lengths = short_dashed ;
count = WXSIZEOF(short_dashed) ;
break ;
+
case wxDOT_DASH :
lengths = dotted_dashed ;
count = WXSIZEOF(dotted_dashed);
break ;
+
case wxUSER_DASH :
wxDash *dashes ;
count = pen.GetDashes( &dashes ) ;
if ((dashes != NULL) && (count > 0))
{
userLengths = new float[count] ;
- for( int i = 0 ; i < count ; ++i )
+ for ( int i = 0 ; i < count ; ++i )
{
- userLengths[i] = (float)dashes[i] ;
- if (userLengths[i] <= 0.0)
- {
- userLengths[i] = 1.0;
-// wxLogDebug( wxT("wxMacCGContext::SetPen - bad dash length[%d] [%.2f]"), i, (float)dashes[i] );
- }
+ userLengths[i] = dashes[i] * dashUnit ;
+
+ if ( i % 2 == 1 && userLengths[i] < dashUnit + 2.0 )
+ userLengths[i] = dashUnit + 2.0 ;
+ else if ( i % 2 == 0 && userLengths[i] < dashUnit )
+ userLengths[i] = dashUnit ;
}
}
lengths = userLengths ;
break ;
+
+ case wxSTIPPLE :
+ {
+ float alphaArray[1] = { 1.0 } ;
+ wxBitmap* bmp = pen.GetStipple() ;
+ if ( bmp && bmp->Ok() )
+ {
+ wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( NULL ) ) ;
+ CGContextSetStrokeColorSpace( m_cgContext , patternSpace ) ;
+ wxMacCFRefHolder<CGPatternRef> pattern( *( new ImagePattern( bmp , CGContextGetCTM( m_cgContext ) ) ) );
+ CGContextSetStrokePattern( m_cgContext, pattern , alphaArray ) ;
+ }
+ }
+ break ;
+
default :
+ {
+ wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ) ;
+ CGContextSetStrokeColorSpace( m_cgContext , patternSpace ) ;
+ wxMacCFRefHolder<CGPatternRef> pattern( *( new HatchPattern( pen.GetStyle() , CGContextGetCTM( m_cgContext ) ) ) );
+
+ RGBColor col = MAC_WXCOLORREF( pen.GetColour().GetPixel() ) ;
+ float colorArray[4] = { col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 } ;
+
+ CGContextSetStrokePattern( m_cgContext, pattern , colorArray ) ;
+ }
break ;
}
if ((lengths != NULL) && (count > 0))
{
- // we need to change the cap, otherwise everything overlaps
- // and we get solid lines
CGContextSetLineDash( m_cgContext , 0 , lengths , count ) ;
- CGContextSetLineCap( m_cgContext , kCGLineCapButt ) ;
+ // force the line cap, otherwise we get artifacts (overlaps) and just solid lines
+ cap = kCGLineCapButt ;
}
else
{
CGContextSetLineDash( m_cgContext , 0 , NULL , 0 ) ;
}
+ CGContextSetLineCap( m_cgContext , cap ) ;
+ CGContextSetLineJoin( m_cgContext , join ) ;
+
delete[] userLengths ;
-#endif
}
+
if ( fill && stroke )
- {
m_mode = kCGPathFillStroke ;
- }
}
}
if ( fill )
{
-#if defined(_NEW_GC_SUPPORT_)
- // new candidate
+ if ( brush.GetStyle() == wxSOLID )
+ {
+ RGBColor col = MAC_WXCOLORREF( brush.GetColour().GetPixel() ) ;
+ CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+ }
+ else if ( brush.IsHatch() )
{
- CGPatternRef patternRef;
- float alphaArray[1];
- long result;
- bool hasSetPattern, useMultibit;
-
- hasSetPattern = false;
- useMultibit = true;
- result = CreatePatternFromBrush( &patternRef, brush, useMultibit );
- if (result == 0)
+ wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ) ;
+ CGContextSetFillColorSpace( m_cgContext , patternSpace ) ;
+ wxMacCFRefHolder<CGPatternRef> pattern( *( new HatchPattern( brush.GetStyle() , CGContextGetCTM( m_cgContext ) ) ) );
+
+ RGBColor col = MAC_WXCOLORREF( brush.GetColour().GetPixel() ) ;
+ float colorArray[4] = { col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 } ;
+
+ CGContextSetFillPattern( m_cgContext, pattern , colorArray ) ;
+ }
+ else
+ {
+ // now brush is a bitmap
+ float alphaArray[1] = { 1.0 } ;
+ wxBitmap* bmp = brush.GetStipple() ;
+ if ( bmp && bmp->Ok() )
{
- EstablishPatternColorSpace( m_cgContext, useMultibit, true );
-
- alphaArray[0] = 1.0;
- CGContextSetFillPattern( m_cgContext, patternRef, alphaArray );
- CGPatternRelease( patternRef );
-
- hasSetPattern = true;
-
-//wxLogDebug( wxT("CreatePatternFromBrush succeeded!") );
- }
-
- // NB: the (-2) result is from wxBrush instances that don't have a stipple wxBitmap
- if (result < (-2))
- wxLogDebug( wxT("CreatePatternFromBrush failed: result [%ld]"), result );
-
- if (!hasSetPattern)
- {
- RGBColor col;
-
-#if 1
- col = MAC_WXCOLORREF( brush.GetColour().GetPixel() );
-#else
- GetThemeBrushAsColor( brush.MacGetTheme(), 32, true, &col );
-#endif
-
- CGContextSetRGBFillColor(
- m_cgContext, (float) col.red / 65536.0,
- (float) col.green / 65536.0, (float) col.blue / 65536.0, 1.0 );
+ wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( NULL ) ) ;
+ CGContextSetFillColorSpace( m_cgContext , patternSpace ) ;
+ wxMacCFRefHolder<CGPatternRef> pattern( *( new ImagePattern( bmp , CGContextGetCTM( m_cgContext ) ) ) );
+ CGContextSetFillPattern( m_cgContext, pattern , alphaArray ) ;
}
}
-#else
- // original implementation
- RGBColor col = MAC_WXCOLORREF( brush.GetColour().GetPixel() ) ;
- CGContextSetRGBFillColor( m_cgContext , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
-#endif
-
m_mode = kCGPathFill ;
}
- if ( stroke )
- {
- m_mode = kCGPathStroke ;
- }
+
if ( fill && stroke )
- {
m_mode = kCGPathFillStroke ;
- }
+ else if ( stroke )
+ m_mode = kCGPathStroke ;
}
}
CGContextAddRect(c, rect);
return;
}
+
CGContextSaveGState(c);
CGContextTranslateCTM(c, CGRectGetMinX(rect), CGRectGetMinY(rect));
CGContextScaleCTM(c, ovalWidth, ovalHeight);
+
fw = CGRectGetWidth(rect) / ovalWidth;
fh = CGRectGetHeight(rect) / ovalHeight;
- CGContextMoveToPoint(c, fw, fh/2);
- CGContextAddArcToPoint(c, fw, fh, fw/2, fh, 1);
- CGContextAddArcToPoint(c, 0, fh, 0, fh/2, 1);
- CGContextAddArcToPoint(c, 0, 0, fw/2, 0, 1);
- CGContextAddArcToPoint(c, fw, 0, fw, fh/2, 1);
+
+ CGContextMoveToPoint(c, fw, fh / 2);
+ CGContextAddArcToPoint(c, fw, fh, fw / 2, fh, 1);
+ CGContextAddArcToPoint(c, 0, fh, 0, fh / 2, 1);
+ CGContextAddArcToPoint(c, 0, 0, fw / 2, 0, 1);
+ CGContextAddArcToPoint(c, fw, 0, fw, fh / 2, 1);
CGContextClosePath(c);
CGContextRestoreGState(c);
}
+#pragma mark -
+
wxDC::wxDC()
{
- m_ok = FALSE;
- m_colour = TRUE;
+ m_ok = false ;
+ m_colour = true;
m_mm_to_pix_x = mm2pt;
m_mm_to_pix_y = mm2pt;
- m_internalDeviceOriginX = 0;
- m_internalDeviceOriginY = 0;
+
m_externalDeviceOriginX = 0;
m_externalDeviceOriginY = 0;
m_logicalScaleX = 1.0;
m_userScaleY = 1.0;
m_scaleX = 1.0;
m_scaleY = 1.0;
- m_needComputeScaleX = FALSE;
- m_needComputeScaleY = FALSE;
+ m_needComputeScaleX =
+ m_needComputeScaleY = false;
- m_ok = FALSE ;
m_macPort = 0 ;
- m_macLocalOrigin.x = m_macLocalOrigin.y = 0 ;
+ m_macLocalOrigin.x =
+ m_macLocalOrigin.y = 0 ;
m_pen = *wxBLACK_PEN;
m_font = *wxNORMAL_FONT;
m_brush = *wxWHITE_BRUSH;
m_macATSUIStyle = NULL ;
-
m_graphicContext = NULL ;
}
-wxDC::~wxDC(void)
+wxDC::~wxDC()
{
- if( m_macATSUIStyle )
+ if ( m_macATSUIStyle )
{
::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle);
m_macATSUIStyle = NULL ;
void wxDC::DoDrawBitmap( const wxBitmap &bmp, wxCoord x, wxCoord y, bool useMask )
{
- wxCHECK_RET( Ok(), wxT("invalid window dc") );
- wxCHECK_RET( bmp.Ok(), wxT("invalid bitmap") );
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawBitmap - invalid DC") );
+ wxCHECK_RET( bmp.Ok(), wxT("wxDC(cg)::DoDrawBitmap - invalid bitmap") );
+
wxCoord xx = XLOG2DEVMAC(x);
wxCoord yy = YLOG2DEVMAC(y);
wxCoord w = bmp.GetWidth();
void wxDC::DoDrawIcon( const wxIcon &icon, wxCoord x, wxCoord y )
{
- wxCHECK_RET(Ok(), wxT("Invalid dc wxDC::DoDrawIcon"));
- wxCHECK_RET(icon.Ok(), wxT("Invalid icon wxDC::DoDrawIcon"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawIcon - invalid DC") );
+ wxCHECK_RET( icon.Ok(), wxT("wxDC(cg)::DoDrawIcon - invalid icon") );
wxCoord xx = XLOG2DEVMAC(x);
wxCoord yy = YLOG2DEVMAC(y);
CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
CGRect r = CGRectMake( 00 , 00 , ww , hh ) ;
- CGContextSaveGState(cg);
- CGContextTranslateCTM(cg, xx , yy + hh );
- CGContextScaleCTM(cg, 1, -1);
+ CGContextSaveGState( cg );
+ CGContextTranslateCTM( cg, xx , yy + hh );
+ CGContextScaleCTM( cg, 1, -1 );
PlotIconRefInContext( cg , &r , kAlignNone , kTransformNone ,
NULL , kPlotIconRefNormalFlags , MAC_WXHICON( icon.GetHICON() ) ) ;
CGContextRestoreGState( cg ) ;
void wxDC::DoSetClippingRegion( wxCoord x, wxCoord y, wxCoord width, wxCoord height )
{
- wxCHECK_RET(Ok(), wxT("wxDC::DoSetClippingRegion Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoSetClippingRegion - invalid DC") );
+
wxCoord xx, yy, ww, hh;
xx = XLOG2DEVMAC(x);
yy = YLOG2DEVMAC(y);
hh = YLOG2DEVREL(height);
CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
- CGRect clipRect = CGRectMake( xx ,yy , ww, hh ) ;
+ CGRect clipRect = CGRectMake( xx , yy , ww, hh ) ;
CGContextClipToRect( cgContext , clipRect ) ;
// SetRectRgn( (RgnHandle) m_macCurrentClipRgn , xx , yy , xx + ww , yy + hh ) ;
// SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
- if( m_clipping )
+
+ if ( m_clipping )
{
- m_clipX1 = wxMax( m_clipX1 , xx );
- m_clipY1 = wxMax( m_clipY1 , yy );
- m_clipX2 = wxMin( m_clipX2, (xx + ww));
- m_clipY2 = wxMin( m_clipY2, (yy + hh));
+ m_clipX1 = wxMax( m_clipX1, xx );
+ m_clipY1 = wxMax( m_clipY1, yy );
+ m_clipX2 = wxMin( m_clipX2, (xx + ww) );
+ m_clipY2 = wxMin( m_clipY2, (yy + hh) );
}
else
{
- m_clipping = TRUE;
+ m_clipping = true;
+
m_clipX1 = xx;
m_clipY1 = yy;
m_clipX2 = xx + ww;
m_clipY2 = yy + hh;
}
- // TODO as soon as we don't reset the context for each operation anymore
+
+ // TODO: as soon as we don't reset the context for each operation anymore
// we have to update the context as well
}
-void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion )
+void wxDC::DoSetClippingRegionAsRegion( const wxRegion ®ion )
{
- wxCHECK_RET( Ok(), wxT("invalid window dc") ) ;
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoSetClippingRegionAsRegion - invalid DC") );
+
if (region.Empty())
{
DestroyClippingRegion();
return;
}
+
wxCoord x, y, w, h;
region.GetBox( x, y, w, h );
wxCoord xx, yy, ww, hh;
yy = YLOG2DEVMAC(y);
ww = XLOG2DEVREL(w);
hh = YLOG2DEVREL(h);
+
// if we have a scaling that we cannot map onto native regions
// we must use the box
if ( ww != w || hh != h )
}
else
{
- /*
+#if 0
CopyRgn( (RgnHandle) region.GetWXHRGN() , (RgnHandle) m_macCurrentClipRgn ) ;
if ( xx != x || yy != y )
- {
OffsetRgn( (RgnHandle) m_macCurrentClipRgn , xx - x , yy - y ) ;
- }
- SectRgn( (RgnHandle) m_macCurrentClipRgn , (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
- */
- if( m_clipping )
+ SectRgn( (RgnHandle)m_macCurrentClipRgn , (RgnHandle)m_macBoundaryClipRgn , (RgnHandle)m_macCurrentClipRgn ) ;
+#endif
+
+ if ( m_clipping )
{
- m_clipX1 = wxMax( m_clipX1 , xx );
- m_clipY1 = wxMax( m_clipY1 , yy );
- m_clipX2 = wxMin( m_clipX2, (xx + ww));
- m_clipY2 = wxMin( m_clipY2, (yy + hh));
+ m_clipX1 = wxMax( m_clipX1, xx );
+ m_clipY1 = wxMax( m_clipY1, yy );
+ m_clipX2 = wxMin( m_clipX2, (xx + ww) );
+ m_clipY2 = wxMin( m_clipY2, (yy + hh) );
}
else
{
- m_clipping = TRUE;
+ m_clipping = true;
+
m_clipX1 = xx;
m_clipY1 = yy;
m_clipX2 = xx + ww;
void wxDC::DestroyClippingRegion()
{
// CopyRgn( (RgnHandle) m_macBoundaryClipRgn , (RgnHandle) m_macCurrentClipRgn ) ;
+
CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
CGContextRestoreGState( cgContext );
- CGContextSaveGState( cgContext );
+ CGContextSaveGState( cgContext );
+
m_graphicContext->SetPen( m_pen ) ;
m_graphicContext->SetBrush( m_brush ) ;
- m_clipping = FALSE;
+
+ m_clipping = false;
}
void wxDC::DoGetSizeMM( int* width, int* height ) const
{
- int w = 0;
- int h = 0;
+ int w = 0, h = 0;
+
GetSize( &w, &h );
- *width = long( double(w) / (m_scaleX*m_mm_to_pix_x) );
- *height = long( double(h) / (m_scaleY*m_mm_to_pix_y) );
+ if (width)
+ *width = long( double(w) / (m_scaleX * m_mm_to_pix_x) );
+ if (height)
+ *height = long( double(h) / (m_scaleY * m_mm_to_pix_y) );
}
void wxDC::SetTextForeground( const wxColour &col )
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::SetTextForeground - invalid DC") );
+
if ( col != m_textForegroundColour )
{
m_textForegroundColour = col;
void wxDC::SetTextBackground( const wxColour &col )
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::SetTextBackground - invalid DC") );
+
m_textBackgroundColour = col;
}
switch (mode)
{
case wxMM_TWIPS:
- SetLogicalScale( twips2mm*m_mm_to_pix_x, twips2mm*m_mm_to_pix_y );
+ SetLogicalScale( twips2mm * m_mm_to_pix_x, twips2mm * m_mm_to_pix_y );
break;
+
case wxMM_POINTS:
- SetLogicalScale( pt2mm*m_mm_to_pix_x, pt2mm*m_mm_to_pix_y );
+ SetLogicalScale( pt2mm * m_mm_to_pix_x, pt2mm * m_mm_to_pix_y );
break;
+
case wxMM_METRIC:
SetLogicalScale( m_mm_to_pix_x, m_mm_to_pix_y );
break;
+
case wxMM_LOMETRIC:
- SetLogicalScale( m_mm_to_pix_x/10.0, m_mm_to_pix_y/10.0 );
+ SetLogicalScale( m_mm_to_pix_x / 10.0, m_mm_to_pix_y / 10.0 );
break;
- default:
+
case wxMM_TEXT:
+ default:
SetLogicalScale( 1.0, 1.0 );
break;
}
+
if (mode != wxMM_TEXT)
{
- m_needComputeScaleX = TRUE;
- m_needComputeScaleY = TRUE;
+ m_needComputeScaleX =
+ m_needComputeScaleY = true;
}
}
void wxDC::SetAxisOrientation( bool xLeftRight, bool yBottomUp )
{
m_signX = (xLeftRight ? 1 : -1);
- m_signY = (yBottomUp ? -1 : 1);
+ m_signY = (yBottomUp ? -1 : 1);
ComputeScaleAndOrigin();
}
double origScaleY = m_scaleY;
m_scaleX = m_logicalScaleX * m_userScaleX;
m_scaleY = m_logicalScaleY * m_userScaleY;
- m_deviceOriginX = m_internalDeviceOriginX + m_externalDeviceOriginX;
- m_deviceOriginY = m_internalDeviceOriginY + m_externalDeviceOriginY;
+ m_deviceOriginX = m_externalDeviceOriginX;
+ m_deviceOriginY = m_externalDeviceOriginY;
+
// CMB: if scale has changed call SetPen to recalulate the line width
if (m_scaleX != origScaleX || m_scaleY != origScaleY)
{
// this is a bit artificial, but we need to force wxDC to think
// the pen has changed
- wxPen pen(GetPen());
+ wxPen pen( GetPen() );
+
m_pen = wxNullPen;
SetPen(pen);
}
}
-void wxDC::SetPalette( const wxPalette& palette )
+void wxDC::SetPalette( const wxPalette& palette )
{
}
-void wxDC::SetBackgroundMode( int mode )
+void wxDC::SetBackgroundMode( int mode )
{
m_backgroundMode = mode ;
}
-void wxDC::SetFont( const wxFont &font )
+void wxDC::SetFont( const wxFont &font )
{
m_font = font;
MacInstallFont() ;
}
-void wxDC::SetPen( const wxPen &pen )
+void wxDC::SetPen( const wxPen &pen )
{
if ( m_pen == pen )
return ;
+
m_pen = pen;
if ( m_graphicContext )
{
- m_graphicContext->SetPen( m_pen ) ;
+ if ( m_pen.GetStyle() == wxSOLID || m_pen.GetStyle() == wxTRANSPARENT )
+ {
+ m_graphicContext->SetPen( m_pen ) ;
+ }
+ else
+ {
+ // we have to compensate for moved device origins etc. otherwise patterned pens are standing still
+ // eg when using a wxScrollWindow and scrolling around
+ CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
+ int origX = XLOG2DEVMAC(0) ;
+ int origY = YLOG2DEVMAC(0) ;
+ CGContextTranslateCTM( cgContext, origX, origY );
+ m_graphicContext->SetPen( m_pen ) ;
+ CGContextTranslateCTM( cgContext, -origX, -origY );
+ }
}
}
-void wxDC::SetBrush( const wxBrush &brush )
+void wxDC::SetBrush( const wxBrush &brush )
{
if (m_brush == brush)
return;
+
m_brush = brush;
if ( m_graphicContext )
{
- m_graphicContext->SetBrush( m_brush ) ;
+ if ( brush.GetStyle() == wxSOLID || brush.GetStyle() == wxTRANSPARENT )
+ {
+ m_graphicContext->SetBrush( m_brush ) ;
+ }
+ else
+ {
+ // we have to compensate for moved device origins etc. otherwise patterned brushes are standing still
+ // eg when using a wxScrollWindow and scrolling around
+ CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
+ int origX = XLOG2DEVMAC(0) ;
+ int origY = YLOG2DEVMAC(0) ;
+ CGContextTranslateCTM( cgContext, origX, origY );
+ m_graphicContext->SetBrush( m_brush ) ;
+ CGContextTranslateCTM( cgContext, -origX, -origY );
+ }
}
}
-void wxDC::SetBackground( const wxBrush &brush )
+void wxDC::SetBackground( const wxBrush &brush )
{
if (m_backgroundBrush == brush)
return;
+
m_backgroundBrush = brush;
if (!m_backgroundBrush.Ok())
return;
}
-void wxDC::SetLogicalFunction( int function )
+void wxDC::SetLogicalFunction( int function )
{
if (m_logicalFunction == function)
return;
+
m_logicalFunction = function ;
}
return wxDoFloodFill(this, x, y, col, style);
}
-bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
+bool wxDC::DoGetPixel( wxCoord x, wxCoord y, wxColour *col ) const
{
- wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel Invalid DC") );
- wxCHECK_MSG( Ok(), false, wxT("wxDC::DoGetPixel Invalid DC") );
+ wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoGetPixel - invalid DC") );
+
wxMacPortSaver helper((CGrafPtr)m_macPort) ;
RGBColor colour;
+
+ // NB: GetCPixel is a deprecated QD call, and a slow one at that
GetCPixel(
XLOG2DEVMAC(x) + m_macLocalOriginInPort.x - m_macLocalOrigin.x,
YLOG2DEVMAC(y) + m_macLocalOriginInPort.y - m_macLocalOrigin.y, &colour );
- // Convert from Mac colour to wx
- col->Set( colour.red >> 8,
- colour.green >> 8,
- colour.blue >> 8);
+
+ // convert from Mac colour to wx
+ col->Set( colour.red >> 8, colour.green >> 8, colour.blue >> 8 );
+
return true ;
}
-void wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
+void wxDC::DoDrawLine( wxCoord x1, wxCoord y1, wxCoord x2, wxCoord y2 )
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
-
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawLine - invalid DC") );
+
if ( m_logicalFunction != wxCOPY )
return ;
-
+
wxCoord xx1 = XLOG2DEVMAC(x1) ;
wxCoord yy1 = YLOG2DEVMAC(y1) ;
wxCoord xx2 = XLOG2DEVMAC(x2) ;
wxCoord yy2 = YLOG2DEVMAC(y2) ;
wxGraphicPath* path = m_graphicContext->CreatePath() ;
- path->MoveToPoint( xx1 , yy1 ) ;
+ path->MoveToPoint( xx1, yy1 ) ;
path->AddLineToPoint( xx2 , yy2 ) ;
path->CloseSubpath() ;
m_graphicContext->StrokePath( path ) ;
CalcBoundingBox(x2, y2);
}
-void wxDC::DoCrossHair( wxCoord x, wxCoord y )
+void wxDC::DoCrossHair( wxCoord x, wxCoord y )
{
- wxCHECK_RET( Ok(), wxT("wxDC::DoCrossHair Invalid window dc") );
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoCrossHair - invalid DC") );
if ( m_logicalFunction != wxCOPY )
return ;
- int w = 0;
- int h = 0;
+ int w = 0, h = 0;
+
GetSize( &w, &h );
wxCoord xx = XLOG2DEVMAC(x);
wxCoord yy = YLOG2DEVMAC(y);
wxGraphicPath* path = m_graphicContext->CreatePath() ;
- path->MoveToPoint( XLOG2DEVMAC(0), yy ) ;
+ path->MoveToPoint( XLOG2DEVMAC(0), yy ) ;
path->AddLineToPoint( XLOG2DEVMAC(w), yy ) ;
path->CloseSubpath() ;
path->MoveToPoint( xx, YLOG2DEVMAC(0) ) ;
delete path ;
CalcBoundingBox(x, y);
- CalcBoundingBox(x+w, y+h);
+ CalcBoundingBox(x + w, y + h);
}
-void wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
+void wxDC::DoDrawArc( wxCoord x1, wxCoord y1,
wxCoord x2, wxCoord y2,
wxCoord xc, wxCoord yc )
{
- wxCHECK_RET(Ok(), wxT("wxDC::DoDrawArc Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawArc - invalid DC") );
if ( m_logicalFunction != wxCOPY )
return ;
wxCoord yy2 = YLOG2DEVMAC(y2);
wxCoord xxc = XLOG2DEVMAC(xc);
wxCoord yyc = YLOG2DEVMAC(yc);
+
double dx = xx1 - xxc;
double dy = yy1 - yyc;
- double radius = sqrt((double)(dx*dx+dy*dy));
- wxCoord rad = (wxCoord)radius;
+ double radius = sqrt((double)(dx * dx + dy * dy));
+ wxCoord rad = (wxCoord)radius;
double sa, ea;
if (xx1 == xx2 && yy1 == yy2)
{
{
sa = (xx1 - xxc == 0) ?
(yy1 - yyc < 0) ? 90.0 : -90.0 :
- -atan2(double(yy1-yyc), double(xx1-xxc)) * RAD2DEG;
+ -atan2(double(yy1 - yyc), double(xx1 - xxc)) * RAD2DEG;
ea = (xx2 - xxc == 0) ?
(yy2 - yyc < 0) ? 90.0 : -90.0 :
- -atan2(double(yy2-yyc), double(xx2-xxc)) * RAD2DEG;
+ -atan2(double(yy2 - yyc), double(xx2 - xxc)) * RAD2DEG;
}
bool fill = m_brush.GetStyle() != wxTRANSPARENT ;
CGContextScaleCTM( ctx , 1 , -1 ) ;
if ( fill )
CGContextMoveToPoint( ctx , 0 , 0 ) ;
- CGContextAddArc( ctx, 0, 0 , rad , DegToRad(sa), DegToRad(ea), 0);
+ CGContextAddArc( ctx, 0, 0 , rad , DegToRad(sa), DegToRad(ea), 0 );
if ( fill )
CGContextAddLineToPoint( ctx , 0 , 0 ) ;
CGContextRestoreGState( ctx ) ;
CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
}
-void wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
+void wxDC::DoDrawEllipticArc( wxCoord x, wxCoord y, wxCoord w, wxCoord h,
double sa, double ea )
{
- wxCHECK_RET(Ok(), wxT("wxDC::DoDrawEllepticArc Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawEllipticArc - invalid DC") );
if ( m_logicalFunction != wxCOPY )
return ;
wxCoord yy = YLOG2DEVMAC(y);
wxCoord ww = m_signX * XLOG2DEVREL(w);
wxCoord hh = m_signY * YLOG2DEVREL(h);
+
// handle -ve width and/or height
- if (ww < 0) { ww = -ww; xx = xx - ww; }
- if (hh < 0) { hh = -hh; yy = yy - hh; }
+ if (ww < 0)
+ {
+ ww = -ww;
+ xx = xx - ww;
+ }
+ if (hh < 0)
+ {
+ hh = -hh;
+ yy = yy - hh;
+ }
bool fill = m_brush.GetStyle() != wxTRANSPARENT ;
CGContextRef ctx = mctx->GetNativeContext() ;
CGContextSaveGState( ctx ) ;
- CGContextTranslateCTM( ctx, xx + ww / 2, yy + hh / 2);
+ CGContextTranslateCTM( ctx, xx + ww / 2, yy + hh / 2 );
CGContextScaleCTM( ctx , 1 * ww / 2 , -1 * hh / 2 ) ;
if ( fill )
CGContextMoveToPoint( ctx , 0 , 0 ) ;
- CGContextAddArc( ctx, 0, 0, 1, DegToRad(sa), DegToRad(ea), 0);
+ CGContextAddArc( ctx, 0, 0, 1, DegToRad(sa), DegToRad(ea), 0 );
if ( fill )
CGContextAddLineToPoint( ctx , 0 , 0 ) ;
CGContextRestoreGState( ctx ) ;
CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
}
-void wxDC::DoDrawPoint( wxCoord x, wxCoord y )
+void wxDC::DoDrawPoint( wxCoord x, wxCoord y )
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawPoint - invalid DC") );
+
DoDrawLine( x , y , x + 1 , y + 1 ) ;
}
-void wxDC::DoDrawLines(int n, wxPoint points[],
+void wxDC::DoDrawLines(int n, wxPoint points[],
wxCoord xoffset, wxCoord yoffset)
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
-
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawLines - invalid DC") );
+
if ( m_logicalFunction != wxCOPY )
return ;
path->AddLineToPoint( x2 , y2 ) ;
}
+
+ m_graphicContext->StrokePath( path ) ;
+ delete path ;
+}
+
+#if wxUSE_SPLINES
+void wxDC::DoDrawSpline(wxList *points)
+{
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawSpline - invalid DC") );
+
+ if ( m_logicalFunction != wxCOPY )
+ return ;
+
+ wxGraphicPath* path = m_graphicContext->CreatePath() ;
+
+ wxList::compatibility_iterator node = points->GetFirst();
+ if (node == wxList::compatibility_iterator())
+ // empty list
+ return;
+
+ wxPoint *p = (wxPoint *)node->GetData();
+
+ wxCoord x1 = p->x;
+ wxCoord y1 = p->y;
+
+ node = node->GetNext();
+ p = (wxPoint *)node->GetData();
+
+ wxCoord x2 = p->x;
+ wxCoord y2 = p->y;
+ wxCoord cx1 = ( x1 + x2 ) / 2;
+ wxCoord cy1 = ( y1 + y2 ) / 2;
+
+ path->MoveToPoint( XLOG2DEVMAC( x1 ) , XLOG2DEVMAC( y1 ) ) ;
+ path->AddLineToPoint( XLOG2DEVMAC( cx1 ) , XLOG2DEVMAC( cy1 ) ) ;
+
+#if !wxUSE_STL
+ while ((node = node->GetNext()) != NULL)
+#else
+ while ((node = node->GetNext()))
+#endif // !wxUSE_STL
+ {
+ p = (wxPoint *)node->GetData();
+ x1 = x2;
+ y1 = y2;
+ x2 = p->x;
+ y2 = p->y;
+ wxCoord cx4 = (x1 + x2) / 2;
+ wxCoord cy4 = (y1 + y2) / 2;
+
+ path->AddQuadCurveToPoint( XLOG2DEVMAC( x1 ) , XLOG2DEVMAC( y1 ) ,
+ XLOG2DEVMAC( cx4 ) , XLOG2DEVMAC( cy4 ) ) ;
+
+ cx1 = cx4;
+ cy1 = cy4;
+ }
+
+ path->AddLineToPoint( XLOG2DEVMAC( x2 ) , XLOG2DEVMAC( y2 ) ) ;
+
m_graphicContext->StrokePath( path ) ;
delete path ;
}
+#endif
-void wxDC::DoDrawPolygon(int n, wxPoint points[],
+void wxDC::DoDrawPolygon( int n, wxPoint points[],
wxCoord xoffset, wxCoord yoffset,
int fillStyle )
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
- wxCoord x1, x2 , y1 , y2 ;
- if ( n== 0 || (m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT ) )
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawPolygon - invalid DC") );
+
+ if ( n <= 0 || (m_brush.GetStyle() == wxTRANSPARENT && m_pen.GetStyle() == wxTRANSPARENT ) )
return ;
-
if ( m_logicalFunction != wxCOPY )
return ;
+ wxCoord x1, x2 , y1 , y2 ;
x2 = x1 = XLOG2DEVMAC(points[0].x + xoffset);
y2 = y1 = YLOG2DEVMAC(points[0].y + yoffset);
path->AddLineToPoint( x2 , y2 ) ;
}
+
if ( x1 != x2 || y1 != y2 )
- {
- path->AddLineToPoint( x1,y1 ) ;
- }
+ path->AddLineToPoint( x1, y1 ) ;
+
path->CloseSubpath() ;
m_graphicContext->DrawPath( path , fillStyle ) ;
+
delete path ;
}
void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawRectangle - invalid DC") );
if ( m_logicalFunction != wxCOPY )
return ;
wxCoord yy = YLOG2DEVMAC(y);
wxCoord ww = m_signX * XLOG2DEVREL(width);
wxCoord hh = m_signY * YLOG2DEVREL(height);
+
// CMB: draw nothing if transformed w or h is 0
if (ww == 0 || hh == 0)
return;
+
// CMB: handle -ve width and/or height
if (ww < 0)
{
hh = -hh;
yy = yy - hh;
}
+
wxGraphicPath* path = m_graphicContext->CreatePath() ;
- path->AddRectangle(xx ,yy , ww , hh ) ;
+ path->AddRectangle( xx , yy , ww , hh ) ;
m_graphicContext->DrawPath( path ) ;
delete path ;
}
-void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
+void wxDC::DoDrawRoundedRectangle(wxCoord x, wxCoord y,
wxCoord width, wxCoord height,
double radius)
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawRoundedRectangle - invalid DC") );
if ( m_logicalFunction != wxCOPY )
return ;
-
if (radius < 0.0)
radius = - radius * ((width < height) ? width : height);
wxCoord xx = XLOG2DEVMAC(x);
wxCoord yy = YLOG2DEVMAC(y);
wxCoord ww = m_signX * XLOG2DEVREL(width);
wxCoord hh = m_signY * YLOG2DEVREL(height);
+
// CMB: draw nothing if transformed w or h is 0
if (ww == 0 || hh == 0)
return;
+
// CMB: handle -ve width and/or height
if (ww < 0)
{
hh = -hh;
yy = yy - hh;
}
+
wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ;
CGContextRef ctx = mctx->GetNativeContext() ;
- AddRoundedRectToPath( ctx , CGRectMake( xx , yy , ww , hh ) , 16 ,16 ) ;
+ AddRoundedRectToPath( ctx , CGRectMake( xx , yy , ww , hh ) , 16 ,16 ) ;
CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
}
-void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
+void wxDC::DoDrawEllipse(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawEllipse - invalid DC") );
if ( m_logicalFunction != wxCOPY )
return ;
// CMB: draw nothing if transformed w or h is 0
if (ww == 0 || hh == 0)
return;
+
// CMB: handle -ve width and/or height
if (ww < 0)
{
wxMacCGContext* mctx = ((wxMacCGContext*) m_graphicContext) ;
CGContextRef ctx = mctx->GetNativeContext() ;
CGContextSaveGState( ctx ) ;
- CGContextTranslateCTM( ctx, xx + ww / 2, yy + hh / 2);
+ CGContextTranslateCTM( ctx, xx + ww / 2, yy + hh / 2 );
CGContextScaleCTM( ctx , ww / 2 , hh / 2 ) ;
- CGContextAddArc( ctx, 0, 0, 1, 0 , 2*M_PI , 0);
+ CGContextAddArc( ctx, 0, 0, 1, 0 , 2 * M_PI , 0 );
CGContextRestoreGState( ctx ) ;
CGContextDrawPath( ctx , mctx->GetDrawingMode() ) ;
}
-bool wxDC::CanDrawBitmap(void) const
+bool wxDC::CanDrawBitmap(void) const
{
return true ;
}
-bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
+bool wxDC::DoBlit(wxCoord xdest, wxCoord ydest, wxCoord width, wxCoord height,
wxDC *source, wxCoord xsrc, wxCoord ysrc, int logical_func , bool useMask,
- wxCoord xsrcMask, wxCoord ysrcMask )
+ wxCoord xsrcMask, wxCoord ysrcMask )
{
- wxCHECK_MSG(Ok(), false, wxT("wxDC::DoBlit Illegal dc"));
- wxCHECK_MSG(source->Ok(), false, wxT("wxDC::DoBlit Illegal source DC"));
+ wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoBlit - invalid DC") );
+ wxCHECK_MSG( source->Ok(), false, wxT("wxDC(cg)::DoBlit - invalid source DC") );
+
if ( logical_func == wxNO_OP )
- return TRUE ;
+ return true ;
+
if (xsrcMask == -1 && ysrcMask == -1)
{
- xsrcMask = xsrc; ysrcMask = ysrc;
+ xsrcMask = xsrc;
+ ysrcMask = ysrc;
}
wxCoord yysrc = source->YLOG2DEVMAC(ysrc) ;
- wxCoord xxsrc = source->XLOG2DEVMAC(xsrc) ;
- wxCoord wwsrc = source->XLOG2DEVREL(width ) ;
+ wxCoord xxsrc = source->XLOG2DEVMAC(xsrc) ;
+ wxCoord wwsrc = source->XLOG2DEVREL(width) ;
wxCoord hhsrc = source->YLOG2DEVREL(height) ;
wxCoord yydest = YLOG2DEVMAC(ydest) ;
wxCoord xxdest = XLOG2DEVMAC(xdest) ;
- wxCoord wwdest = XLOG2DEVREL(width ) ;
+ wxCoord wwdest = XLOG2DEVREL(width) ;
wxCoord hhdest = YLOG2DEVREL(height) ;
wxMemoryDC* memdc = dynamic_cast<wxMemoryDC*>(source) ;
if ( memdc && logical_func == wxCOPY )
{
wxBitmap blit = memdc->GetSelectedObject() ;
+
wxASSERT_MSG( blit.Ok() , wxT("Invalid bitmap for blitting") ) ;
wxCoord bmpwidth = blit.GetWidth();
blit = wxNullBitmap ;
}
}
+
if ( blit.Ok() )
{
CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
HIViewDrawCGImage( cg , &r , image ) ;
CGImageRelease( image ) ;
}
-
}
else
{
- /*
+#if 0
CGContextRef cg = (wxMacCGContext*)(source->GetGraphicContext())->GetNativeContext() ;
void *data = CGBitmapContextGetData( cg ) ;
- */
- return FALSE ; // wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ;
+#endif
+
+ return false ; // wxFAIL_MSG( wxT("Blitting is only supported from bitmap contexts") ) ;
}
- return TRUE;
+
+ return true;
}
-void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
+void wxDC::DoDrawRotatedText(const wxString& str, wxCoord x, wxCoord y,
double angle)
{
- wxCHECK_RET( Ok(), wxT("wxDC::DoDrawRotatedText Invalid window dc") );
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawRotatedText - invalid DC") );
+ wxCHECK_RET( m_macATSUIStyle != NULL, wxT("wxDC(cg)::DoDrawRotatedText - no valid font set") );
if ( str.Length() == 0 )
return ;
-
if ( m_logicalFunction != wxCOPY )
return ;
- wxCHECK_RET( m_macATSUIStyle != NULL , wxT("No valid font set") ) ;
-
OSStatus status = noErr ;
ATSUTextLayout atsuLayout ;
UniCharCount chars = str.Length() ;
UniChar* ubuf = NULL ;
+
#if SIZEOF_WCHAR_T == 4
- wxMBConvUTF16 converter ;
+ wxMBConvUTF16 converter ;
#if wxUSE_UNICODE
- size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
- ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
- converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ) ;
+ size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
+ ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
+ converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ) ;
#else
const wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
- size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
- ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
- converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
+ size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
+ ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
+ converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
#endif
chars = unicharlen / 2 ;
#else
{
kATSULineRotationTag ,
} ;
- ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
{
sizeof( Fixed ) ,
} ;
- ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
{
&atsuAngle ,
} ;
- status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag),
+ status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag),
atsuTags, atsuSizes, atsuValues ) ;
}
+
{
CGContextRef cgContext = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
ATSUAttributeTag atsuTags[] =
{
kATSUCGContextTag ,
} ;
- ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
{
sizeof( CGContextRef ) ,
} ;
- ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
{
&cgContext ,
} ;
- status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags)/sizeof(ATSUAttributeTag),
+ status = ::ATSUSetLayoutControls(atsuLayout , sizeof(atsuTags) / sizeof(ATSUAttributeTag),
atsuTags, atsuSizes, atsuValues ) ;
}
- ATSUTextMeasurement textBefore ;
- ATSUTextMeasurement textAfter ;
- ATSUTextMeasurement ascent ;
- ATSUTextMeasurement descent ;
+ ATSUTextMeasurement textBefore, textAfter ;
+ ATSUTextMeasurement ascent, descent ;
status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
&textBefore , &textAfter, &ascent , &descent );
+
wxASSERT_MSG( status == noErr , wxT("couldn't measure the rotated text") );
Rect rect ;
-
+
if ( m_backgroundMode == wxSOLID )
{
wxGraphicPath* path = m_graphicContext->CreatePath() ;
drawX ,
drawY ) ;
path->AddLineToPoint(
- (int) (drawX + sin(angle/RAD2DEG) * FixedToInt(ascent + descent)) ,
- (int) (drawY + cos(angle/RAD2DEG) * FixedToInt(ascent + descent)) ) ;
+ (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent)) ,
+ (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent)) ) ;
path->AddLineToPoint(
- (int) (drawX + sin(angle/RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle/RAD2DEG) * FixedToInt(textAfter)) ,
- (int) (drawY + cos(angle/RAD2DEG) * FixedToInt(ascent + descent) - sin(angle/RAD2DEG) * FixedToInt(textAfter)) ) ;
+ (int) (drawX + sin(angle / RAD2DEG) * FixedToInt(ascent + descent ) + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ,
+ (int) (drawY + cos(angle / RAD2DEG) * FixedToInt(ascent + descent) - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ) ;
path->AddLineToPoint(
- (int) (drawX + cos(angle/RAD2DEG) * FixedToInt(textAfter)) ,
- (int) (drawY - sin(angle/RAD2DEG) * FixedToInt(textAfter)) ) ;
+ (int) (drawX + cos(angle / RAD2DEG) * FixedToInt(textAfter)) ,
+ (int) (drawY - sin(angle / RAD2DEG) * FixedToInt(textAfter)) ) ;
m_graphicContext->FillPath( path , m_textBackgroundColour ) ;
delete path ;
}
- drawX += (int)(sin(angle/RAD2DEG) * FixedToInt(ascent));
- drawY += (int)(cos(angle/RAD2DEG) * FixedToInt(ascent));
+ drawX += (int)(sin(angle / RAD2DEG) * FixedToInt(ascent));
+ drawY += (int)(cos(angle / RAD2DEG) * FixedToInt(ascent));
status = ::ATSUMeasureTextImage( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
IntToFixed(drawX) , IntToFixed(drawY) , &rect );
CGContextScaleCTM(((wxMacCGContext*)(m_graphicContext))->GetNativeContext(), 1, -1);
status = ::ATSUDrawText( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
IntToFixed(0) , IntToFixed(0) );
+
wxASSERT_MSG( status == noErr , wxT("couldn't draw the rotated text") );
+
CGContextRestoreGState( ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ) ;
CalcBoundingBox(XDEV2LOG(rect.left), YDEV2LOG(rect.top) );
CalcBoundingBox(XDEV2LOG(rect.right), YDEV2LOG(rect.bottom) );
::ATSUDisposeTextLayout(atsuLayout);
+
#if SIZEOF_WCHAR_T == 4
free( ubuf ) ;
#endif
}
-void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y)
+void wxDC::DoDrawText(const wxString& strtext, wxCoord x, wxCoord y)
{
- wxCHECK_RET(Ok(), wxT("wxDC::DoDrawText Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoDrawText - invalid DC") );
+
DoDrawRotatedText( strtext , x , y , 0.0 ) ;
}
-bool wxDC::CanGetTextExtent() const
+bool wxDC::CanGetTextExtent() const
{
- wxCHECK_MSG(Ok(), false, wxT("Invalid DC"));
+ wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::CanGetTextExtent - invalid DC") );
+
return true ;
}
-void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height,
+void wxDC::DoGetTextExtent( const wxString &str, wxCoord *width, wxCoord *height,
wxCoord *descent, wxCoord *externalLeading ,
wxFont *theFont ) const
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::DoGetTextExtent - invalid DC") );
+
wxFont formerFont = m_font ;
if ( theFont )
{
- // work around the constness
+ // work around the const-ness
*((wxFont*)(&m_font)) = *theFont ;
MacInstallFont() ;
}
if ( str.Length() == 0 )
return ;
- wxCHECK_RET( m_macATSUIStyle != NULL , wxT("No valid font set") ) ;
+ wxCHECK_RET( m_macATSUIStyle != NULL, wxT("wxDC(cg)::DoGetTextExtent - no valid font set") ) ;
OSStatus status = noErr ;
ATSUTextLayout atsuLayout ;
UniCharCount chars = str.Length() ;
UniChar* ubuf = NULL ;
+
#if SIZEOF_WCHAR_T == 4
- wxMBConvUTF16 converter ;
+ wxMBConvUTF16 converter ;
#if wxUSE_UNICODE
- size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
- ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
- converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ) ;
+ size_t unicharlen = converter.WC2MB( NULL , str.wc_str() , 0 ) ;
+ ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
+ converter.WC2MB( (char*) ubuf , str.wc_str(), unicharlen + 2 ) ;
#else
const wxWCharBuffer wchar = str.wc_str( wxConvLocal ) ;
- size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
- ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
- converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
+ size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
+ ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
+ converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
#endif
chars = unicharlen / 2 ;
#else
#endif
#endif
-
status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
&chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
wxASSERT_MSG( status == noErr , wxT("couldn't create the layout of the text") );
- ATSUTextMeasurement textBefore ;
- ATSUTextMeasurement textAfter ;
- ATSUTextMeasurement textAscent ;
- ATSUTextMeasurement textDescent ;
+ ATSUTextMeasurement textBefore, textAfter ;
+ ATSUTextMeasurement textAscent, textDescent ;
status = ::ATSUGetUnjustifiedBounds( atsuLayout, kATSUFromTextBeginning, kATSUToTextEnd,
&textBefore , &textAfter, &textAscent , &textDescent );
*width = XDEV2LOGREL( FixedToInt(textAfter - textBefore) ) ;
::ATSUDisposeTextLayout(atsuLayout);
+
#if SIZEOF_WCHAR_T == 4
free( ubuf ) ;
#endif
+
if ( theFont )
{
// work around the constness
}
}
-
bool wxDC::DoGetPartialTextExtents(const wxString& text, wxArrayInt& widths) const
{
- wxCHECK_MSG(Ok(), false, wxT("Invalid DC"));
+ wxCHECK_MSG( Ok(), false, wxT("wxDC(cg)::DoGetPartialTextExtents - invalid DC") );
widths.Empty();
widths.Add(0, text.Length());
if (text.Length() == 0)
return false;
-
+
ATSUTextLayout atsuLayout ;
UniCharCount chars = text.Length() ;
UniChar* ubuf = NULL ;
+
#if SIZEOF_WCHAR_T == 4
wxMBConvUTF16 converter ;
#if wxUSE_UNICODE
converter.WC2MB( (char*) ubuf , text.wc_str(), unicharlen + 2 ) ;
#else
const wxWCharBuffer wchar = text.wc_str( wxConvLocal ) ;
- size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
+ size_t unicharlen = converter.WC2MB( NULL , wchar.data() , 0 ) ;
ubuf = (UniChar*) malloc( unicharlen + 2 ) ;
converter.WC2MB( (char*) ubuf , wchar.data() , unicharlen + 2 ) ;
#endif
#endif
#endif
- OSStatus status;
+ OSStatus status;
status = ::ATSUCreateTextLayoutWithTextPtr( (UniCharArrayPtr) ubuf , 0 , chars , chars , 1 ,
&chars , (ATSUStyle*) &m_macATSUIStyle , &atsuLayout ) ;
- for ( int pos = 0; pos < (int)chars; pos ++ ) {
- unsigned long actualNumberOfBounds = 0;
- ATSTrapezoid glyphBounds;
-
- // We get a single bound, since the text should only require one. If it requires more, there is an issue
- OSStatus result;
- result = ATSUGetGlyphBounds( atsuLayout, 0, 0, kATSUFromTextBeginning, pos + 1, kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds );
- if (result != noErr || actualNumberOfBounds != 1 )
- {
- return false;
- }
-
- widths[pos] = XDEV2LOGREL(FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ));
- //unsigned char uch = s[i];
-
- }
+ for ( int pos = 0; pos < (int)chars; pos ++ )
+ {
+ unsigned long actualNumberOfBounds = 0;
+ ATSTrapezoid glyphBounds;
+
+ // We get a single bound, since the text should only require one. If it requires more, there is an issue
+ OSStatus result;
+ result = ATSUGetGlyphBounds( atsuLayout, 0, 0, kATSUFromTextBeginning, pos + 1,
+ kATSUseDeviceOrigins, 1, &glyphBounds, &actualNumberOfBounds );
+ if (result != noErr || actualNumberOfBounds != 1 )
+ return false;
+
+ widths[pos] = XDEV2LOGREL(FixedToInt( glyphBounds.upperRight.x - glyphBounds.upperLeft.x ));
+ //unsigned char uch = s[i];
+ }
+
::ATSUDisposeTextLayout(atsuLayout);
return true;
}
-wxCoord wxDC::GetCharWidth(void) const
+wxCoord wxDC::GetCharWidth(void) const
{
wxCoord width ;
- DoGetTextExtent(wxT("g") , &width , NULL , NULL , NULL , NULL ) ;
+ DoGetTextExtent( wxT("g") , &width , NULL , NULL , NULL , NULL ) ;
+
return width ;
}
-wxCoord wxDC::GetCharHeight(void) const
+wxCoord wxDC::GetCharHeight(void) const
{
wxCoord height ;
- DoGetTextExtent(wxT("g") , NULL , &height , NULL , NULL , NULL ) ;
+ DoGetTextExtent( wxT("g") , NULL , &height , NULL , NULL , NULL ) ;
+
return height ;
}
-void wxDC::Clear(void)
+void wxDC::Clear(void)
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::Clear - invalid DC") );
- if ( m_backgroundBrush.Ok() && m_backgroundBrush.GetStyle() != wxTRANSPARENT)
- {
+ if (m_backgroundBrush.Ok() && m_backgroundBrush.GetStyle() != wxTRANSPARENT)
+ {
HIRect rect = CGRectMake( -10000 , -10000 , 20000 , 20000 ) ;
CGContextRef cg = ((wxMacCGContext*)(m_graphicContext))->GetNativeContext() ;
- switch( m_backgroundBrush.MacGetBrushKind() )
+ switch ( m_backgroundBrush.MacGetBrushKind() )
{
case kwxMacBrushTheme :
{
else
#endif
{
- RGBColor color;
+ RGBColor color;
GetThemeBrushAsColor( m_backgroundBrush.MacGetTheme(), 32, true, &color );
CGContextSetRGBFillColor( cg, (float) color.red / 65536,
- (float) color.green / 65536, (float) color.blue / 65536, 1 );
- CGContextFillRect( cg, rect );
+ (float) color.green / 65536, (float) color.blue / 65536, 1 );
+ CGContextFillRect( cg, rect );
}
// reset to normal value
RGBColor col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
CGContextSetRGBFillColor( cg, col.red / 65536.0, col.green / 65536.0, col.blue / 65536.0, 1.0 );
}
- break ;
+ break ;
+
case kwxMacBrushThemeBackground :
{
wxFAIL_MSG( wxT("There shouldn't be theme backgrounds under Quartz") ) ;
+
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_3
if ( UMAGetSystemVersion() >= 0x1030 )
{
HIThemeBackgroundDrawInfo drawInfo ;
drawInfo.version = 0 ;
drawInfo.state = kThemeStateActive ;
- drawInfo.kind = m_backgroundBrush.MacGetThemeBackground(NULL) ;
+ drawInfo.kind = m_backgroundBrush.MacGetThemeBackground( NULL ) ;
if ( drawInfo.kind == kThemeBackgroundMetal )
- HIThemeDrawBackground( &rect , &drawInfo, cg ,
- kHIThemeOrientationNormal) ;
- HIThemeApplyBackground( &rect , &drawInfo, cg ,
- kHIThemeOrientationNormal) ;
+ {
+ HIThemeDrawBackground( &rect, &drawInfo, cg, kHIThemeOrientationNormal ) ;
+ HIThemeApplyBackground( &rect, &drawInfo, cg, kHIThemeOrientationNormal ) ;
+ }
}
- else
#endif
- {
- }
}
- break ;
+ break ;
+
case kwxMacBrushColour :
- {
- RGBColor col = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) ;
- CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
- CGContextFillRect(cg, rect);
+ {
+ // FIXME: doesn't correctly render stippled brushes !!
+ // FIXME: should this be replaced by ::SetBrush() ??
- // reset to normal value
- col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
- CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
- }
- break ;
+ RGBColor col = MAC_WXCOLORREF( m_backgroundBrush.GetColour().GetPixel()) ;
+ CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+ CGContextFillRect(cg, rect);
+
+ // reset to normal value
+ col = MAC_WXCOLORREF( GetBrush().GetColour().GetPixel() ) ;
+ CGContextSetRGBFillColor( cg , col.red / 65536.0 , col.green / 65536.0 , col.blue / 65536.0 , 1.0 ) ;
+ }
+ break ;
+
+ default :
+ wxFAIL_MSG( wxT("unknown brush kind") ) ;
+ break ;
}
}
}
void wxDC::MacInstallFont() const
{
- wxCHECK_RET(Ok(), wxT("Invalid DC"));
+ wxCHECK_RET( Ok(), wxT("wxDC(cg)::MacInstallFont - invalid DC") );
- if( m_macATSUIStyle )
+ if ( m_macATSUIStyle )
{
::ATSUDisposeStyle((ATSUStyle)m_macATSUIStyle);
m_macATSUIStyle = NULL ;
if ( m_font.Ok() )
{
- OSStatus status = noErr ;
+ OSStatus status ;
+
status = ATSUCreateAndCopyStyle( (ATSUStyle) m_font.MacGetATSUStyle() , (ATSUStyle*) &m_macATSUIStyle ) ;
- wxASSERT_MSG( status == noErr , wxT("couldn't set create ATSU style") ) ;
+
+ wxASSERT_MSG( status == noErr, wxT("couldn't create ATSU style") ) ;
Fixed atsuSize = IntToFixed( int(m_scaleY * m_font.MacGetFontSize()) ) ;
RGBColor atsuColor = MAC_WXCOLORREF( m_textForegroundColour.GetPixel() ) ;
kATSUSizeTag ,
kATSUColorTag ,
} ;
- ByteCount atsuSizes[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ ByteCount atsuSizes[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
{
sizeof( Fixed ) ,
sizeof( RGBColor ) ,
} ;
- // Boolean kTrue = true ;
- // Boolean kFalse = false ;
-
- // ATSUVerticalCharacterType kHorizontal = kATSUStronglyHorizontal;
- ATSUAttributeValuePtr atsuValues[sizeof(atsuTags)/sizeof(ATSUAttributeTag)] =
+ ATSUAttributeValuePtr atsuValues[sizeof(atsuTags) / sizeof(ATSUAttributeTag)] =
{
&atsuSize ,
&atsuColor ,
} ;
- status = ::ATSUSetAttributes((ATSUStyle)m_macATSUIStyle, sizeof(atsuTags)/sizeof(ATSUAttributeTag) ,
+
+ status = ::ATSUSetAttributes(
+ (ATSUStyle)m_macATSUIStyle, sizeof(atsuTags) / sizeof(ATSUAttributeTag) ,
atsuTags, atsuSizes, atsuValues);
- wxASSERT_MSG( status == noErr , wxT("couldn't Modify ATSU style") ) ;
+ wxASSERT_MSG( status == noErr , wxT("couldn't modify ATSU style") ) ;
}
}
+#pragma mark -
+
// ---------------------------------------------------------------------------
// coordinates transformations
// ---------------------------------------------------------------------------