diff options
author | Justin Luth <justin.luth@collabora.com> | 2024-02-14 18:16:29 -0500 |
---|---|---|
committer | Miklos Vajna <vmiklos@collabora.com> | 2024-02-23 10:53:40 +0100 |
commit | 396ece804b3a31e4eddf56de4e557f3755331d8c (patch) | |
tree | 091d094dced81907ebdb7904235396a1560b39af | |
parent | 397d72e582c725d162c7e0b819dc6c0bb62e42b0 (diff) |
related tdf#126533 vml import: fix gradient color swapping
tdf#65295 already fixed one case
by removing the test for degrees > 180
for the linear-equivalent gradients.
Unfortunately the comment wasn't also removed,
so that was confusing: removed comment.
The test for degrees > 180 is not needed
for the axial-equivalent case either: removed.
The reason for that degrees > 180 case is likely due to
negative degrees, which is a documented reason
for swapping the colors: added swap if negative degrees.
All the affected, existing unit tests are improved now:
-tdf81345.docx: famous MS example: improved header gradient
-fdo78300.docx: fontworks: hard to tell without MCGR...
make CppunitTest_sw_ooxmlexport7 \
CPPUNIT_TEST_NAME=testTdf126533_negativeAxialAngle
make CppunitTest_sw_ooxmlexport7 \
CPPUNIT_TEST_NAME=testTdf77219_backgroundShape
Change-Id: I9f4d56375bb2cec28ffbd93df419d586da465b78
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163417
Tested-by: Jenkins
Reviewed-by: Justin Luth <jluth@mail.com>
-rw-r--r-- | oox/source/vml/vmlformatting.cxx | 27 | ||||
-rw-r--r-- | sw/qa/extras/ooxmlexport/data/tdf126533_negativeAxialAngle.docx | bin | 0 -> 12994 bytes | |||
-rw-r--r-- | sw/qa/extras/ooxmlexport/ooxmlexport7.cxx | 45 |
3 files changed, 61 insertions, 11 deletions
diff --git a/oox/source/vml/vmlformatting.cxx b/oox/source/vml/vmlformatting.cxx index 6182950973ee..f4022d0639d6 100644 --- a/oox/source/vml/vmlformatting.cxx +++ b/oox/source/vml/vmlformatting.cxx @@ -777,15 +777,18 @@ void FillModel::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper& sal_Int32 nVmlAngle = getIntervalValue< sal_Int32, sal_Int32 >( moAngle.value_or( 0 ), 0, 360 ); // focus of -50% or 50% is axial gradient + // so approximate anything with a similar focus by using LO's axial gradient, + // (otherwise drop the radial aspect; linear gradient becomes the closest match) if( ((-0.75 <= fFocus) && (fFocus <= -0.25)) || ((0.25 <= fFocus) && (fFocus <= 0.75)) ) { - /* According to spec, focus of 50% is outer-to-inner, + /* According to spec, a focus of positive 50% is outer-to-inner, and -50% is inner-to-outer (color to color2). - BUT: For angles >= 180 deg., the behaviour is - reversed... that's not spec'ed of course. So, - [0;180) deg. and 50%, or [180;360) deg. and -50% is - outer-to-inner in fact. */ - bool bOuterToInner = (fFocus > 0.0) == (nVmlAngle < 180); + If the angle was provided as a negative, + then the colors are also (again) reversed. */ + bool bOuterToInner = fFocus > 0.0; + if (moAngle.value_or(0) < 0) + bOuterToInner = !bOuterToInner; + // simulate axial gradient by 3-step DrawingML gradient const Color& rOuterColor = bOuterToInner ? aColor1 : aColor2; const Color& rInnerColor = bOuterToInner ? aColor2 : aColor1; @@ -797,13 +800,15 @@ void FillModel::pushToPropMap( ShapePropertyMap& rPropMap, const GraphicHelper& } else // focus of -100%, 0%, and 100% is linear gradient { - /* According to spec, focus of -100% or 100% swaps the - start and stop colors, effectively reversing the - gradient. BUT: For angles >= 180 deg., the - behaviour is reversed. This means that in this case - a focus of 0% swaps the gradient. */ + /* According to spec, a focus of -100% or 100% swaps the + start and stop colors, effectively reversing the gradient. + If the angle was provided as a negative, + then the colors are also (again) reversed. */ if( fFocus < -0.5 || fFocus > 0.5 ) nVmlAngle = (nVmlAngle + 180) % 360; + if (moAngle.value_or(0) < 0) + nVmlAngle = (nVmlAngle + 180) % 360; + // set the start and stop colors lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 0.0, aColor1 ); lcl_setGradientStop( aFillProps.maGradientProps.maGradientStops, 1.0, aColor2 ); diff --git a/sw/qa/extras/ooxmlexport/data/tdf126533_negativeAxialAngle.docx b/sw/qa/extras/ooxmlexport/data/tdf126533_negativeAxialAngle.docx Binary files differnew file mode 100644 index 000000000000..98077b51a372 --- /dev/null +++ b/sw/qa/extras/ooxmlexport/data/tdf126533_negativeAxialAngle.docx diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx index 85c4396cba0a..ef4bcb2d0000 100644 --- a/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx +++ b/sw/qa/extras/ooxmlexport/ooxmlexport7.cxx @@ -9,14 +9,18 @@ #include <swmodeltestbase.hxx> +#include <com/sun/star/awt/Gradient2.hpp> +#include <com/sun/star/drawing/FillStyle.hpp> #include <com/sun/star/drawing/Hatch.hpp> #include <com/sun/star/drawing/PointSequenceSequence.hpp> #include <com/sun/star/packages/zip/ZipFileAccess.hpp> #include <com/sun/star/text/XTextTable.hpp> +#include <basegfx/utils/gradienttools.hxx> #include <config_fonts.h> #include <comphelper/sequenceashashmap.hxx> #include <comphelper/processfactory.hxx> +#include <docmodel/uno/UnoGradientTools.hxx> #include <unotxdoc.hxx> #include <docsh.hxx> @@ -618,6 +622,47 @@ CPPUNIT_TEST_FIXTURE(Test, test77219) DECLARE_OOXMLEXPORT_TEST(testTdf77219_backgroundShape, "tdf77219_backgroundShape.docx") { CPPUNIT_ASSERT_EQUAL_MESSAGE("Shape is in front of the paragraph", false, getProperty<bool>(getShape(1), "Opaque")); + + // tdf#126533: gradient is purple foreground to white background (top-right to bottom-left) + uno::Reference<beans::XPropertySet> xRectangle(getShape(1), uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xRectangle, "FillStyle")); + awt::Gradient2 aGradient = getProperty<awt::Gradient2>(xRectangle, "FillGradient"); + + basegfx::BColorStops aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops); + + CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size()); + CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 0.0)); + CPPUNIT_ASSERT_EQUAL(Color(0x5f497a), Color(aColorStops[0].getStopColor())); + CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 1.0)); + CPPUNIT_ASSERT_EQUAL(COL_WHITE, Color(aColorStops[1].getStopColor())); + CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style); + // without the fix, this was 1350 (visually the colors were reversed) + CPPUNIT_ASSERT_EQUAL(sal_Int16(3150), aGradient.Angle); +} + +DECLARE_OOXMLEXPORT_TEST(testTdf126533_negativeAxialAngle, "tdf126533_negativeAxialAngle.docx") +{ + if (isExported()) + return; + + // axiel gradient is purple foreground/lime background in the middle (top-left to bottom-right) + uno::Reference<beans::XPropertySet> xPageStyle(getStyles("PageStyles")->getByName("Standard"), + uno::UNO_QUERY); + CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, getProperty<drawing::FillStyle>(xPageStyle, "FillStyle")); + awt::Gradient2 aGradient = getProperty<awt::Gradient2>(xPageStyle, "FillGradient"); + + basegfx::BColorStops aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops); + + CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size()); + CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 0.0)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTMAGENTA, Color(aColorStops[0].getStopColor())); + CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[1].getStopOffset(), 0.5)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, Color(aColorStops[1].getStopColor())); + CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[2].getStopOffset(), 1.0)); + CPPUNIT_ASSERT_EQUAL(COL_LIGHTMAGENTA, Color(aColorStops[2].getStopColor())); + // without the fix, this was 1350 (visually the colors were reversed) + CPPUNIT_ASSERT_EQUAL(sal_Int16(450), aGradient.Angle); + CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style); } DECLARE_OOXMLEXPORT_TEST(testTdf77219_foregroundShape, "tdf77219_foregroundShape.docx") |