oox/source/vml/vmlformatting.cxx                                |   27 +++---
 sw/qa/extras/ooxmlexport/data/tdf126533_negativeAxialAngle.docx |binary
 sw/qa/extras/ooxmlexport/ooxmlexport7.cxx                       |   45 
++++++++++
 3 files changed, 61 insertions(+), 11 deletions(-)

New commits:
commit 2c97f30c6aeaddfb9942a1906f182a7704fbf093
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Wed Feb 14 18:16:29 2024 -0500
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Mon Feb 26 08:49:09 2024 +0100

    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 <jl...@mail.com>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163865
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>

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
new file mode 100644
index 000000000000..98077b51a372
Binary files /dev/null and 
b/sw/qa/extras/ooxmlexport/data/tdf126533_negativeAxialAngle.docx differ
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")

Reply via email to