tdf#153341: try to parse alpha value when copying HTML text
Change-Id: Ic7240358be19e73f3c3f021e0de9414e3e988aa6
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/146546
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/sw/source/filter/html/parcss1.cxx b/sw/source/filter/html/parcss1.cxx
index 6da42b8..f3145f1 100644
--- a/sw/source/filter/html/parcss1.cxx
+++ b/sw/source/filter/html/parcss1.cxx
@@ -633,7 +633,8 @@ CSS1Token CSS1Parser::GetNextToken()
( (('u'==m_aToken[0] || 'U'==m_aToken[0]) &&
m_aToken.equalsIgnoreAsciiCase( "url" )) ||
(('r'==m_aToken[0] || 'R'==m_aToken[0]) &&
m_aToken.equalsIgnoreAsciiCase( "rgb" )) ) )
(m_aToken.equalsIgnoreAsciiCase( "rgb" ) || m_aToken.equalsIgnoreAsciiCase( "rgba" ) )
) ) )
{
int nNestCnt = 0;
OUStringBuffer sTmpBuffer2(64);
@@ -1268,18 +1269,24 @@ bool CSS1Expression::GetColor( Color &rColor ) const
{
case CSS1_RGB:
{
sal_uInt8 aColors[3] = { 0, 0, 0 };
// fourth value to 255 means no alpha transparency
// so the right by default value
sal_uInt8 aColors[4] = { 0, 0, 0, 255 };
// it can be "rgb" or "rgba"
if (!aValue.startsWithIgnoreAsciiCase( "rgb" ) || aValue.getLength() < 6 ||
aValue[3] != '(' || aValue[aValue.getLength()-1] != ')')
(aValue[3] != '(' && aValue[4] != '(' ) || aValue[aValue.getLength()-1] != ')')
{
break;
}
sal_Int32 nPos = 4; // start after "rgb("
for ( int nCol = 0; nCol < 3 && nPos > 0; ++nCol )
sal_Int32 nPos = aValue.startsWithIgnoreAsciiCase( "rgba" )?5:4; // start after "rgba(" or "rgb("
char cSep = (aValue.indexOf(',') != -1)?',':' ';
// alpha value can be after a "/" or ","
bool bIsSepAlphaDiv = (aValue.indexOf('/') != -1)?true:false;
for ( int nCol = 0; nCol < 4 && nPos > 0; ++nCol )
{
const std::u16string_view aNumber = o3tl::getToken(aValue, 0, ',', nPos);
const std::u16string_view aNumber = o3tl::getToken(aValue, 0, cSep, nPos);
sal_Int32 nNumber = o3tl::toInt32(aNumber);
if( nNumber<0 )
@@ -1295,13 +1302,25 @@ bool CSS1Expression::GetColor( Color &rColor ) const
}
else if( nNumber > 255 )
nNumber = 255;
else if( aNumber.find('.') != std::u16string_view::npos )
{
// in this case aNumber contains something like "0.3" so not an sal_Int32
nNumber = static_cast<sal_Int32>(255.0*o3tl::toDouble(aNumber));
}
aColors[nCol] = static_cast<sal_uInt8>(nNumber);
// rgb with alpha and '/' has this form: rgb(255 0 0 / 50%)
if (bIsSepAlphaDiv && nCol == 2)
{
// but there can be some spaces or not before and after the "/", so skip them
while (aValue[nPos] == '/' || aValue[nPos] == ' ')
++nPos;
}
}
rColor.SetRed( aColors[0] );
rColor.SetGreen( aColors[1] );
rColor.SetBlue( aColors[2] );
rColor.SetAlpha( aColors[3] );
bRet = true; // something different than a colour isn't possible
}