summaryrefslogtreecommitdiff
path: root/filter/source/msfilter/util.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'filter/source/msfilter/util.cxx')
-rw-r--r--filter/source/msfilter/util.cxx70
1 files changed, 69 insertions, 1 deletions
diff --git a/filter/source/msfilter/util.cxx b/filter/source/msfilter/util.cxx
index 9031a7761938..5aa5e681994e 100644
--- a/filter/source/msfilter/util.cxx
+++ b/filter/source/msfilter/util.cxx
@@ -1352,6 +1352,74 @@ bool HasTextBoxContent(sal_uInt32 nShapeType)
}
}
+namespace
+{
+
+// Scheme means pattern of chromatic values.
+// [2,2,1] -> red and green are approximately equal and blue is the dominant color (e.g. blue)
+// [1,1,1] -> all chromatic values are approximately equal (e.g. white, gray, black)
+static void CalculateScheme(const BitmapColor& rBitmapColor, std::vector<int> &vScheme, sal_uInt16 nVariance)
+{
+ vScheme.resize(3,1);
+ if( rBitmapColor.GetRed() > rBitmapColor.GetGreen() + nVariance )
+ ++vScheme[0];
+ if( rBitmapColor.GetRed() > rBitmapColor.GetBlue() + nVariance )
+ ++vScheme[0];
+ if( rBitmapColor.GetGreen() > rBitmapColor.GetRed() + nVariance )
+ ++vScheme[1];
+ if( rBitmapColor.GetGreen() > rBitmapColor.GetBlue() + nVariance )
+ ++vScheme[1];
+ if( rBitmapColor.GetBlue() > rBitmapColor.GetRed() + nVariance )
+ ++vScheme[2];
+ if( rBitmapColor.GetBlue() > rBitmapColor.GetGreen() + nVariance )
+ ++vScheme[2];
+}
+
+static bool HasSimilarScheme(const BitmapColor& rBitmapColor1, const BitmapColor& rBitmapColor2, sal_uInt16 nVariance)
+{
+ std::vector<int> vScheme1, vScheme2;
+ CalculateScheme(rBitmapColor1, vScheme1, nVariance);
+ CalculateScheme(rBitmapColor2, vScheme2, nVariance);
+ for( int i = 0; i < 3; ++i )
+ {
+ if( vScheme1[i] != vScheme2[i] )
+ return false;
+ }
+ return true;
+}
+
+// Find the best match in the color palette using scheme of the input color
+static sal_uInt16 GetBestIndex(const BitmapPalette& rPalette, const BitmapColor& rBitmapColor)
+{
+ sal_uInt16 nReturn = 0;
+ bool bFound = false;
+ sal_uLong nLastErr = 3 * 255 + 1;
+
+ // Prefer those colors which have similar scheme as the input
+ // Allow bigger and bigger variance of the schemes until we find
+ // a color in the palette with similar scheme.
+ for( sal_uInt16 nVariance = 0; nVariance <= 255; ++nVariance )
+ {
+ for( sal_uInt16 i = 0; i < rPalette.GetEntryCount(); ++i )
+ {
+ if( HasSimilarScheme(rBitmapColor, rPalette[i], nVariance) )
+ {
+ sal_uLong nActErr = rBitmapColor.GetColorError( rPalette[i] );
+ if( nActErr < nLastErr )
+ {
+ nLastErr = nActErr;
+ nReturn = i;
+ bFound = true;
+ }
+ }
+ }
+ if( bFound )
+ return nReturn;
+ }
+ return nReturn;
+}
+}
+
sal_uInt8 TransColToIco( const Color& rCol )
{
sal_uInt8 nCol = 0; // ->Auto
@@ -1386,7 +1454,7 @@ sal_uInt8 TransColToIco( const Color& rCol )
for( sal_uInt16 i = 0; i < 16; ++i )
aBmpPal[i] = Color( aColArr[ i ] );
- nCol = static_cast< sal_uInt8 >(aBmpPal.GetBestIndex( rCol ) + 1);
+ nCol = static_cast< sal_uInt8 >(GetBestIndex(aBmpPal, rCol) + 1);
break;
}
return nCol;