]>
git.saurik.com Git - wxWidgets.git/blob - src/common/colourcmn.cpp
1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/common/colourcmn.cpp
3 // Purpose: wxColourBase implementation
4 // Author: Francesco Montorsi
8 // Copyright: (c) Francesco Montorsi
9 // Licence: wxWindows licence
10 /////////////////////////////////////////////////////////////////////////////
13 // For compilers that support precompilation, includes "wx.h".
14 #include "wx/wxprec.h"
20 #include "wx/colour.h"
25 #include "wx/gdicmn.h"
26 #include "wx/wxcrtvararg.h"
30 IMPLEMENT_VARIANT_OBJECT_EXPORTED(wxColour
,WXDLLEXPORT
)
34 // ----------------------------------------------------------------------------
36 // ----------------------------------------------------------------------------
38 #if wxUSE_EXTENDED_RTTI
42 template<> void wxStringReadValue(const wxString
&s
, wxColour
&data
)
46 wxLogError(_("String To Colour : Incorrect colour specification : %s"),
52 template<> void wxStringWriteValue(wxString
&s
, const wxColour
&data
)
54 s
= data
.GetAsString(wxC2S_HTML_SYNTAX
);
57 wxTO_STRING_IMP( wxColour
)
58 wxFROM_STRING_IMP( wxColour
)
60 wxIMPLEMENT_DYNAMIC_CLASS_WITH_COPY_AND_STREAMERS_XTI( wxColour
, wxObject
, \
61 "wx/colour.h", &wxTO_STRING( wxColour
), &wxFROM_STRING( wxColour
))
62 //WX_IMPLEMENT_ANY_VALUE_TYPE(wxAnyValueTypeImpl<wxColour>)
63 wxBEGIN_PROPERTIES_TABLE(wxColour
)
64 wxREADONLY_PROPERTY( Red
, unsigned char, Red
, wxEMPTY_PARAMETER_VALUE
, \
65 0 /*flags*/, wxT("Helpstring"), wxT("group"))
66 wxREADONLY_PROPERTY( Green
, unsigned char, Green
, wxEMPTY_PARAMETER_VALUE
, \
67 0 /*flags*/, wxT("Helpstring"), wxT("group"))
68 wxREADONLY_PROPERTY( Blue
, unsigned char, Blue
, wxEMPTY_PARAMETER_VALUE
, \
69 0 /*flags*/, wxT("Helpstring"), wxT("group"))
70 wxEND_PROPERTIES_TABLE()
72 wxDIRECT_CONSTRUCTOR_3( wxColour
, unsigned char, Red
, \
73 unsigned char, Green
, unsigned char, Blue
)
75 wxEMPTY_HANDLERS_TABLE(wxColour
)
78 #if wxCOLOUR_IS_GDIOBJECT
79 wxIMPLEMENT_DYNAMIC_CLASS(wxColour
, wxGDIObject
)
81 wxIMPLEMENT_DYNAMIC_CLASS(wxColour
, wxObject
)
86 // ============================================================================
87 // wxString <-> wxColour conversions
88 // ============================================================================
90 bool wxColourBase::FromString(const wxString
& str
)
93 return false; // invalid or empty string
95 if ( wxStrnicmp(str
, wxT("RGB"), 3) == 0 )
97 // CSS-like RGB specification
98 // according to http://www.w3.org/TR/css3-color/#colorunits
99 // values outside 0-255 range are allowed but should be clipped
100 int red
, green
, blue
,
101 alpha
= wxALPHA_OPAQUE
;
102 if ( str
.length() > 3 && (str
[3] == wxT('a') || str
[3] == wxT('A')) )
105 // TODO: use locale-independent function
106 if ( wxSscanf(str
.wx_str() + 4, wxT("( %d , %d , %d , %f )"),
107 &red
, &green
, &blue
, &a
) != 4 )
110 alpha
= wxRound(a
* 255);
112 else // no 'a' following "rgb"
114 if ( wxSscanf(str
.wx_str() + 3, wxT("( %d , %d , %d )"),
115 &red
, &green
, &blue
) != 3 )
119 Set((unsigned char)wxClip(red
, 0, 255),
120 (unsigned char)wxClip(green
, 0, 255),
121 (unsigned char)wxClip(blue
, 0, 255),
122 (unsigned char)wxClip(alpha
, 0, 255));
124 else if ( str
[0] == wxT('#') && wxStrlen(str
) == 7 )
126 // hexadecimal prefixed with # (HTML syntax)
128 if (wxSscanf(str
.wx_str() + 1, wxT("%lx"), &tmp
) != 1)
131 Set((unsigned char)(tmp
>> 16),
132 (unsigned char)(tmp
>> 8),
135 else if (wxTheColourDatabase
) // a colour name ?
138 // *this = wxTheColourDatabase->Find(str)
139 // because this place can be called from constructor
140 // and 'this' could not be available yet
141 wxColour clr
= wxTheColourDatabase
->Find(str
);
143 Set((unsigned char)clr
.Red(),
144 (unsigned char)clr
.Green(),
145 (unsigned char)clr
.Blue());
151 wxLogDebug(wxT("wxColour::Set - couldn't set to colour string '%s'"), str
);
155 wxString
wxColourBase::GetAsString(long flags
) const
159 const bool isOpaque
= Alpha() == wxALPHA_OPAQUE
;
161 // we can't use the name format if the colour is not opaque as the alpha
162 // information would be lost
163 if ( (flags
& wxC2S_NAME
) && isOpaque
)
165 colName
= wxTheColourDatabase
->FindName(
166 static_cast<const wxColour
&>(*this)).MakeLower();
169 if ( colName
.empty() )
171 const int red
= Red(),
175 if ( flags
& wxC2S_CSS_SYNTAX
)
177 // no name for this colour; return it in CSS syntax
180 colName
.Printf(wxT("rgb(%d, %d, %d)"), red
, green
, blue
);
182 else // use rgba() form
184 // TODO: use locale-independent function
185 colName
.Printf(wxT("rgba(%d, %d, %d, %.3f)"),
186 red
, green
, blue
, Alpha() / 255.);
189 else if ( flags
& wxC2S_HTML_SYNTAX
)
191 wxASSERT_MSG( isOpaque
, "alpha is lost in HTML syntax" );
193 // no name for this colour; return it in HTML syntax
194 colName
.Printf(wxT("#%02X%02X%02X"), red
, green
, blue
);
198 // this function should alway returns a non-empty string
199 wxASSERT_MSG(!colName
.empty(),
200 wxT("Invalid wxColour -> wxString conversion flags"));
206 void wxColourBase::MakeMono(unsigned char* r
, unsigned char* g
, unsigned char* b
,
209 *r
= *g
= *b
= on
? 255 : 0;
213 void wxColourBase::MakeGrey(unsigned char* r
, unsigned char* g
, unsigned char* b
214 /*, unsigned char brightness */
217 *r
= *g
= *b
= (wxByte
)(((*b
)*117UL + (*g
)*601UL + (*r
)*306UL) >> 10);
221 void wxColourBase::MakeGrey(unsigned char* r
, unsigned char* g
, unsigned char* b
,
222 double weight_r
, double weight_g
, double weight_b
)
224 double luma
= (*r
) * weight_r
+ (*g
) * weight_g
+ (*b
) * weight_b
;
225 *r
= *g
= *b
= (wxByte
)wxRound(luma
);
229 void wxColourBase::MakeDisabled(unsigned char* r
, unsigned char* g
, unsigned char* b
,
230 unsigned char brightness
)
232 //MakeGrey(r, g, b, brightness); // grey no-blend version
233 *r
= AlphaBlend(*r
, brightness
, 0.4);
234 *g
= AlphaBlend(*g
, brightness
, 0.4);
235 *b
= AlphaBlend(*b
, brightness
, 0.4);
238 // AlphaBlend is used by ChangeLightness and MakeDisabled
241 unsigned char wxColourBase::AlphaBlend(unsigned char fg
, unsigned char bg
,
244 double result
= bg
+ (alpha
* (fg
- bg
));
245 result
= wxMax(result
, 0.0);
246 result
= wxMin(result
, 255.0);
247 return (unsigned char)result
;
250 // ChangeLightness() is a utility function that simply darkens
251 // or lightens a color, based on the specified percentage
252 // ialpha of 0 would be completely black, 100 completely white
253 // an ialpha of 100 returns the same colour
256 void wxColourBase::ChangeLightness(unsigned char* r
, unsigned char* g
, unsigned char* b
,
259 if (ialpha
== 100) return;
261 // ialpha is 0..200 where 0 is completely black
262 // and 200 is completely white and 100 is the same
263 // convert that to normal alpha 0.0 - 1.0
264 ialpha
= wxMax(ialpha
, 0);
265 ialpha
= wxMin(ialpha
, 200);
266 double alpha
= ((double)(ialpha
- 100.0))/100.0;
273 alpha
= 1.0 - alpha
; // 0 = transparent fg; 1 = opaque fg
279 alpha
= 1.0 + alpha
; // 0 = transparent fg; 1 = opaque fg
282 *r
= AlphaBlend(*r
, bg
, alpha
);
283 *g
= AlphaBlend(*g
, bg
, alpha
);
284 *b
= AlphaBlend(*b
, bg
, alpha
);
287 wxColour
wxColourBase::ChangeLightness(int ialpha
) const
292 ChangeLightness(&r
, &g
, &b
, ialpha
);
293 return wxColour(r
,g
,b
);
296 #if WXWIN_COMPATIBILITY_2_6
299 wxColour
wxColourBase::CreateByName(const wxString
& name
)
301 return wxColour(name
);
304 void wxColourBase::InitFromName(const wxString
& col
)
309 #endif // WXWIN_COMPATIBILITY_2_6
311 // wxColour <-> wxString utilities, used by wxConfig
312 wxString
wxToString(const wxColourBase
& col
)
314 return col
.IsOk() ? col
.GetAsString(wxC2S_CSS_SYNTAX
)
318 bool wxFromString(const wxString
& str
, wxColourBase
*col
)
320 wxCHECK_MSG( col
, false, wxT("NULL output parameter") );
328 return col
->Set(str
);