finished implementation for stencil and colored patterns

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@36092 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Stefan Csomor 2005-11-05 16:53:42 +00:00
parent bf00c875fe
commit 24cd6f8250

View File

@ -304,208 +304,189 @@ void wxMacCGContext::SetNativeContext( CGContextRef cg )
#pragma mark -
// Experimental support for dashes and patterned brushes
// uncomment the following lines to enable it
// wrapper class for a CGPattern, always allocate on heap, never call destructor
// #define _NEW_GC_DASHES_
// #define _NEW_GC_SUPPORT_
class wxMacCGPattern
{
public :
wxMacCGPattern()
{
}
// is guaranteed to be called only with a non-Null CGContextRef
virtual void Render( CGContextRef ctxRef ) = 0 ;
#if MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_4
#define kCGColorSpaceGenericRGB CFSTR("kCGColorSpaceGenericRGB")
operator CGPatternRef() const { return m_patternRef ; }
protected :
virtual ~wxMacCGPattern()
{
// as this is called only when our m_patternRef is been released, don't release
// it again
}
static void _Render( void *info, CGContextRef ctxRef )
{
wxMacCGPattern* self = (wxMacCGPattern*) info ;
if ( self && ctxRef )
self->Render( ctxRef ) ;
}
static void _Dispose( void *info )
{
wxMacCGPattern* self = (wxMacCGPattern*) info ;
delete self ;
}
CGPatternRef m_patternRef ;
static const CGPatternCallbacks ms_Callbacks ;
} ;
const CGPatternCallbacks wxMacCGPattern::ms_Callbacks = { 0, &wxMacCGPattern::_Render, &wxMacCGPattern::_Dispose };
class ImagePattern : public wxMacCGPattern
{
public :
ImagePattern( const wxBitmap* bmp , CGAffineTransform transform )
{
wxASSERT( bmp && bmp->Ok() ) ;
Init( (CGImageRef) bmp->CGImageCreate() , transform ) ;
}
// ImagePattern takes ownership of CGImageRef passed in
ImagePattern( CGImageRef image , CGAffineTransform transform )
{
if ( image )
{
CFRetain( image ) ;
}
Init( image , transform ) ;
}
virtual void Render( CGContextRef ctxRef )
{
if (m_image != NULL)
HIViewDrawCGImage( ctxRef, &m_imageBounds, m_image );
}
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 ) ;
}
}
~ImagePattern()
{
if ( m_image )
CGImageRelease( m_image ) ;
}
CGImageRef m_image ;
CGRect m_imageBounds ;
} ;
class HatchPattern : public wxMacCGPattern
{
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);
}
}
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 ;
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 ;
case wxFDIAGONAL_HATCH :
{
CGPoint pts[] = {
{ 0.0 , 0.0 } , { 8.0 , 8.0 }
};
StrokeLineSegments( ctxRef , pts , 2 ) ;
}
break ;
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 ;
case wxHORIZONTAL_HATCH :
{
CGPoint pts[] = {
{ 0.0 , 4.0 } , { 8.0 , 4.0 } ,
};
StrokeLineSegments( ctxRef , pts , 2 ) ;
}
break ;
case wxVERTICAL_HATCH :
{
CGPoint pts[] = {
{ 4.0 , 0.0 } , { 4.0 , 8.0 } ,
};
StrokeLineSegments( ctxRef , pts , 2 ) ;
}
break ;
}
}
protected :
~HatchPattern()
{
}
int m_hatch ;
CGRect m_imageBounds ;
} ;
void EstablishPatternColorSpace(
CGContextRef ctxRef,
bool useMultibit,
bool useFill )
{
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 );
}
}
void ImagePatternDispose(
void *info )
{
CGImageRef imageRef = (CGImageRef)info;
if (imageRef != NULL)
CGImageRelease( imageRef );
}
// specifies the struct version value and the callback functions for draw and release
static const CGPatternCallbacks sImagePatternCallback = { 0, &ImagePatternRender, &ImagePatternDispose };
long CreatePatternFromBitmap(
CGPatternRef *patternRef,
const wxBitmap *rasterInfo,
bool useMultibit )
{
CGRect boundsR;
CGImageRef imageRef;
long errorStatus, widthV, heightV, depthV;
if (patternRef == NULL)
return (-1);
*patternRef = NULL;
imageRef = NULL;
errorStatus = 0;
if ((rasterInfo == NULL) || !rasterInfo->Ok())
errorStatus = (-2);
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);
}
if (errorStatus == 0)
{
depthV = rasterInfo->GetDepth();
// isColored = (depthV > 1);
// FIXME: this is often <= 0 - why???
// if (depthV <= 1)
// errorStatus = (-4);
}
if (errorStatus == 0)
{
imageRef = (CGImageRef)(rasterInfo->CGImageCreate());
if (imageRef == NULL)
errorStatus = (-5);
}
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 ) );
*patternRef = CGPatternCreate(
(void*)imageRef,
boundsR,
CGAffineTransformIdentity,
boundsR.size.width,
boundsR.size.height,
kCGPatternTilingNoDistortion,
(int)useMultibit,
&sImagePatternCallback );
if (*patternRef == (CGPatternRef)NULL)
errorStatus = (-6);
}
return errorStatus;
}
long CreatePatternFromDashes(
CGPatternRef *patternRef,
const wxDash *sourceDash,
int count,
bool useMultibit )
{
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;
}
long CreatePatternFromBrush(
CGPatternRef *patternRef,
const wxBrush &sourceBrush,
bool useMultibit )
{
long errorStatus;
if (patternRef == NULL)
return (-1);
*patternRef = NULL;
errorStatus = CreatePatternFromBitmap( patternRef, sourceBrush.GetStipple(), useMultibit );
return errorStatus;
}
long CreatePatternFromPen(
CGPatternRef *patternRef,
const wxPen &sourcePen,
bool useMultibit )
{
long errorStatus;
if (patternRef == NULL)
return (-1);
*patternRef = NULL;
errorStatus = CreatePatternFromBitmap( patternRef, sourcePen.GetStipple(), useMultibit );
return errorStatus;
}
// ------------
#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 ;
@ -529,55 +510,14 @@ void wxMacCGContext::SetPen( const wxPen &pen )
}
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() )
@ -595,7 +535,6 @@ void wxMacCGContext::SetPen( const wxPen &pen )
cap = kCGLineCapButt ;
break ;
}
CGContextSetLineCap( m_cgContext , cap ) ;
CGLineJoin join ;
switch( pen.GetJoin() )
@ -615,91 +554,20 @@ void wxMacCGContext::SetPen( const wxPen &pen )
}
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 };
int 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 :
@ -728,34 +596,56 @@ void wxMacCGContext::SetPen( const wxPen &pen )
userLengths = new float[count] ;
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] = (float)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 ) ;
delete[] userLengths ;
#endif
}
if ( fill && stroke )
{
@ -785,56 +675,35 @@ void wxMacCGContext::SetBrush( const wxBrush &brush )
if ( fill )
{
#if defined(_NEW_GC_SUPPORT_)
// new candidate
if ( brush.GetStyle() == wxSOLID )
{
CGPatternRef patternRef;
float alphaArray[1];
long result;
bool hasSetPattern, useMultibit;
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() )
{
wxMacCFRefHolder<CGColorSpaceRef> patternSpace( CGColorSpaceCreatePattern( wxMacGetGenericRGBColorSpace() ) ) ;
CGContextSetFillColorSpace( m_cgContext , patternSpace ) ;
wxMacCFRefHolder<CGPatternRef> pattern( *( new HatchPattern( brush.GetStyle() , CGContextGetCTM( m_cgContext ) ) ) );
hasSetPattern = false;
useMultibit = true;
result = CreatePatternFromBrush( &patternRef, brush, useMultibit );
if (result == 0)
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 )
@ -888,8 +757,7 @@ wxDC::wxDC()
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;
@ -1166,8 +1034,8 @@ void wxDC::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)
{
@ -1201,7 +1069,21 @@ void wxDC::SetPen( const wxPen &pen )
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);
}
}
}
@ -1212,7 +1094,21 @@ void wxDC::SetBrush( const wxBrush &brush )
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);
}
}
}
@ -1542,7 +1438,7 @@ void wxDC::DoDrawRectangle(wxCoord x, wxCoord y, wxCoord width, wxCoord height)
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 ;
}