summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--filter/CppunitTest_filter_utils.mk46
-rw-r--r--filter/Module_filter.mk1
-rw-r--r--filter/qa/cppunit/utils-test.cxx77
-rw-r--r--filter/source/msfilter/util.cxx70
-rw-r--r--sw/qa/extras/globalfilter/globalfilter.cxx24
5 files changed, 205 insertions, 13 deletions
diff --git a/filter/CppunitTest_filter_utils.mk b/filter/CppunitTest_filter_utils.mk
new file mode 100644
index 000000000000..1d042a980ccb
--- /dev/null
+++ b/filter/CppunitTest_filter_utils.mk
@@ -0,0 +1,46 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call gb_CppunitTest_CppunitTest,filter_utils))
+
+$(eval $(call gb_CppunitTest_use_sdk_api,filter_utils))
+$(eval $(call gb_CppunitTest_use_ure,filter_utils))
+
+$(eval $(call gb_CppunitTest_use_configuration,filter_utils))
+
+$(eval $(call gb_CppunitTest_use_externals,filter_utils, \
+ boost_headers \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,filter_utils, \
+ tl \
+ comphelper \
+ unotest \
+ cppuhelper \
+ cppu \
+ msfilter \
+ sal \
+ $(gb_UWINAPI) \
+))
+
+$(eval $(call gb_CppunitTest_use_components,filter_utils,\
+ configmgr/source/configmgr \
+ filter/source/config/cache/filterconfig1 \
+ framework/util/fwk \
+ framework/util/fwl \
+ i18npool/util/i18npool \
+ ucb/source/core/ucb1 \
+ ucb/source/ucp/file/ucpfile1 \
+))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,filter_utils, \
+ filter/qa/cppunit/utils-test \
+))
+
+# vim: set noet sw=4 ts=4:
diff --git a/filter/Module_filter.mk b/filter/Module_filter.mk
index 33f0f745f1e9..4cb64628d53f 100644
--- a/filter/Module_filter.mk
+++ b/filter/Module_filter.mk
@@ -81,6 +81,7 @@ endif
$(eval $(call gb_Module_add_check_targets,filter,\
CppunitTest_filter_xslt \
CppunitTest_filter_priority \
+ CppunitTest_filter_utils \
))
ifneq ($(DISABLE_CVE_TESTS),TRUE)
diff --git a/filter/qa/cppunit/utils-test.cxx b/filter/qa/cppunit/utils-test.cxx
new file mode 100644
index 000000000000..5e306ef99335
--- /dev/null
+++ b/filter/qa/cppunit/utils-test.cxx
@@ -0,0 +1,77 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <cppunit/TestAssert.h>
+#include <cppunit/TestFixture.h>
+#include <cppunit/extensions/HelperMacros.h>
+#include <cppunit/plugin/TestPlugIn.h>
+
+#include <sal/types.h>
+#include <rtl/ustrbuf.hxx>
+#include <filter/msfilter/util.hxx>
+
+#include <unotest/bootstrapfixturebase.hxx>
+
+namespace {
+
+class UtilsTest
+ : public test::BootstrapFixtureBase
+{
+public:
+ void testTransColToIco();
+
+ CPPUNIT_TEST_SUITE(UtilsTest);
+ CPPUNIT_TEST(testTransColToIco);
+ CPPUNIT_TEST_SUITE_END();
+};
+
+void UtilsTest::testTransColToIco()
+{
+ const sal_uInt32 aStdCol[] = {
+ 0xeeeeee, 0xffff99, 0xff6600, 0xff3333, 0xff00cc, 0xff33ff, 0x9900ff, 0x6666ff, 0x00ccff, 0x66ffff, 0x33ff99, 0x99ff66, 0xccff00,
+ 0xdddddd, 0xffff66, 0xffcc00, 0xff9999, 0xff66cc, 0xff99ff, 0xcc66ff, 0x9999ff, 0x9999ff, 0x99ffff, 0x66ff99, 0x99ff99, 0xccff66,
+ 0xcccccc, 0xffff00, 0xff9900, 0xff6666, 0xff3399, 0xff66ff, 0x9933ff, 0x3333ff, 0x3399ff, 0x00ffff, 0x00ff66, 0x66ff66, 0x99ff33,
+ 0xb2b2b2, 0xcc9900, 0xff3300, 0xff0000, 0xff0066, 0xff00ff, 0x6600ff, 0x0000ff, 0x0066ff, 0x00cccc, 0x00cc33, 0x00cc00, 0x66ff00,
+ 0x999999, 0x996600, 0xcc3300, 0xcc0000, 0xcc0066, 0xcc00cc, 0x6600cc, 0x0000cc, 0x0066cc, 0x009999, 0x009933, 0x009900, 0x66cc00,
+ 0x808080, 0x663300, 0x801900, 0x990000, 0x990066, 0x990099, 0x330099, 0x000099, 0x006699, 0x006666, 0x007826, 0x006600, 0x669900,
+ 0x666666, 0x333300, 0x461900, 0x330000, 0x330033, 0x660066, 0x000033, 0x000066, 0x000080, 0x003333, 0x00331a, 0x003300, 0x193300,
+ 0x333333, 0x666633, 0x661900, 0x663333, 0x660033, 0x663366, 0x330066, 0x333366, 0x003366, 0x336666, 0x006633, 0x336633, 0x336600 };
+
+ const sal_uInt16 aExpected[] = {
+ 8, 7, 6, 6, 5, 5, 5, 2, 3, 3, 10, 4, 7,
+ 16, 7, 7, 6, 5, 5, 5, 2, 2, 3, 4, 4, 7,
+ 16, 7, 7, 6, 12, 5, 12, 2, 10, 3, 4, 4, 14,
+ 16, 14, 6, 6, 6, 5, 2, 2, 2, 3, 4, 4, 4,
+ 15, 14, 6, 6, 12, 5, 12, 2, 10, 10, 11, 11, 14,
+ 15, 1, 13, 13, 12, 12, 9, 9, 10, 10, 11, 11, 14,
+ 15, 14, 13, 13, 12, 12, 9, 9, 9, 10, 10, 11, 11,
+ 1, 14, 13, 13, 1, 12, 1, 9, 1, 10, 1, 11, 1 };
+
+ for( size_t i = 0; i < SAL_N_ELEMENTS(aStdCol); ++i)
+ {
+ const OString sMessage = "Index of unmatched color: " + OString::number(i);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), aExpected[i],
+ static_cast<sal_uInt16>(msfilter::util::TransColToIco( Color(aStdCol[i]) )));
+ }
+
+ // tdf#92471
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), static_cast<sal_uInt16>(msfilter::util::TransColToIco( Color( 0x6666ff ))));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), static_cast<sal_uInt16>(msfilter::util::TransColToIco( Color( 0x6566ff ))));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), static_cast<sal_uInt16>(msfilter::util::TransColToIco( Color( 0x6665ff ))));
+ CPPUNIT_ASSERT_EQUAL(sal_uInt16(2), static_cast<sal_uInt16>(msfilter::util::TransColToIco( Color( 0x6666fe ))));
+
+}
+
+CPPUNIT_TEST_SUITE_REGISTRATION(UtilsTest);
+
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
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;
diff --git a/sw/qa/extras/globalfilter/globalfilter.cxx b/sw/qa/extras/globalfilter/globalfilter.cxx
index b1abdec46fd8..f2a7cf26af91 100644
--- a/sw/qa/extras/globalfilter/globalfilter.cxx
+++ b/sw/qa/extras/globalfilter/globalfilter.cxx
@@ -604,7 +604,7 @@ void Test::testCharBackgroundToHighlighting()
mxComponent = loadFromDesktop(getURLFromSrc("/sw/qa/extras/globalfilter/data/char_background.odt"),
"com.sun.star.text.TextDocument");
- const OString sFailedMessage = OString("Failed on filter: ") + aFilterNames[nFilter];
+ OString sFailedMessage = OString("Failed on filter: ") + aFilterNames[nFilter];
SvtFilterOptions& rOpt = SvtFilterOptions::Get();
@@ -625,7 +625,7 @@ void Test::testCharBackgroundToHighlighting()
// Check highlight color
const uno::Reference< text::XTextRange > xPara = getParagraph(1);
- for( int nRun = 1; nRun <= 20; ++nRun )
+ for( int nRun = 1; nRun <= 19; ++nRun )
{
const uno::Reference<beans::XPropertySet> xRun(getRun(xPara,nRun), uno::UNO_QUERY);
sal_Int32 nHighlightColor = 0;
@@ -642,17 +642,17 @@ void Test::testCharBackgroundToHighlighting()
case 9: nHighlightColor = 0x008000; break; //dark green
case 10: nHighlightColor = 0x800080; break; //dark magenta
case 11: nHighlightColor = 0x000080; break; //dark blue
- case 12: nHighlightColor = 0x000000; break; //black
- case 13: nHighlightColor = 0x808000; break; //dark yellow
- case 14: nHighlightColor = 0x808080; break; //dark gray
- case 15: nHighlightColor = 0x000000; break; //white
- case 16: nHighlightColor = 0xff0000; break; //red
- case 17: nHighlightColor = 0xC0C0C0; break; //light gray
- case 18: nHighlightColor = 0x800000; break; //dark red
- case 19: nHighlightColor = 0x008080; break; //dark cyan
- case 20: nHighlightColor = 0xffffff; break; //white
+ case 12: nHighlightColor = 0x808000; break; //dark yellow
+ case 13: nHighlightColor = 0x808080; break; //dark gray
+ case 14: nHighlightColor = 0x000000; break; //black
+ case 15: nHighlightColor = 0xff0000; break; //red
+ case 16: nHighlightColor = 0xC0C0C0; break; //light gray
+ case 17: nHighlightColor = 0x800000; break; //dark red
+ case 18: nHighlightColor = 0x808080; break; //dark gray
+ case 19: nHighlightColor = 0xffff00; break; //yellow
}
- CPPUNIT_ASSERT_EQUAL_MESSAGE(sFailedMessage.getStr(), nHighlightColor, getProperty<sal_Int32>(xRun,"CharHighlight"));
+ const OString sMessage = sFailedMessage +". Index of run with unmatched color: " + OString::number(nRun);
+ CPPUNIT_ASSERT_EQUAL_MESSAGE(sMessage.getStr(), nHighlightColor, getProperty<sal_Int32>(xRun,"CharHighlight"));
}
}
}