OSX using ref data for colour and NSColor native support (#878)
* First attempt using ref data for colour and spliting implementation for CGColorRef and NSColor * correcting SDK dependency * Implementing feedback suggestions
This commit is contained in:
@@ -65,7 +65,7 @@ DECLARE_VARIANT_OBJECT_EXPORTED(wxColour,WXDLLIMPEXP_CORE)
|
|||||||
not need the wxGDIObject machinery to handle colors, please add it to the
|
not need the wxGDIObject machinery to handle colors, please add it to the
|
||||||
list of ports which do not need it.
|
list of ports which do not need it.
|
||||||
*/
|
*/
|
||||||
#if defined( __WXMAC__ ) || defined( __WXMSW__ ) || defined( __WXQT__ )
|
#if defined( __WXMSW__ ) || defined( __WXQT__ )
|
||||||
#define wxCOLOUR_IS_GDIOBJECT 0
|
#define wxCOLOUR_IS_GDIOBJECT 0
|
||||||
#else
|
#else
|
||||||
#define wxCOLOUR_IS_GDIOBJECT 1
|
#define wxCOLOUR_IS_GDIOBJECT 1
|
||||||
|
@@ -29,60 +29,76 @@ public:
|
|||||||
// default copy ctor and dtor are ok
|
// default copy ctor and dtor are ok
|
||||||
|
|
||||||
// accessors
|
// accessors
|
||||||
virtual bool IsOk() const { return m_cgColour != NULL; }
|
virtual ChannelType Red() const wxOVERRIDE;
|
||||||
|
virtual ChannelType Green() const wxOVERRIDE;
|
||||||
|
virtual ChannelType Blue() const wxOVERRIDE;
|
||||||
|
virtual ChannelType Alpha() const wxOVERRIDE;
|
||||||
|
|
||||||
virtual WXDLLIMPEXP_INLINE_CORE ChannelType Red() const { return m_red; }
|
wxColour& operator=(const wxColour& col);
|
||||||
virtual WXDLLIMPEXP_INLINE_CORE ChannelType Green() const { return m_green; }
|
|
||||||
virtual WXDLLIMPEXP_INLINE_CORE ChannelType Blue() const { return m_blue; }
|
|
||||||
virtual WXDLLIMPEXP_INLINE_CORE ChannelType Alpha() const { return m_alpha; }
|
|
||||||
|
|
||||||
// comparison
|
// comparison
|
||||||
bool operator == (const wxColour& colour) const;
|
bool operator == (const wxColour& colour) const;
|
||||||
|
|
||||||
bool operator != (const wxColour& colour) const { return !(*this == colour); }
|
bool operator != (const wxColour& colour) const { return !(*this == colour); }
|
||||||
|
|
||||||
CGColorRef GetPixel() const { return m_cgColour; }
|
// CoreGraphics CGColor
|
||||||
|
// --------------------
|
||||||
|
|
||||||
CGColorRef GetCGColor() const { return m_cgColour; }
|
// This ctor does take ownership of the color.
|
||||||
CGColorRef CreateCGColor() const { return wxCFRetain( (CGColorRef)m_cgColour ); }
|
wxColour( CGColorRef col );
|
||||||
|
|
||||||
|
// don't take ownership of the returned value
|
||||||
|
CGColorRef GetCGColor() const;
|
||||||
|
|
||||||
|
// do take ownership of the returned value
|
||||||
|
CGColorRef CreateCGColor() const { return wxCFRetain(GetCGColor()); }
|
||||||
|
|
||||||
#if wxOSX_USE_COCOA_OR_CARBON
|
#if wxOSX_USE_COCOA_OR_CARBON
|
||||||
|
// Quickdraw RGBColor
|
||||||
|
// ------------------
|
||||||
|
wxColour(const RGBColor& col);
|
||||||
void GetRGBColor( RGBColor *col ) const;
|
void GetRGBColor( RGBColor *col ) const;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// Mac-specific ctor and assignment operator from the native colour
|
|
||||||
// assumes ownership of CGColorRef
|
|
||||||
wxColour( CGColorRef col );
|
|
||||||
#if wxOSX_USE_COCOA_OR_CARBON
|
|
||||||
wxColour(const RGBColor& col);
|
|
||||||
wxColour& operator=(const RGBColor& col);
|
|
||||||
#endif
|
|
||||||
#if wxOSX_USE_COCOA
|
#if wxOSX_USE_COCOA
|
||||||
|
// NSColor Cocoa
|
||||||
|
// -------------
|
||||||
|
|
||||||
// This ctor does not take ownership of the color.
|
// This ctor does not take ownership of the color.
|
||||||
explicit wxColour(WX_NSColor color);
|
explicit wxColour(WX_NSColor color);
|
||||||
WX_NSColor OSXGetNSColor() const;
|
WX_NSColor OSXGetNSColor() const;
|
||||||
#endif
|
#endif
|
||||||
wxColour& operator=(CGColorRef col);
|
|
||||||
wxColour& operator=(const wxColour& col);
|
|
||||||
|
|
||||||
protected :
|
protected :
|
||||||
virtual void
|
virtual void
|
||||||
InitRGBA(ChannelType r, ChannelType g, ChannelType b, ChannelType a);
|
InitRGBA(ChannelType r, ChannelType g, ChannelType b, ChannelType a) wxOVERRIDE;
|
||||||
#if wxOSX_USE_COCOA_OR_CARBON
|
|
||||||
void InitRGBColor( const RGBColor& col );
|
virtual wxGDIRefData *CreateGDIRefData() const wxOVERRIDE;
|
||||||
#endif
|
virtual wxGDIRefData *CloneGDIRefData(const wxGDIRefData *data) const wxOVERRIDE;
|
||||||
void InitCGColorRef( CGColorRef col );
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
wxCFRef<CGColorRef> m_cgColour;
|
|
||||||
|
|
||||||
ChannelType m_red;
|
|
||||||
ChannelType m_blue;
|
|
||||||
ChannelType m_green;
|
|
||||||
ChannelType m_alpha;
|
|
||||||
|
|
||||||
wxDECLARE_DYNAMIC_CLASS(wxColour);
|
wxDECLARE_DYNAMIC_CLASS(wxColour);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class wxColourRefData : public wxGDIRefData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxColourRefData() {}
|
||||||
|
virtual ~wxColourRefData() {}
|
||||||
|
|
||||||
|
virtual CGFloat Red() const = 0;
|
||||||
|
virtual CGFloat Green() const = 0;
|
||||||
|
virtual CGFloat Blue() const = 0;
|
||||||
|
virtual CGFloat Alpha() const = 0;
|
||||||
|
|
||||||
|
virtual CGColorRef GetCGColor() const = 0;
|
||||||
|
|
||||||
|
virtual wxColourRefData* Clone() const = 0;
|
||||||
|
|
||||||
|
#if wxOSX_USE_COCOA
|
||||||
|
virtual WX_NSColor GetNSColor() const;
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
// _WX_COLOUR_H_
|
// _WX_COLOUR_H_
|
||||||
|
@@ -13,78 +13,136 @@
|
|||||||
|
|
||||||
#include "wx/osx/private.h"
|
#include "wx/osx/private.h"
|
||||||
|
|
||||||
// Helper function to avoid writing too many casts in wxColour ctor.
|
class wxNSColorRefData : public wxColourRefData
|
||||||
static inline wxColour::ChannelType NSColorChannelToWX(CGFloat c)
|
|
||||||
{
|
{
|
||||||
return static_cast<wxColour::ChannelType>(c * 255 + 0.5);
|
public:
|
||||||
|
wxNSColorRefData(WX_NSColor color);
|
||||||
|
|
||||||
|
wxNSColorRefData(const wxNSColorRefData& other);
|
||||||
|
|
||||||
|
virtual ~wxNSColorRefData();
|
||||||
|
|
||||||
|
virtual CGFloat Red() const wxOVERRIDE;
|
||||||
|
virtual CGFloat Green() const wxOVERRIDE;
|
||||||
|
virtual CGFloat Blue() const wxOVERRIDE;
|
||||||
|
virtual CGFloat Alpha() const wxOVERRIDE;
|
||||||
|
|
||||||
|
CGColorRef GetCGColor() const wxOVERRIDE;
|
||||||
|
|
||||||
|
virtual wxColourRefData* Clone() const wxOVERRIDE { return new wxNSColorRefData(*this); }
|
||||||
|
|
||||||
|
virtual WX_NSColor GetNSColor() const wxOVERRIDE;
|
||||||
|
private:
|
||||||
|
WX_NSColor m_nsColour;
|
||||||
|
|
||||||
|
wxDECLARE_NO_ASSIGN_CLASS(wxNSColorRefData);
|
||||||
|
};
|
||||||
|
|
||||||
|
wxNSColorRefData::wxNSColorRefData(WX_NSColor color)
|
||||||
|
{
|
||||||
|
m_nsColour = [color retain];
|
||||||
}
|
}
|
||||||
|
|
||||||
wxColour::wxColour(WX_NSColor col)
|
wxNSColorRefData::wxNSColorRefData(const wxNSColorRefData& other)
|
||||||
|
{
|
||||||
|
m_nsColour = [other.m_nsColour retain];
|
||||||
|
}
|
||||||
|
|
||||||
|
wxNSColorRefData::~wxNSColorRefData()
|
||||||
|
{
|
||||||
|
[m_nsColour release];
|
||||||
|
}
|
||||||
|
|
||||||
|
WX_NSColor wxNSColorRefData::GetNSColor() const
|
||||||
|
{
|
||||||
|
return m_nsColour;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat wxNSColorRefData::Red() const
|
||||||
|
{
|
||||||
|
if ( NSColor* colRGBA = [m_nsColour colorUsingColorSpaceName:NSCalibratedRGBColorSpace] )
|
||||||
|
return [colRGBA redComponent];
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat wxNSColorRefData::Green() const
|
||||||
|
{
|
||||||
|
if ( NSColor* colRGBA = [m_nsColour colorUsingColorSpaceName:NSCalibratedRGBColorSpace] )
|
||||||
|
return [colRGBA greenComponent];
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat wxNSColorRefData::Blue() const
|
||||||
|
{
|
||||||
|
if ( NSColor* colRGBA = [m_nsColour colorUsingColorSpaceName:NSCalibratedRGBColorSpace] )
|
||||||
|
return [colRGBA blueComponent];
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGFloat wxNSColorRefData::Alpha() const
|
||||||
|
{
|
||||||
|
if ( NSColor* colRGBA = [m_nsColour colorUsingColorSpaceName:NSCalibratedRGBColorSpace] )
|
||||||
|
return [colRGBA alphaComponent];
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
CGColorRef wxNSColorRefData::GetCGColor() const
|
||||||
{
|
{
|
||||||
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_8
|
||||||
if ( wxPlatformInfo::Get().CheckOSVersion(10, 8) )
|
if (wxPlatformInfo::Get().CheckOSVersion(10, 8))
|
||||||
{
|
return [m_nsColour CGColor];
|
||||||
CGColorRef cgcolor = [col CGColor];
|
|
||||||
CFRetain(cgcolor);
|
|
||||||
InitCGColorRef(cgcolor);
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
CGColorRef cgcolor = NULL;
|
||||||
// Simplest case is when we can directly get the RGBA components:
|
|
||||||
if ( NSColor* colRGBA = [col colorUsingColorSpaceName:NSCalibratedRGBColorSpace] )
|
|
||||||
{
|
|
||||||
InitRGBA
|
|
||||||
(
|
|
||||||
NSColorChannelToWX([colRGBA redComponent]),
|
|
||||||
NSColorChannelToWX([colRGBA greenComponent]),
|
|
||||||
NSColorChannelToWX([colRGBA blueComponent]),
|
|
||||||
NSColorChannelToWX([colRGBA alphaComponent])
|
|
||||||
);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Simplest case is when we can directly get the RGBA components:
|
||||||
|
if (NSColor* colRGBA = [m_nsColour colorUsingColorSpaceName:NSCalibratedRGBColorSpace])
|
||||||
|
{
|
||||||
|
CGFloat components[4];
|
||||||
|
[colRGBA getRed:&components[0] green:&components[1] blue:&components[2] alpha:&components[3]];
|
||||||
|
|
||||||
|
cgcolor = CGColorCreate(wxMacGetGenericRGBColorSpace(), components);
|
||||||
|
}
|
||||||
// Some colours use patterns, we can handle them with the help of CGColorRef
|
// Some colours use patterns, we can handle them with the help of CGColorRef
|
||||||
if ( NSColor* colPat = [col colorUsingColorSpaceName:NSPatternColorSpace] )
|
else if (NSColor* colPat = [m_nsColour colorUsingColorSpaceName:NSPatternColorSpace])
|
||||||
{
|
{
|
||||||
NSImage* const nsimage = [colPat patternImage];
|
NSImage* const nsimage = [colPat patternImage];
|
||||||
if ( nsimage )
|
if (nsimage)
|
||||||
{
|
{
|
||||||
NSSize size = [nsimage size];
|
NSSize size = [nsimage size];
|
||||||
NSRect r = NSMakeRect(0, 0, size.width, size.height);
|
NSRect r = NSMakeRect(0, 0, size.width, size.height);
|
||||||
CGImageRef cgimage = [nsimage CGImageForProposedRect:&r context:nil hints:nil];
|
CGImageRef cgimage = [nsimage CGImageForProposedRect:&r context:nil hints:nil];
|
||||||
if ( cgimage )
|
if (cgimage)
|
||||||
{
|
{
|
||||||
// Callbacks for CGPatternCreate()
|
// Callbacks for CGPatternCreate()
|
||||||
struct PatternCreateCallbacks
|
struct PatternCreateCallbacks
|
||||||
{
|
{
|
||||||
static void Draw(void *info, CGContextRef ctx)
|
static void Draw(void* info, CGContextRef ctx)
|
||||||
{
|
{
|
||||||
CGImageRef image = (CGImageRef) info;
|
CGImageRef image = (CGImageRef)info;
|
||||||
CGContextDrawImage
|
CGContextDrawImage(
|
||||||
(
|
|
||||||
ctx,
|
ctx,
|
||||||
CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)),
|
CGRectMake(0, 0, CGImageGetWidth(image), CGImageGetHeight(image)),
|
||||||
image
|
image);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void Release(void * WXUNUSED(info))
|
static void Release(void* WXUNUSED(info))
|
||||||
{
|
{
|
||||||
// Do not release the image here, we don't own it as it
|
// Do not release the image here, we don't own it as it
|
||||||
// comes from NSImage.
|
// comes from NSImage.
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const CGPatternCallbacks callbacks =
|
const CGPatternCallbacks callbacks = {
|
||||||
{
|
|
||||||
/* version: */ 0,
|
/* version: */ 0,
|
||||||
&PatternCreateCallbacks::Draw,
|
&PatternCreateCallbacks::Draw,
|
||||||
&PatternCreateCallbacks::Release
|
&PatternCreateCallbacks::Release
|
||||||
};
|
};
|
||||||
|
|
||||||
CGPatternRef pattern = CGPatternCreate
|
CGPatternRef pattern = CGPatternCreate(
|
||||||
(
|
|
||||||
cgimage,
|
cgimage,
|
||||||
CGRectMake(0, 0, size.width, size.height),
|
CGRectMake(0, 0, size.width, size.height),
|
||||||
CGAffineTransformMake(1, 0, 0, 1, 0, 0),
|
CGAffineTransformMake(1, 0, 0, 1, 0, 0),
|
||||||
@@ -96,24 +154,32 @@ wxColour::wxColour(WX_NSColor col)
|
|||||||
);
|
);
|
||||||
CGColorSpaceRef space = CGColorSpaceCreatePattern(NULL);
|
CGColorSpaceRef space = CGColorSpaceCreatePattern(NULL);
|
||||||
CGFloat components[1] = { 1.0 };
|
CGFloat components[1] = { 1.0 };
|
||||||
CGColorRef cgcolor = CGColorCreateWithPattern(space, pattern, components);
|
cgcolor = CGColorCreateWithPattern(space, pattern, components);
|
||||||
CGColorSpaceRelease(space);
|
CGColorSpaceRelease(space);
|
||||||
CGPatternRelease(pattern);
|
CGPatternRelease(pattern);
|
||||||
|
|
||||||
InitCGColorRef(cgcolor);
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Don't assert here, this will more likely than not result in a crash as
|
if (cgcolor == NULL)
|
||||||
// colours are often created in drawing code which will be called again
|
{
|
||||||
// when the assert dialog is shown, resulting in a recursive assertion
|
// Don't assert here, this will more likely than not result in a crash as
|
||||||
// failure and, hence, a crash.
|
// colours are often created in drawing code which will be called again
|
||||||
NSLog(@"Failed to convert NSColor \"%@\" to wxColour.", col);
|
// when the assert dialog is shown, resulting in a recursive assertion
|
||||||
|
// failure and, hence, a crash.
|
||||||
|
NSLog(@"Failed to convert NSColor \"%@\" to CGColorRef.", m_nsColour);
|
||||||
|
}
|
||||||
|
return cgcolor;
|
||||||
}
|
}
|
||||||
|
|
||||||
WX_NSColor wxColour::OSXGetNSColor() const
|
WX_NSColor wxColourRefData::GetNSColor() const
|
||||||
{
|
{
|
||||||
return [NSColor colorWithCalibratedRed:m_red / 255.0 green:m_green / 255.0 blue:m_blue / 255.0 alpha:m_alpha / 255.0];
|
return [NSColor colorWithCalibratedRed:Red() green:Green() blue:Blue() alpha:Alpha() ];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wxColour::wxColour(WX_NSColor col)
|
||||||
|
{
|
||||||
|
m_refData = new wxNSColorRefData(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -18,122 +18,221 @@
|
|||||||
|
|
||||||
#include "wx/osx/private.h"
|
#include "wx/osx/private.h"
|
||||||
|
|
||||||
|
CGColorSpaceRef wxMacGetGenericRGBColorSpace();
|
||||||
|
|
||||||
|
class wxCGColorRefData : public wxColourRefData
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
wxCGColorRefData(CGFloat r, CGFloat g, CGFloat b, CGFloat a = 1.0);
|
||||||
|
|
||||||
|
wxCGColorRefData(CGFloat components[4]);
|
||||||
|
|
||||||
|
wxCGColorRefData(CGColorRef);
|
||||||
|
|
||||||
|
wxCGColorRefData(const wxCGColorRefData& other);
|
||||||
|
|
||||||
|
virtual bool IsOk() const wxOVERRIDE{ return m_cgColour != NULL; }
|
||||||
|
|
||||||
|
virtual CGFloat Red() const wxOVERRIDE { return m_red; }
|
||||||
|
virtual CGFloat Green() const wxOVERRIDE { return m_green; }
|
||||||
|
virtual CGFloat Blue() const wxOVERRIDE { return m_blue; }
|
||||||
|
virtual CGFloat Alpha() const wxOVERRIDE { return m_alpha; }
|
||||||
|
|
||||||
|
CGColorRef GetCGColor() const wxOVERRIDE { return m_cgColour; }
|
||||||
|
|
||||||
|
virtual wxColourRefData* Clone() const wxOVERRIDE { return new wxCGColorRefData(*this); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
void Init(CGFloat components[4]);
|
||||||
|
|
||||||
|
wxCFRef<CGColorRef> m_cgColour;
|
||||||
|
|
||||||
|
CGFloat m_red;
|
||||||
|
CGFloat m_blue;
|
||||||
|
CGFloat m_green;
|
||||||
|
CGFloat m_alpha;
|
||||||
|
|
||||||
|
wxDECLARE_NO_ASSIGN_CLASS(wxCGColorRefData);
|
||||||
|
};
|
||||||
|
|
||||||
|
wxCGColorRefData::wxCGColorRefData(CGFloat r, CGFloat g, CGFloat b, CGFloat a)
|
||||||
|
{
|
||||||
|
CGFloat components[4];
|
||||||
|
components[0] = r;
|
||||||
|
components[1] = b;
|
||||||
|
components[2] = g;
|
||||||
|
components[3] = a;
|
||||||
|
|
||||||
|
Init(components);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCGColorRefData::wxCGColorRefData(CGFloat components[4])
|
||||||
|
{
|
||||||
|
Init(components);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCGColorRefData::wxCGColorRefData(const wxCGColorRefData& other)
|
||||||
|
{
|
||||||
|
m_red = other.m_red;
|
||||||
|
m_blue = other.m_blue;
|
||||||
|
m_green = other.m_green;
|
||||||
|
m_alpha = other.m_alpha;
|
||||||
|
|
||||||
|
m_cgColour = other.m_cgColour;
|
||||||
|
}
|
||||||
|
|
||||||
|
void wxCGColorRefData::Init(CGFloat components[4])
|
||||||
|
{
|
||||||
|
m_red = components[0];
|
||||||
|
m_blue = components[1];
|
||||||
|
m_green = components[2];
|
||||||
|
m_alpha = components[3];
|
||||||
|
|
||||||
|
m_cgColour = CGColorCreate(wxMacGetGenericRGBColorSpace(), components);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxCGColorRefData::wxCGColorRefData(CGColorRef col)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(col != NULL, "Invalid CoreGraphics Color");
|
||||||
|
m_cgColour.reset(col);
|
||||||
|
|
||||||
|
wxCFRef<CGColorRef> rgbacol;
|
||||||
|
size_t noComp = CGColorGetNumberOfComponents(col);
|
||||||
|
const CGFloat* components = CGColorGetComponents(col);
|
||||||
|
|
||||||
|
// set default alpha
|
||||||
|
m_alpha = 1.0;
|
||||||
|
bool isRGB = true;
|
||||||
|
|
||||||
|
CGColorSpaceModel model = CGColorSpaceGetModel(CGColorGetColorSpace(col));
|
||||||
|
if (model == kCGColorSpaceModelMonochrome)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(1 <= noComp && noComp <= 2, "Monochrome Color unexpected components");
|
||||||
|
m_red = components[0];
|
||||||
|
m_green = components[0];
|
||||||
|
m_blue = components[0];
|
||||||
|
if (noComp > 1)
|
||||||
|
m_alpha = components[1];
|
||||||
|
isRGB = false;
|
||||||
|
}
|
||||||
|
else if (model != kCGColorSpaceModelRGB)
|
||||||
|
{
|
||||||
|
#if MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_11
|
||||||
|
if (wxPlatformInfo::Get().CheckOSVersion(10, 11))
|
||||||
|
{
|
||||||
|
rgbacol = CGColorCreateCopyByMatchingToColorSpace(wxMacGetGenericRGBColorSpace(), kCGRenderingIntentDefault, col, NULL);
|
||||||
|
noComp = CGColorGetNumberOfComponents(rgbacol);
|
||||||
|
components = CGColorGetComponents(rgbacol);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
#endif
|
||||||
|
{
|
||||||
|
isRGB = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isRGB)
|
||||||
|
{
|
||||||
|
wxASSERT_MSG(3 <= noComp && noComp <= 4, "RGB Color unexpected components");
|
||||||
|
m_red = components[0];
|
||||||
|
m_green = components[1];
|
||||||
|
m_blue = components[2];
|
||||||
|
|
||||||
|
if (noComp == 4)
|
||||||
|
m_alpha = components[3];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#define M_COLDATA static_cast<wxColourRefData*>(m_refData)
|
||||||
|
|
||||||
#if wxOSX_USE_COCOA_OR_CARBON
|
#if wxOSX_USE_COCOA_OR_CARBON
|
||||||
wxColour::wxColour(const RGBColor& col)
|
wxColour::wxColour(const RGBColor& col)
|
||||||
{
|
{
|
||||||
InitRGBColor(col);
|
CGFloat components[4] = { (CGFloat)(col.red / 65535.0), (CGFloat)(col.green / 65535.0),
|
||||||
|
(CGFloat)(col.blue / 65535.0), (CGFloat)1.0 };
|
||||||
|
m_refData = new wxCGColorRefData(components);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxColour::wxColour(CGColorRef col)
|
wxColour::wxColour(CGColorRef col)
|
||||||
{
|
{
|
||||||
InitCGColorRef(col);
|
wxASSERT_MSG(col != NULL, "Invalid CoreGraphics Color");
|
||||||
|
|
||||||
|
m_refData = new wxCGColorRefData(col);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxColour::ChannelType wxColour::Red() const
|
||||||
|
{
|
||||||
|
return wxRound(M_COLDATA->Red() * 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxColour::ChannelType wxColour::Green() const
|
||||||
|
{
|
||||||
|
return wxRound(M_COLDATA->Red() * 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxColour::ChannelType wxColour::Blue() const
|
||||||
|
{
|
||||||
|
return wxRound(M_COLDATA->Red() * 255.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
wxColour::ChannelType wxColour::Alpha() const
|
||||||
|
{
|
||||||
|
return wxRound(M_COLDATA->Red() * 255.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxOSX_USE_COCOA_OR_CARBON
|
#if wxOSX_USE_COCOA_OR_CARBON
|
||||||
void wxColour::GetRGBColor( RGBColor *col ) const
|
void wxColour::GetRGBColor(RGBColor* col) const
|
||||||
{
|
{
|
||||||
col->red = (m_red << 8) + m_red;
|
col->red = M_COLDATA->Red() * 65535.0;
|
||||||
col->blue = (m_blue << 8) + m_blue;
|
col->blue = M_COLDATA->Blue() * 65535.0;
|
||||||
col->green = (m_green << 8) + m_green;
|
col->green = M_COLDATA->Green() * 65535.0;
|
||||||
}
|
|
||||||
|
|
||||||
wxColour& wxColour::operator=(const RGBColor& col)
|
|
||||||
{
|
|
||||||
InitRGBColor(col);
|
|
||||||
return *this;
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wxColour& wxColour::operator=(CGColorRef col)
|
CGColorRef wxColour::GetCGColor() const
|
||||||
{
|
{
|
||||||
InitCGColorRef(col);
|
return M_COLDATA->GetCGColor();
|
||||||
return *this;
|
}
|
||||||
|
|
||||||
|
#if wxOSX_USE_COCOA
|
||||||
|
WX_NSColor wxColour::OSXGetNSColor() const
|
||||||
|
{
|
||||||
|
return M_COLDATA->GetNSColor();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
void wxColour::InitRGBA(ChannelType r, ChannelType g, ChannelType b, ChannelType a)
|
||||||
|
{
|
||||||
|
CGFloat components[4] = { (CGFloat)(r / 255.0), (CGFloat)(g / 255.0), (CGFloat)(b / 255.0), (CGFloat)(a / 255.0) };
|
||||||
|
m_refData = new wxCGColorRefData(components);
|
||||||
}
|
}
|
||||||
|
|
||||||
wxColour& wxColour::operator=(const wxColour& col)
|
wxColour& wxColour::operator=(const wxColour& col)
|
||||||
{
|
{
|
||||||
m_red = col.m_red;
|
wxObject::operator=(col);
|
||||||
m_green = col.m_green;
|
|
||||||
m_blue = col.m_blue;
|
|
||||||
m_alpha = col.m_alpha;
|
|
||||||
m_cgColour = col.m_cgColour;
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
void wxColour::InitRGBA (ChannelType r, ChannelType g, ChannelType b, ChannelType a)
|
bool wxColour::operator==(const wxColour& other) const
|
||||||
{
|
{
|
||||||
m_red = r;
|
if (m_refData == other.m_refData)
|
||||||
m_green = g;
|
return true;
|
||||||
m_blue = b;
|
|
||||||
m_alpha = a ;
|
if (!m_refData || !other.m_refData)
|
||||||
|
return false;
|
||||||
CGColorRef col = 0 ;
|
|
||||||
CGFloat components[4] = { (CGFloat)(r / 255.0), (CGFloat) (g / 255.0), (CGFloat) (b / 255.0), (CGFloat) (a / 255.0) } ;
|
return CGColorEqualToColor(GetCGColor(), other.GetCGColor());
|
||||||
col = CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ;
|
|
||||||
|
|
||||||
wxASSERT_MSG(col != NULL, "Invalid CoreGraphics Color");
|
|
||||||
m_cgColour.reset( col );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if wxOSX_USE_COCOA_OR_CARBON
|
wxGDIRefData* wxColour::CreateGDIRefData() const
|
||||||
void wxColour::InitRGBColor( const RGBColor& col )
|
|
||||||
{
|
{
|
||||||
m_red = col.red >> 8;
|
// black
|
||||||
m_blue = col.blue >> 8;
|
return new wxCGColorRefData(0.0, 0.0, 0.0);
|
||||||
m_green = col.green >> 8;
|
|
||||||
m_alpha = wxALPHA_OPAQUE;
|
|
||||||
CGColorRef cfcol;
|
|
||||||
CGFloat components[4] = { (CGFloat)(col.red / 65535.0), (CGFloat)(col.green / 65535.0),
|
|
||||||
(CGFloat)(col.blue / 65535.0), (CGFloat) 1.0 } ;
|
|
||||||
cfcol = CGColorCreate( wxMacGetGenericRGBColorSpace() , components ) ;
|
|
||||||
|
|
||||||
wxASSERT_MSG(cfcol != NULL, "Invalid CoreGraphics Color");
|
|
||||||
m_cgColour.reset( cfcol );
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void wxColour::InitCGColorRef( CGColorRef col )
|
|
||||||
{
|
|
||||||
wxASSERT_MSG(col != NULL, "Invalid CoreGraphics Color");
|
|
||||||
m_cgColour.reset( col );
|
|
||||||
size_t noComp = CGColorGetNumberOfComponents( col );
|
|
||||||
|
|
||||||
const CGFloat *components = NULL;
|
|
||||||
if ( noComp >= 1 && noComp <= 4 )
|
|
||||||
{
|
|
||||||
// TODO verify whether we really are on a RGB color space
|
|
||||||
m_alpha = wxALPHA_OPAQUE;
|
|
||||||
components = CGColorGetComponents( col );
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( noComp < 1 || !components )
|
|
||||||
{
|
|
||||||
m_alpha = wxALPHA_OPAQUE;
|
|
||||||
m_red = m_green = m_blue = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if ( noComp >= 3 )
|
|
||||||
{
|
|
||||||
m_red = (int)(components[0]*255+0.5);
|
|
||||||
m_green = (int)(components[1]*255+0.5);
|
|
||||||
m_blue = (int)(components[2]*255+0.5);
|
|
||||||
if ( noComp == 4 )
|
|
||||||
m_alpha = (int)(components[3]*255+0.5);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
m_red = (int)(components[0]*255+0.5);
|
|
||||||
m_green = (int)(components[0]*255+0.5);
|
|
||||||
m_blue = (int)(components[0]*255+0.5);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wxColour::operator == (const wxColour& colour) const
|
wxGDIRefData* wxColour::CloneGDIRefData(const wxGDIRefData* data) const
|
||||||
{
|
{
|
||||||
return ( (IsOk() == colour.IsOk()) && (!IsOk() ||
|
return static_cast<const wxColourRefData*>(data)->Clone();
|
||||||
CGColorEqualToColor( m_cgColour, colour.m_cgColour ) ) );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user