Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Make QgsSymbolLayerUtils::parseColor handle hsl(a) color strings
  • Loading branch information
nyalldawson committed Sep 6, 2020
1 parent 958d5dd commit 96c2ddb
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 2 deletions.
Expand Up @@ -645,7 +645,7 @@ codes, rgb and rgba strings.
static QColor parseColorWithAlpha( const QString &colorStr, bool &containsAlpha, bool strictEval = false );
%Docstring
Attempts to parse a string as a color using a variety of common formats, including hex
codes, rgb and rgba strings.
codes, rgb and rgba, hsl and hsla strings.

:param colorStr: string representing the color
:param containsAlpha: if colorStr contains an explicit alpha value then containsAlpha will be set to ``True``
Expand Down
33 changes: 33 additions & 0 deletions src/core/symbology/qgssymbollayerutils.cpp
Expand Up @@ -3623,6 +3623,22 @@ QColor QgsSymbolLayerUtils::parseColorWithAlpha( const QString &colorStr, bool &
}
}

//color in hsl(h,s,l) format, brackets optional
const QRegularExpression hslFormatRx( "^\\s*hsl\\(?\\s*(\\d+)\\s*,\\s*(\\d+)\\s*%\\s*,\\s*(\\d+)\\s*%\\s*\\)?\\s*;?\\s*$" );
QRegularExpressionMatch match = hslFormatRx.match( colorStr );
if ( match.hasMatch() )
{
int h = match.captured( 1 ).toInt();
int s = match.captured( 2 ).toInt();
int l = match.captured( 3 ).toInt();
parsedColor.setHsl( h, s / 100.0 * 255.0, l / 100.0 * 255.0 );
if ( parsedColor.isValid() )
{
containsAlpha = false;
return parsedColor;
}
}

//color in (r%,g%,b%) format, brackets and rgb prefix optional
QRegExp rgbPercentFormatRx( "^\\s*(?:rgb)?\\(?\\s*(100|0*\\d{1,2})\\s*%\\s*,\\s*(100|0*\\d{1,2})\\s*%\\s*,\\s*(100|0*\\d{1,2})\\s*%\\s*\\)?\\s*;?\\s*$" );
if ( rgbPercentFormatRx.indexIn( colorStr ) != -1 )
Expand Down Expand Up @@ -3670,6 +3686,23 @@ QColor QgsSymbolLayerUtils::parseColorWithAlpha( const QString &colorStr, bool &
}
}

//color in hsla(h,s%,l%,a) format, brackets optional
const QRegularExpression hslaPercentFormatRx( "^\\s*hsla\\(?\\s*(\\d+)\\s*,\\s*(\\d+)\\s*%\\s*,\\s*(\\d+)\\s*%\\s*,\\s*([\\d\\.]+)\\s*\\)?\\s*;?\\s*$" );
match = hslaPercentFormatRx.match( colorStr );
if ( match.hasMatch() )
{
int h = match.captured( 1 ).toInt();
int s = match.captured( 2 ).toInt();
int l = match.captured( 3 ).toInt();
int a = std::round( match.captured( 4 ).toDouble() * 255.0 );
parsedColor.setHsl( h, s / 100.0 * 255.0, l / 100.0 * 255.0, a );
if ( parsedColor.isValid() )
{
containsAlpha = true;
return parsedColor;
}
}

//couldn't parse string as color
return QColor();
}
Expand Down
2 changes: 1 addition & 1 deletion src/core/symbology/qgssymbollayerutils.h
Expand Up @@ -592,7 +592,7 @@ class CORE_EXPORT QgsSymbolLayerUtils

/**
* Attempts to parse a string as a color using a variety of common formats, including hex
* codes, rgb and rgba strings.
* codes, rgb and rgba, hsl and hsla strings.
* \param colorStr string representing the color
* \param containsAlpha if colorStr contains an explicit alpha value then containsAlpha will be set to TRUE
* \param strictEval set to TRUE for stricter color parsing rules
Expand Down
8 changes: 8 additions & 0 deletions tests/src/core/testqgssymbol.cpp
Expand Up @@ -251,6 +251,14 @@ void TestQgsSymbol::testParseColor()
colorTests.insert( QStringLiteral( "rgb(256,60,0)" ), qMakePair( QColor(), false ) );
colorTests.insert( QStringLiteral( " rgb( 127, 60 , 0 ) " ), qMakePair( QColor( 127, 60, 0 ), false ) );
colorTests.insert( QStringLiteral( "rgb(127,60,0);" ), qMakePair( QColor( 127, 60, 0 ), false ) );
colorTests.insert( QStringLiteral( "hsl(30,19%,90%)" ), qMakePair( QColor::fromHsl( 30, 48, 229 ), false ) );
colorTests.insert( QStringLiteral( "hsl( 30 , 19 % , 90 % )" ), qMakePair( QColor::fromHsl( 30, 48, 229 ), false ) );
colorTests.insert( QStringLiteral( " hsl( 30, 19%, 90% ) " ), qMakePair( QColor::fromHsl( 30, 48, 229 ), false ) );
colorTests.insert( QStringLiteral( "hsl(30,19%,90%);" ), qMakePair( QColor::fromHsl( 30, 48, 229 ), false ) );
colorTests.insert( QStringLiteral( "hsla(30,19%,90%,0.4)" ), qMakePair( QColor::fromHsl( 30, 48, 229, 102 ), true ) );
colorTests.insert( QStringLiteral( "hsla( 30 , 19 % , 90 % , 0.4 )" ), qMakePair( QColor::fromHsl( 30, 48, 229, 102 ), true ) );
colorTests.insert( QStringLiteral( " hsla( 30, 19%, 90%, 0.4 ) " ), qMakePair( QColor::fromHsl( 30, 48, 229, 102 ), true ) );
colorTests.insert( QStringLiteral( "hsla(30,19%,90%,0.4);" ), qMakePair( QColor::fromHsl( 30, 48, 229, 102 ), true ) );
colorTests.insert( QStringLiteral( "(127,60,0);" ), qMakePair( QColor( 127, 60, 0 ), false ) );
colorTests.insert( QStringLiteral( "(127,60,0)" ), qMakePair( QColor( 127, 60, 0 ), false ) );
colorTests.insert( QStringLiteral( "127,060,000" ), qMakePair( QColor( 127, 60, 0 ), false ) );
Expand Down

0 comments on commit 96c2ddb

Please sign in to comment.