diff options
author | Justin Luth <jluth@mail.com> | 2024-02-21 16:37:31 -0500 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-02-26 09:06:28 +0100 |
commit | 64398a41f7d4110b58f0496f1237a6778772b05c (patch) | |
tree | 7dee7ff8be9b2ce77d20eb9983608fc82b2a2adb /sw | |
parent | ffaf75303273c3803cce58f887b5fb8bd570ff18 (diff) |
related tdf#159824 RTF import/export gradient angle
The fillAngle is important for obvious visual reasons,
but also significantly because a negative angle
means that the start/end colors should be swapped
(which is the normal case since
LO's 0 degree angle == -180 VML/RTF angle).
There were no existing unit tests with a "fillAngle" specified,
or with a non-180 angle (0 VML/RTF angle) in LO.
make CppunitTest_sw_rtfexport8 \
CPPUNIT_TEST_NAME=testTdf159824_gradientAngle1
make CppunitTest_sw_rtfexport8 \
CPPUNIT_TEST_NAME=testTdf159824_gradientAngle2
make CppunitTest_sw_rtfexport8 \
CPPUNIT_TEST_NAME=testTdf159824_axialGradient
Change-Id: I4bb2c47bd2a79833d11bedac72ba2152b65b7c73
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163714
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163870
Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoffice@gmail.com>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/qa/extras/rtfexport/data/tdf159824_gradientAngle1.rtf | 17 | ||||
-rw-r--r-- | sw/qa/extras/rtfexport/data/tdf159824_gradientAngle2.rtf | 17 | ||||
-rw-r--r-- | sw/qa/extras/rtfexport/rtfexport8.cxx | 57 | ||||
-rw-r--r-- | sw/source/filter/ww8/rtfattributeoutput.cxx | 9 |
4 files changed, 93 insertions, 7 deletions
diff --git a/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle1.rtf b/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle1.rtf new file mode 100644 index 000000000000..37fd8ae2e339 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle1.rtf @@ -0,0 +1,17 @@ +{\rtf1\ansi\deff3\adeflang1025 + +\landscape\paperh5940\paperw8391 + +{ +\shp{\*\shpinst\shptop382\shpbottom2737\shpleft759\shpright5064 +{\sp{\sn shapeType}{\sv 202}} +{\sp{\sn fillType}{\sv 7}} +{\sp{\sn fillAngle}{\sv 60000}} +{\sp{\sn fillFocus}{\sv 0}} +{\sp{\sn fillColor}{\sv 1758337}} +{\sp{\sn fillBackColor}{\sv 16777215}} + +{\shptxt\par \pard}} +} + +\par } diff --git a/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle2.rtf b/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle2.rtf new file mode 100644 index 000000000000..223864f3281b --- /dev/null +++ b/sw/qa/extras/rtfexport/data/tdf159824_gradientAngle2.rtf @@ -0,0 +1,17 @@ +{\rtf1\ansi\deff3\adeflang1025 + +\landscape\paperh5940\paperw8391 + +{ +\shp{\*\shpinst\shptop382\shpbottom2737\shpleft759\shpright5064 +{\sp{\sn shapeType}{\sv 202}} +{\sp{\sn fillType}{\sv 7}} +{\sp{\sn fillAngle}{\sv -120000}} +{\sp{\sn fillFocus}{\sv 0}} +{\sp{\sn fillColor}{\sv 1758337}} +{\sp{\sn fillBackColor}{\sv 16777215}} + +{\shptxt\par \pard}} +} + +\par } diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx index ab787919dfa9..c0b8cbad9a0a 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -195,8 +195,8 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf159824_axialGradient) getProperty<drawing::FillStyle>(xFrame, "FillStyle")); awt::Gradient2 aGradient = getProperty<awt::Gradient2>(xFrame, "FillGradient"); - //const Color aColA(0x127622); // green - //const Color aColB(0xffffff); // white + const Color aColA(0x127622); // green + const Color aColB(0xffffff); // white // MCGR: Use the completely imported transparency gradient to check for correctness basegfx::BColorStops aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops); @@ -205,11 +205,54 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf159824_axialGradient) CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size()); CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style); CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 0.0)); - //CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[0].getStopColor())); - // CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 0.5)); - // CPPUNIT_ASSERT_EQUAL(aColA, Color(aColorStops[1].getStopColor())); - // CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[2].getStopOffset(), 1.0)); - // CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[2].getStopColor())); + CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[0].getStopColor())); + CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 0.5)); + CPPUNIT_ASSERT_EQUAL(aColA, Color(aColorStops[1].getStopColor())); + CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[2].getStopOffset(), 1.0)); + CPPUNIT_ASSERT_EQUAL(aColB, Color(aColorStops[2].getStopColor())); +} + +DECLARE_RTFEXPORT_TEST(testTdf159824_gradientAngle1, "tdf159824_gradientAngle1.rtf") +{ + // given a frame with a white (top) to lime (bottom) linear gradient at an RTF 1° angle + uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, + getProperty<drawing::FillStyle>(xFrame, "FillStyle")); + awt::Gradient2 aGradient = getProperty<awt::Gradient2>(xFrame, "FillGradient"); + + // MCGR: Use the completely imported transparency gradient to check for correctness + basegfx::BColorStops aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops); + + CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size()); + CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8508442), aGradient.StartColor); + CPPUNIT_ASSERT_EQUAL(sal_Int32(COL_WHITE), aGradient.EndColor); + // RTF 1° angle (in 1/60,000 degree units = 60,000) == LO 181° (in 1/10 degree unites) + CPPUNIT_ASSERT_EQUAL(sal_Int32(181), sal_Int32(aGradient.Angle / 10)); +} + +DECLARE_RTFEXPORT_TEST(testTdf159824_gradientAngle2, "tdf159824_gradientAngle2.rtf") +{ + // given a frame with a lime (top) to white (bottom) linear gradient at an RTF -2° angle. + uno::Reference<text::XTextFramesSupplier> xTextFramesSupplier(mxComponent, uno::UNO_QUERY); + uno::Reference<container::XIndexAccess> xIndexAccess(xTextFramesSupplier->getTextFrames(), + uno::UNO_QUERY); + uno::Reference<beans::XPropertySet> xFrame(xIndexAccess->getByIndex(0), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, + getProperty<drawing::FillStyle>(xFrame, "FillStyle")); + awt::Gradient2 aGradient = getProperty<awt::Gradient2>(xFrame, "FillGradient"); + + // MCGR: Use the completely imported transparency gradient to check for correctness + basegfx::BColorStops aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops); + CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size()); + CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style); + CPPUNIT_ASSERT_EQUAL(sal_Int32(8508442), aGradient.StartColor); + CPPUNIT_ASSERT_EQUAL(sal_Int32(COL_WHITE), aGradient.EndColor); + // RTF -2° angle (in 1/60,000 degree units = -120,000) == LO 358° (in 1/10 degree unites) + CPPUNIT_ASSERT_EQUAL(sal_Int32(358), sal_Int32(aGradient.Angle / 10)); } DECLARE_RTFEXPORT_TEST(testTdf158830, "tdf158830.rtf") diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 05e1cbc2cd22..3b9127fb2c53 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -3741,6 +3741,15 @@ void RtfAttributeOutput::FormatFillGradient(const XFillGradientItem& rFillGradie m_aFlyProperties.push_back(std::make_pair<OString, OString>( "fillColor"_ostr, OString::number(wwUtility::RGBToBGR(aStartColor)))); + // LO's angle is 180° different from VML/RTF. Copied docxattribute angle formula here. + sal_Int32 nReverseAngle = toDegrees(4500_deg10 - rGradient.GetAngle()); + nReverseAngle = (270 - nReverseAngle) % 360; + if (nReverseAngle != 0) + { + m_aFlyProperties.push_back(std::make_pair<OString, OString>( + "fillAngle"_ostr, OString::number(nReverseAngle * 60000))); + } + if (rColorStops.size() < 3) { // two-color version, use back as 2nd color |