From fb27932e4cf1253c2ba46a4fb5acdc478a10b9d7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Va=CC=81clav=20Slavi=CC=81k?= Date: Sun, 20 Nov 2016 12:12:38 +0100 Subject: [PATCH] Support #rrggbbaa, #rgb and #rgba colors syntax Add support for alpha channel in the #rrggbbaa format to wxColour::GetAsString() and FromString(). This syntax is introduced in CSS4 spec draft (see https://drafts.csswg.org/css-color/#hex-notation) and already used by Pango for markup as well. Also recognize #rgb and #rgba shorter variants in FromString(). --- src/common/colourcmn.cpp | 52 ++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 12 deletions(-) diff --git a/src/common/colourcmn.cpp b/src/common/colourcmn.cpp index a27e3b56cb..805eb0202d 100644 --- a/src/common/colourcmn.cpp +++ b/src/common/colourcmn.cpp @@ -158,16 +158,42 @@ bool wxColourBase::FromString(const wxString& str) (unsigned char)wxClip(blue, 0, 255), (unsigned char)wxClip(alpha, 0, 255)); } - else if ( str[0] == wxT('#') && wxStrlen(str) == 7 ) + else if ( str[0] == wxT('#') ) { - // hexadecimal prefixed with # (HTML syntax) + // hexadecimal prefixed with # ("HTML syntax") + // see https://drafts.csswg.org/css-color/#hex-notation + size_t len = wxStrlen(str) - 1; unsigned long tmp; if (wxSscanf(str.wx_str() + 1, wxT("%lx"), &tmp) != 1) return false; - Set((unsigned char)(tmp >> 16), - (unsigned char)(tmp >> 8), - (unsigned char)tmp); + switch ( len ) + { + case 6: // #rrggbb + tmp = (tmp << 8) + wxALPHA_OPAQUE; + wxFALLTHROUGH; + + case 8: // #rrggbbaa + Set((unsigned char)((tmp >> 24) & 0xFF), + (unsigned char)((tmp >> 16) & 0xFF), + (unsigned char)((tmp >> 8) & 0xFF), + (unsigned char)( tmp & 0xFF)); + break; + + case 3: // #rgb + tmp = (tmp << 4) + 0xF; + wxFALLTHROUGH; + + case 4: // #rgba + Set((unsigned char)(((tmp >> 12) & 0xF) * 0x11), + (unsigned char)(((tmp >> 8) & 0xF) * 0x11), + (unsigned char)(((tmp >> 4) & 0xF) * 0x11), + (unsigned char)(( tmp & 0xF) * 0x11)); + break; + + default: + return false; // unrecognized + } } else if (wxTheColourDatabase) // a colour name ? { @@ -195,7 +221,8 @@ wxString wxColourBase::GetAsString(long flags) const { wxString colName; - const bool isOpaque = Alpha() == wxALPHA_OPAQUE; + const int alpha = Alpha(); + const bool isOpaque = alpha == wxALPHA_OPAQUE; // we can't use the name format if the colour is not opaque as the alpha // information would be lost @@ -208,8 +235,8 @@ wxString wxColourBase::GetAsString(long flags) const if ( colName.empty() ) { const int red = Red(), - blue = Blue(), - green = Green(); + green = Green(), + blue = Blue(); if ( flags & wxC2S_CSS_SYNTAX ) { @@ -222,15 +249,16 @@ wxString wxColourBase::GetAsString(long flags) const { colName.Printf(wxT("rgba(%d, %d, %d, %s)"), red, green, blue, - wxString::FromCDouble(Alpha() / 255., 3)); + wxString::FromCDouble(alpha / 255., 3)); } } else if ( flags & wxC2S_HTML_SYNTAX ) { - wxASSERT_MSG( isOpaque, "alpha is lost in HTML syntax" ); - // no name for this colour; return it in HTML syntax - colName.Printf(wxT("#%02X%02X%02X"), red, green, blue); + if ( isOpaque ) + colName.Printf(wxT("#%02X%02X%02X"), red, green, blue); + else + colName.Printf(wxT("#%02X%02X%02X%02X"), red, green, blue, alpha); } }