]>
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
)
33 // ============================================================================
34 // wxString <-> wxColour conversions
35 // ============================================================================
37 bool wxColourBase::FromString(const wxString
& str
)
40 return false; // invalid or empty string
42 if ( wxStrnicmp(str
, wxT("RGB"), 3) == 0 )
44 // CSS-like RGB specification
45 // according to http://www.w3.org/TR/css3-color/#colorunits
46 // values outside 0-255 range are allowed but should be clipped
48 alpha
= wxALPHA_OPAQUE
;
49 if ( str
.length() > 3 && (str
[3] == wxT('a') || str
[3] == wxT('A')) )
52 // TODO: use locale-independent function
53 if ( wxSscanf(str
.wx_str() + 4, wxT("( %d , %d , %d , %f )"),
54 &red
, &green
, &blue
, &a
) != 4 )
57 alpha
= wxRound(a
* 255);
59 else // no 'a' following "rgb"
61 if ( wxSscanf(str
.wx_str() + 3, wxT("( %d , %d , %d )"),
62 &red
, &green
, &blue
) != 3 )
66 Set((unsigned char)wxClip(red
, 0, 255),
67 (unsigned char)wxClip(green
, 0, 255),
68 (unsigned char)wxClip(blue
, 0, 255),
69 (unsigned char)wxClip(alpha
, 0, 255));
71 else if ( str
[0] == wxT('#') && wxStrlen(str
) == 7 )
73 // hexadecimal prefixed with # (HTML syntax)
75 if (wxSscanf(str
.wx_str() + 1, wxT("%lx"), &tmp
) != 1)
78 Set((unsigned char)(tmp
>> 16),
79 (unsigned char)(tmp
>> 8),
82 else if (wxTheColourDatabase
) // a colour name ?
85 // *this = wxTheColourDatabase->Find(str)
86 // because this place can be called from constructor
87 // and 'this' could not be available yet
88 wxColour clr
= wxTheColourDatabase
->Find(str
);
90 Set((unsigned char)clr
.Red(),
91 (unsigned char)clr
.Green(),
92 (unsigned char)clr
.Blue());
98 wxLogDebug(wxT("wxColour::Set - couldn't set to colour string '%s'"), str
);
102 wxString
wxColourBase::GetAsString(long flags
) const
106 const bool isOpaque
= Alpha() == wxALPHA_OPAQUE
;
108 // we can't use the name format if the colour is not opaque as the alpha
109 // information would be lost
110 if ( (flags
& wxC2S_NAME
) && isOpaque
)
112 colName
= wxTheColourDatabase
->FindName(
113 static_cast<const wxColour
&>(*this)).MakeLower();
116 if ( colName
.empty() )
118 const int red
= Red(),
122 if ( flags
& wxC2S_CSS_SYNTAX
)
124 // no name for this colour; return it in CSS syntax
127 colName
.Printf(wxT("rgb(%d, %d, %d)"), red
, green
, blue
);
129 else // use rgba() form
131 // TODO: use locale-independent function
132 colName
.Printf(wxT("rgba(%d, %d, %d, %.3f)"),
133 red
, green
, blue
, Alpha() / 255.);
136 else if ( flags
& wxC2S_HTML_SYNTAX
)
138 wxASSERT_MSG( isOpaque
, "alpha is lost in HTML syntax" );
140 // no name for this colour; return it in HTML syntax
141 colName
.Printf(wxT("#%02X%02X%02X"), red
, green
, blue
);
145 // this function should alway returns a non-empty string
146 wxASSERT_MSG(!colName
.empty(),
147 wxT("Invalid wxColour -> wxString conversion flags"));
153 void wxColourBase::MakeMono(unsigned char* r
, unsigned char* g
, unsigned char* b
,
156 *r
= *g
= *b
= on
? 255 : 0;
160 void wxColourBase::MakeGrey(unsigned char* r
, unsigned char* g
, unsigned char* b
161 /*, unsigned char brightness */
164 *r
= *g
= *b
= (wxByte
)(((*b
)*117UL + (*g
)*601UL + (*r
)*306UL) >> 10);
168 void wxColourBase::MakeGrey(unsigned char* r
, unsigned char* g
, unsigned char* b
,
169 double weight_r
, double weight_g
, double weight_b
)
171 double luma
= (*r
) * weight_r
+ (*g
) * weight_g
+ (*b
) * weight_b
;
172 *r
= *g
= *b
= (wxByte
)wxRound(luma
);
176 void wxColourBase::MakeDisabled(unsigned char* r
, unsigned char* g
, unsigned char* b
,
177 unsigned char brightness
)
179 //MakeGrey(r, g, b, brightness); // grey no-blend version
180 *r
= AlphaBlend(*r
, brightness
, 0.4);
181 *g
= AlphaBlend(*g
, brightness
, 0.4);
182 *b
= AlphaBlend(*b
, brightness
, 0.4);
185 // AlphaBlend is used by ChangeLightness and MakeDisabled
188 unsigned char wxColourBase::AlphaBlend(unsigned char fg
, unsigned char bg
,
191 double result
= bg
+ (alpha
* (fg
- bg
));
192 result
= wxMax(result
, 0.0);
193 result
= wxMin(result
, 255.0);
194 return (unsigned char)result
;
197 // ChangeLightness() is a utility function that simply darkens
198 // or lightens a color, based on the specified percentage
199 // ialpha of 0 would be completely black, 100 completely white
200 // an ialpha of 100 returns the same colour
203 void wxColourBase::ChangeLightness(unsigned char* r
, unsigned char* g
, unsigned char* b
,
206 if (ialpha
== 100) return;
208 // ialpha is 0..200 where 0 is completely black
209 // and 200 is completely white and 100 is the same
210 // convert that to normal alpha 0.0 - 1.0
211 ialpha
= wxMax(ialpha
, 0);
212 ialpha
= wxMin(ialpha
, 200);
213 double alpha
= ((double)(ialpha
- 100.0))/100.0;
220 alpha
= 1.0 - alpha
; // 0 = transparent fg; 1 = opaque fg
226 alpha
= 1.0 + alpha
; // 0 = transparent fg; 1 = opaque fg
229 *r
= AlphaBlend(*r
, bg
, alpha
);
230 *g
= AlphaBlend(*g
, bg
, alpha
);
231 *b
= AlphaBlend(*b
, bg
, alpha
);
234 wxColour
wxColourBase::ChangeLightness(int ialpha
) const
239 ChangeLightness(&r
, &g
, &b
, ialpha
);
240 return wxColour(r
,g
,b
);
243 #if WXWIN_COMPATIBILITY_2_6
246 wxColour
wxColourBase::CreateByName(const wxString
& name
)
248 return wxColour(name
);
251 void wxColourBase::InitFromName(const wxString
& col
)
256 #endif // WXWIN_COMPATIBILITY_2_6
258 // wxColour <-> wxString utilities, used by wxConfig
259 wxString
wxToString(const wxColourBase
& col
)
261 return col
.IsOk() ? col
.GetAsString(wxC2S_CSS_SYNTAX
)
265 bool wxFromString(const wxString
& str
, wxColourBase
*col
)
267 wxCHECK_MSG( col
, false, wxT("NULL output parameter") );
275 return col
->Set(str
);