basegfx/source/tools/bgradient.cxx                      |  167 -------------
 chart2/Library_chartcontroller.mk                       |    3 
 chart2/import_setup.mk                                  |    1 
 chart2/qa/extras/chart2import.cxx                       |    5 
 chart2/source/controller/main/ChartController_Tools.cxx |    4 
 docmodel/Library_docmodel.mk                            |    1 
 docmodel/source/uno/UnoGradientTools.cxx                |  200 ++++++++++++++++
 include/basegfx/utils/bgradient.hxx                     |   22 -
 include/docmodel/uno/UnoGradientTools.hxx               |   33 ++
 oox/qa/unit/drawingml.cxx                               |    4 
 oox/qa/unit/shape.cxx                                   |   23 +
 oox/source/drawingml/fillproperties.cxx                 |    5 
 oox/source/drawingml/fontworkhelpers.cxx                |    5 
 oox/source/export/chartexport.cxx                       |   13 -
 oox/source/export/drawingml.cxx                         |   12 
 sd/CppunitTest_sd_misc_tests.mk                         |    1 
 sd/export_setup.mk                                      |    1 
 sd/qa/unit/export-tests-ooxml1.cxx                      |    7 
 sd/qa/unit/export-tests-ooxml2.cxx                      |    4 
 sd/qa/unit/export-tests-ooxml3.cxx                      |    7 
 sd/qa/unit/import-tests.cxx                             |    1 
 sd/qa/unit/import-tests2.cxx                            |    1 
 sd/qa/unit/misc-tests.cxx                               |    6 
 svx/source/unodraw/XPropertyTable.cxx                   |   24 -
 svx/source/xoutdev/xattr.cxx                            |   17 -
 sw/CppunitTest_sw_odfexport.mk                          |    1 
 sw/qa/extras/odfexport/odfexport.cxx                    |    5 
 sw/qa/extras/ooxmlexport/ooxmlexport2.cxx               |    5 
 sw/qa/extras/rtfexport/rtfexport.cxx                    |    5 
 sw/rtfexport_setup.mk                                   |    1 
 xmloff/source/style/GradientStyle.cxx                   |    3 
 xmloff/source/style/TransGradientStyle.cxx              |    3 
 32 files changed, 328 insertions(+), 262 deletions(-)

New commits:
commit eee4b3f8e46b85b3bb4f7cbe83b8af552594be89
Author:     Tomaž Vajngerl <tomaz.vajng...@collabora.co.uk>
AuthorDate: Wed Aug 9 13:27:49 2023 +0200
Commit:     Xisco Fauli <xiscofa...@libreoffice.org>
CommitDate: Wed Sep 6 16:56:27 2023 +0200

    move BGradient to awt::Gradient2 UNO conversion into docmodel
    
    This is needed because the module dependencies are an issues if
    the conversion is done in basegfx. The bigger issue will come when
    the ComplexColor conversion will be done as basegfx can't depend on
    docmodel because of circular dependencies.
    
    The BGradient is also more suitable for docmodel anyway as the
    previously it was part of the model and is not a basic (gfx)
    type - however this doesn't move the whole BGradient into docmodel
    yet.
    
    Change-Id: Id91ce52232f89f00e09b451c13da36e2854ae14b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155674
    Tested-by: Jenkins
    Reviewed-by: Tomaž Vajngerl <qui...@gmail.com>
    (cherry picked from commit 242bb3fdda5be165bd00701518df47cc1276438f)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156449
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/basegfx/source/tools/bgradient.cxx 
b/basegfx/source/tools/bgradient.cxx
index cd6f5492a595..88b1094f2445 100644
--- a/basegfx/source/tools/bgradient.cxx
+++ b/basegfx/source/tools/bgradient.cxx
@@ -68,41 +68,6 @@ basegfx::BGradient lcl_buildGradientFromStringMap(StringMap& 
rMap)
 
 namespace basegfx
 {
-void BColorStops::setColorStopSequence(const css::awt::ColorStopSequence& 
rColorStops)
-{
-    const sal_Int32 nLen(rColorStops.getLength());
-
-    if (0 != nLen)
-    {
-        // we have ColorStops
-        reserve(nLen);
-        const css::awt::ColorStop* 
pSourceColorStop(rColorStops.getConstArray());
-
-        for (sal_Int32 a(0); a < nLen; a++, pSourceColorStop++)
-        {
-            emplace_back(pSourceColorStop->StopOffset,
-                         BColor(pSourceColorStop->StopColor.Red, 
pSourceColorStop->StopColor.Green,
-                                pSourceColorStop->StopColor.Blue));
-        }
-    }
-}
-
-BColorStops::BColorStops(const css::awt::ColorStopSequence& rColorStops)
-{
-    setColorStopSequence(rColorStops);
-}
-
-BColorStops::BColorStops(const css::uno::Any& rVal)
-{
-    if (rVal.has<css::awt::ColorStopSequence>())
-    {
-        // we can use awt::ColorStopSequence
-        css::awt::ColorStopSequence aColorStopSequence;
-        rVal >>= aColorStopSequence;
-        setColorStopSequence(aColorStopSequence);
-    }
-}
-
 // constructor with two colors to explicitly create a
 // BColorStops for a single StartColor @0.0 & EndColor @1.0
 BColorStops::BColorStops(const BColor& rStart, const BColor& rEnd)
@@ -498,28 +463,6 @@ bool BColorStops::checkPenultimate() const
     return true;
 }
 
-/* Tooling method to fill a awt::ColorStopSequence with
-        the data from the given ColorStops. This is used in
-        UNO API implementations.
-    */
-css::awt::ColorStopSequence BColorStops::getAsColorStopSequence() const
-{
-    css::awt::ColorStopSequence aRetval(size());
-    // rColorStopSequence.realloc(rColorStops.size());
-    css::awt::ColorStop* pTargetColorStop(aRetval.getArray());
-
-    for (const auto& candidate : *this)
-    {
-        pTargetColorStop->StopOffset = candidate.getStopOffset();
-        pTargetColorStop->StopColor = 
css::rendering::RGBColor(candidate.getStopColor().getRed(),
-                                                               
candidate.getStopColor().getGreen(),
-                                                               
candidate.getStopColor().getBlue());
-        pTargetColorStop++;
-    }
-
-    return aRetval;
-}
-
 /* Tooling method to check if a ColorStop vector is defined
         by a single color. It returns true if this is the case.
         If true is returned, rSingleColor contains that single
@@ -856,72 +799,6 @@ BGradient::BGradient(const basegfx::BColorStops& 
rColorStops, css::awt::Gradient
     SetColorStops(aColorStops);
 }
 
-void BGradient::setGradient2(const css::awt::Gradient2& rGradient2)
-{
-    // set values
-    SetGradientStyle(rGradient2.Style);
-    SetAngle(Degree10(rGradient2.Angle));
-    SetBorder(rGradient2.Border);
-    SetXOffset(rGradient2.XOffset);
-    SetYOffset(rGradient2.YOffset);
-    SetStartIntens(rGradient2.StartIntensity);
-    SetEndIntens(rGradient2.EndIntensity);
-    SetSteps(rGradient2.StepCount);
-
-    // set ColorStops
-    if (rGradient2.ColorStops.hasElements())
-    {
-        // if we have a awt::ColorStopSequence, use it
-        aColorStops = BColorStops(rGradient2.ColorStops);
-        aColorStops.sortAndCorrect();
-    }
-    else
-    {
-        // if not, for compatibility, use StartColor/EndColor
-        aColorStops = BColorStops{
-            BColorStop(0.0, 
ColorToBColorConverter(rGradient2.StartColor).getBColor()),
-            BColorStop(1.0, 
ColorToBColorConverter(rGradient2.EndColor).getBColor())
-        };
-    }
-}
-
-BGradient::BGradient(const css::awt::Gradient2& rGradient2) { 
setGradient2(rGradient2); }
-
-BGradient::BGradient(const css::uno::Any& rVal)
-    : BGradient()
-{
-    if (rVal.has<css::awt::Gradient2>())
-    {
-        // we can use awt::Gradient2 directly
-        css::awt::Gradient2 aGradient2;
-        rVal >>= aGradient2;
-
-        setGradient2(aGradient2);
-    }
-    else if (rVal.has<css::awt::Gradient>())
-    {
-        // use awt::Gradient
-        css::awt::Gradient aGradient;
-        rVal >>= aGradient;
-
-        // set values
-        SetGradientStyle(aGradient.Style);
-        SetAngle(Degree10(aGradient.Angle));
-        SetBorder(aGradient.Border);
-        SetXOffset(aGradient.XOffset);
-        SetYOffset(aGradient.YOffset);
-        SetStartIntens(aGradient.StartIntensity);
-        SetEndIntens(aGradient.EndIntensity);
-        SetSteps(aGradient.StepCount);
-
-        // complete data by creating ColorStops from fixed Start/EndColor
-        aColorStops = BColorStops{
-            BColorStop(0.0, 
ColorToBColorConverter(aGradient.StartColor).getBColor()),
-            BColorStop(1.0, 
ColorToBColorConverter(aGradient.EndColor).getBColor())
-        };
-    }
-}
-
 bool BGradient::operator==(const BGradient& rGradient) const
 {
     return (eStyle == rGradient.eStyle && aColorStops == rGradient.aColorStops
@@ -969,50 +846,6 @@ boost::property_tree::ptree BGradient::dumpAsJSON() const
     return aTree;
 }
 
-css::awt::Gradient2 BGradient::getAsGradient2() const
-{
-    css::awt::Gradient2 aRetval;
-
-    // standard values
-    aRetval.Style = GetGradientStyle();
-    aRetval.Angle = static_cast<short>(GetAngle());
-    aRetval.Border = GetBorder();
-    aRetval.XOffset = GetXOffset();
-    aRetval.YOffset = GetYOffset();
-    aRetval.StartIntensity = GetStartIntens();
-    aRetval.EndIntensity = GetEndIntens();
-    aRetval.StepCount = GetSteps();
-
-    // for compatibility, still set StartColor/EndColor
-    // NOTE: All code after adapting to multi color gradients works
-    //       using the ColorSteps, so in principle Start/EndColor might
-    //       be either
-    //        (a) ignored consequently everywhere or
-    //        (b) be set/added consequently everywhere
-    //       since this is - in principle - redundant data.
-    //       Be aware that e.g. cases like DrawingML::EqualGradients
-    //       and others would have to be identified and adapted (!)
-    //       Since awt::Gradient2 is UNO API data there might
-    //       be cases where just awt::Gradient is transferred, so (b)
-    //       is far better backwards compatible and thus more safe, so
-    //       all changes will make use of additionally using/setting
-    //       these additionally, but will only make use of the given
-    //       ColorSteps if these are not empty, assuming that these
-    //       already contain Start/EndColor.
-    //       In principle that redundancy and that it is conflict-free
-    //       could even be checked and asserted, but consequently using
-    //       (b) methodically should be safe.
-    aRetval.StartColor
-        = 
static_cast<sal_Int32>(ColorToBColorConverter(aColorStops.front().getStopColor()));
-    aRetval.EndColor
-        = 
static_cast<sal_Int32>(ColorToBColorConverter(aColorStops.back().getStopColor()));
-
-    // fill ColorStops to extended Gradient2
-    aRetval.ColorStops = aColorStops.getAsColorStopSequence();
-
-    return aRetval;
-}
-
 void BGradient::tryToRecreateBorder(basegfx::BColorStops* 
pAssociatedTransparencyStops)
 {
     // border already set, do not try to recreate
diff --git a/chart2/Library_chartcontroller.mk 
b/chart2/Library_chartcontroller.mk
index 56a80ea9e43d..ca50d52a1fd9 100644
--- a/chart2/Library_chartcontroller.mk
+++ b/chart2/Library_chartcontroller.mk
@@ -33,10 +33,11 @@ $(eval $(call gb_Library_use_libraries,chartcontroller,\
     cppu \
     cppuhelper \
     drawinglayer \
+    docmodel \
     editeng \
     sal \
     salhelper \
-       i18nlangtag \
+    i18nlangtag \
     sfx \
     sot \
     svl \
diff --git a/chart2/import_setup.mk b/chart2/import_setup.mk
index fb004d9830f4..a63d314bfc34 100644
--- a/chart2/import_setup.mk
+++ b/chart2/import_setup.mk
@@ -30,6 +30,7 @@ $(eval $(call gb_CppunitTest_use_libraries,chart2_import$(1), 
\
     cppu \
     cppuhelper \
     drawinglayer \
+    docmodel \
     editeng \
     for \
     forui \
diff --git a/chart2/qa/extras/chart2import.cxx 
b/chart2/qa/extras/chart2import.cxx
index 890841a79849..d4bae4aa40d5 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -35,6 +35,7 @@
 #include <com/sun/star/awt/Gradient2.hpp>
 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
 #include <basegfx/utils/gradienttools.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 class Chart2ImportTest : public ChartTest
 {
@@ -628,7 +629,7 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testBnc889755)
     uno::Reference<beans::XPropertySet> xShapeProps(xPage->getByIndex(4), 
uno::UNO_QUERY_THROW);
     awt::Gradient2 aTransparence;
     xShapeProps->getPropertyValue("FillTransparenceGradient") >>= 
aTransparence;
-    const basegfx::BColorStops aColorStops(aTransparence.ColorStops);
+    const basegfx::BColorStops aColorStops = 
model::gradient::getColorStopsFromUno(aTransparence.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size());
     CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
@@ -671,7 +672,7 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest, 
testTransparencyGradientValue)
     uno::Reference< container::XNameAccess > 
xTransparenceGradient(xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"),
 uno::UNO_QUERY);
     uno::Any rTransparenceValue = 
xTransparenceGradient->getByName(sTranspGradientName);
     CPPUNIT_ASSERT(rTransparenceValue >>= aTransparenceGradient);
-    const basegfx::BColorStops aColorStops(aTransparenceGradient.ColorStops);
+    const basegfx::BColorStops aColorStops = 
model::gradient::getColorStopsFromUno(aTransparenceGradient.ColorStops);
 
     // MCGR: Use the whole completely imported transparency gradient to check 
for correctness
     CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
diff --git a/chart2/source/controller/main/ChartController_Tools.cxx 
b/chart2/source/controller/main/ChartController_Tools.cxx
index 1a8f5071982f..da166261328f 100644
--- a/chart2/source/controller/main/ChartController_Tools.cxx
+++ b/chart2/source/controller/main/ChartController_Tools.cxx
@@ -47,6 +47,7 @@
 #include <ObjectNameProvider.hxx>
 #include <unonames.hxx>
 
+#include <com/sun/star/awt/Gradient.hpp>
 #include <com/sun/star/chart2/DataPointLabel.hpp>
 #include <com/sun/star/beans/XPropertyState.hpp>
 #include <com/sun/star/graphic/XGraphic.hpp>
@@ -55,6 +56,7 @@
 #include <com/sun/star/chart/ErrorBarStyle.hpp>
 #include <com/sun/star/chart2/XRegressionCurveContainer.hpp>
 
+#include <docmodel/uno/UnoGradientTools.hxx>
 #include <editeng/editview.hxx>
 #include <editeng/outliner.hxx>
 #include <svx/ActionDescriptionProvider.hxx>
@@ -957,7 +959,7 @@ void ChartController::executeDispatch_FillColor(sal_uInt32 
nColor)
 void ChartController::executeDispatch_FillGradient(std::u16string_view 
sJSONGradient)
 {
     basegfx::BGradient aBGradient = 
basegfx::BGradient::fromJSON(sJSONGradient);
-    css::awt::Gradient aGradient = aBGradient.getAsGradient2();
+    css::awt::Gradient aGradient = 
model::gradient::createUnoGradient2(aBGradient);
 
     try
     {
diff --git a/docmodel/Library_docmodel.mk b/docmodel/Library_docmodel.mk
index 2e474eb4f0b8..2678beee7b22 100644
--- a/docmodel/Library_docmodel.mk
+++ b/docmodel/Library_docmodel.mk
@@ -11,6 +11,7 @@ $(eval $(call gb_Library_Library,docmodel))
 
 $(eval $(call gb_Library_add_exception_objects,docmodel,\
     docmodel/source/uno/UnoComplexColor \
+    docmodel/source/uno/UnoGradientTools \
     docmodel/source/uno/UnoTheme \
     docmodel/source/theme/ColorSet \
     docmodel/source/theme/Theme \
diff --git a/docmodel/source/uno/UnoGradientTools.cxx 
b/docmodel/source/uno/UnoGradientTools.cxx
new file mode 100644
index 000000000000..0f05e398de78
--- /dev/null
+++ b/docmodel/source/uno/UnoGradientTools.cxx
@@ -0,0 +1,200 @@
+/* -*- 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 <docmodel/uno/UnoGradientTools.hxx>
+#include <com/sun/star/awt/Gradient.hpp>
+#include <com/sun/star/awt/Gradient2.hpp>
+#include <com/sun/star/rendering/RGBColor.hpp>
+#include <basegfx/utils/bgradient.hxx>
+#include <tools/color.hxx>
+
+using namespace css;
+
+namespace model::gradient
+{
+css::awt::ColorStopSequence createColorStopSequence(basegfx::BColorStops 
const& rColorStops)
+{
+    // Fill color stops
+    css::awt::ColorStopSequence aSequence(rColorStops.size());
+    css::awt::ColorStop* pSequence(aSequence.getArray());
+
+    for (const auto& rStop : rColorStops)
+    {
+        auto rBColor = rStop.getStopColor();
+        pSequence->StopOffset = rStop.getStopOffset();
+        pSequence->StopColor
+            = css::rendering::RGBColor(rBColor.getRed(), rBColor.getGreen(), 
rBColor.getBlue());
+        pSequence++;
+    }
+
+    return aSequence;
+}
+
+css::awt::Gradient2 createUnoGradient2(basegfx::BGradient const& rGradient)
+{
+    css::awt::Gradient2 aGradient2;
+
+    // standard values
+    aGradient2.Style = rGradient.GetGradientStyle();
+    aGradient2.Angle = static_cast<short>(rGradient.GetAngle());
+    aGradient2.Border = rGradient.GetBorder();
+    aGradient2.XOffset = rGradient.GetXOffset();
+    aGradient2.YOffset = rGradient.GetYOffset();
+    aGradient2.StartIntensity = rGradient.GetStartIntens();
+    aGradient2.EndIntensity = rGradient.GetEndIntens();
+    aGradient2.StepCount = rGradient.GetSteps();
+
+    // for compatibility, still set StartColor/EndColor
+    // NOTE: All code after adapting to multi color gradients works
+    //       using the ColorSteps, so in principle Start/EndColor might
+    //       be either
+    //        (a) ignored consequently everywhere or
+    //        (b) be set/added consequently everywhere
+    //       since this is - in principle - redundant data.
+    //       Be aware that e.g. cases like DrawingML::EqualGradients
+    //       and others would have to be identified and adapted (!)
+    //       Since awt::Gradient2 is UNO API data there might
+    //       be cases where just awt::Gradient is transferred, so (b)
+    //       is far better backwards compatible and thus more safe, so
+    //       all changes will make use of additionally using/setting
+    //       these additionally, but will only make use of the given
+    //       ColorSteps if these are not empty, assuming that these
+    //       already contain Start/EndColor.
+    //       In principle that redundancy and that it is conflict-free
+    //       could even be checked and asserted, but consequently using
+    //       (b) methodically should be safe.
+    const basegfx::BColorStops& rColorStops = rGradient.GetColorStops();
+    aGradient2.StartColor = 
static_cast<sal_Int32>(::Color(rColorStops.front().getStopColor()));
+    aGradient2.EndColor = 
static_cast<sal_Int32>(::Color(rColorStops.back().getStopColor()));
+
+    aGradient2.ColorStops = createColorStopSequence(rColorStops);
+
+    return aGradient2;
+}
+
+namespace
+{
+void fillFromColorStopSequence(basegfx::BColorStops& rColorStops,
+                               css::awt::ColorStopSequence const& 
rUnoColorStopSequence)
+{
+    const auto nLength = rUnoColorStopSequence.getLength();
+    if (0 != nLength)
+    {
+        rColorStops.clear();
+        rColorStops.reserve(nLength);
+
+        for (css::awt::ColorStop const& rSourceStop : rUnoColorStopSequence)
+        {
+            rColorStops.emplace_back(rSourceStop.StopOffset,
+                                     basegfx::BColor(rSourceStop.StopColor.Red,
+                                                     
rSourceStop.StopColor.Green,
+                                                     
rSourceStop.StopColor.Blue));
+        }
+    }
+}
+
+void fillFromGradient2(basegfx::BGradient& rBGradient, css::awt::Gradient2 
const& rGradient2)
+{
+    rBGradient.SetGradientStyle(rGradient2.Style);
+    rBGradient.SetAngle(Degree10(rGradient2.Angle));
+    rBGradient.SetBorder(rGradient2.Border);
+    rBGradient.SetXOffset(rGradient2.XOffset);
+    rBGradient.SetYOffset(rGradient2.YOffset);
+    rBGradient.SetStartIntens(rGradient2.StartIntensity);
+    rBGradient.SetEndIntens(rGradient2.EndIntensity);
+    rBGradient.SetSteps(rGradient2.StepCount);
+
+    // set ColorStops
+    if (rGradient2.ColorStops.hasElements())
+    {
+        basegfx::BColorStops aColorStops;
+        fillFromColorStopSequence(aColorStops, rGradient2.ColorStops);
+        rBGradient.SetColorStops(aColorStops);
+    }
+    else
+    {
+        // if not, for compatibility, use StartColor/EndColor
+        basegfx::BColorStops aColorStops{
+            basegfx::BColorStop(0.0, ::Color(ColorTransparency, 
rGradient2.StartColor).getBColor()),
+            basegfx::BColorStop(1.0, ::Color(ColorTransparency, 
rGradient2.EndColor).getBColor())
+        };
+        rBGradient.SetColorStops(aColorStops);
+    }
+}
+
+} // end anonymous
+
+basegfx::BColorStops getColorStopsFromUno(css::awt::ColorStopSequence const& 
rColorStopSequence)
+{
+    basegfx::BColorStops aColorStops;
+    fillFromColorStopSequence(aColorStops, rColorStopSequence);
+    return aColorStops;
+}
+
+basegfx::BColorStops getColorStopsFromAny(css::uno::Any const& rAny)
+{
+    basegfx::BColorStops aColorStops;
+    if (!rAny.has<css::awt::ColorStopSequence>())
+        return aColorStops;
+
+    auto aSequence = rAny.get<css::awt::ColorStopSequence>();
+    fillFromColorStopSequence(aColorStops, aSequence);
+    return aColorStops;
+}
+
+basegfx::BGradient getFromUnoGradient2(css::awt::Gradient2 const& rGradient2)
+{
+    basegfx::BGradient aBGradient;
+    fillFromGradient2(aBGradient, rGradient2);
+    return aBGradient;
+}
+
+basegfx::BGradient getFromAny(css::uno::Any const& rAny)
+{
+    basegfx::BGradient aBGradient;
+
+    if (rAny.has<css::awt::Gradient2>())
+    {
+        // we can use awt::Gradient2 directly
+        css::awt::Gradient2 aGradient2;
+        rAny >>= aGradient2;
+
+        fillFromGradient2(aBGradient, aGradient2);
+    }
+    else if (rAny.has<css::awt::Gradient>())
+    {
+        // use awt::Gradient
+        css::awt::Gradient aGradient;
+        rAny >>= aGradient;
+
+        // set values
+        aBGradient.SetGradientStyle(aGradient.Style);
+        aBGradient.SetAngle(Degree10(aGradient.Angle));
+        aBGradient.SetBorder(aGradient.Border);
+        aBGradient.SetXOffset(aGradient.XOffset);
+        aBGradient.SetYOffset(aGradient.YOffset);
+        aBGradient.SetStartIntens(aGradient.StartIntensity);
+        aBGradient.SetEndIntens(aGradient.EndIntensity);
+        aBGradient.SetSteps(aGradient.StepCount);
+
+        basegfx::BColorStops aColorStops{
+            basegfx::BColorStop(0.0, ::Color(ColorTransparency, 
aGradient.StartColor).getBColor()),
+            basegfx::BColorStop(1.0, ::Color(ColorTransparency, 
aGradient.EndColor).getBColor())
+        };
+
+        aBGradient.SetColorStops(aColorStops);
+    }
+
+    return aBGradient;
+}
+
+} // end model::gradient
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/basegfx/utils/bgradient.hxx 
b/include/basegfx/utils/bgradient.hxx
index 3e2acf9a4b67..69dbb3fd5944 100644
--- a/include/basegfx/utils/bgradient.hxx
+++ b/include/basegfx/utils/bgradient.hxx
@@ -13,7 +13,6 @@
 #include <basegfx/color/bcolor.hxx>
 #include <basegfx/basegfxdllapi.h>
 #include <vector>
-#include <com/sun/star/awt/Gradient2.hpp>
 #include <com/sun/star/awt/GradientStyle.hpp>
 #include <tools/degree.hxx>
 #include <boost/property_tree/ptree_fwd.hpp>
@@ -109,9 +108,6 @@ public:
     */
 class BASEGFX_DLLPUBLIC BColorStops final : public std::vector<BColorStop>
 {
-private:
-    void setColorStopSequence(const css::awt::ColorStopSequence& rColorStops);
-
 public:
     explicit BColorStops()
         : vector()
@@ -133,10 +129,6 @@ public:
         : vector(first, last)
     {
     }
-    BColorStops(const css::awt::ColorStopSequence& rColorStops);
-
-    // needs true == rVal.has<css::awt::ColorStopSequence>()
-    BColorStops(const css::uno::Any& rVal);
 
     // constructor with two colors to explicitly create a
     // BColorStops for StartColor @0.0 & EndColor @1.0
@@ -243,12 +235,6 @@ public:
     // tessellation for gradients does have to create an extra ending/closing 
entry
     bool checkPenultimate() const;
 
-    /* Tooling method to fill a awt::ColorStopSequence with
-           the data from the given ColorStops. This is used in
-           UNO API implementations.
-        */
-    css::awt::ColorStopSequence getAsColorStopSequence() const;
-
     /* Tooling method to check if a ColorStop vector is defined
             by a single color. It returns true if this is the case.
             If true is returned, rSingleColor contains that single
@@ -304,7 +290,6 @@ private:
     sal_uInt16 nStepCount;
 
     static std::string GradientStyleToString(css::awt::GradientStyle eStyle);
-    void setGradient2(const css::awt::Gradient2& rGradient2);
 
 public:
     BGradient();
@@ -313,10 +298,6 @@ public:
               Degree10 nAngle = 0_deg10, sal_uInt16 nXOfs = 50, sal_uInt16 
nYOfs = 50,
               sal_uInt16 nBorder = 0, sal_uInt16 nStartIntens = 100, 
sal_uInt16 nEndIntens = 100,
               sal_uInt16 nSteps = 0);
-    BGradient(const css::awt::Gradient2& rGradient2);
-
-    // needs true == (rVal.has<css::awt::Gradient>() || 
rVal.has<css::awt::Gradient2>())
-    BGradient(const css::uno::Any& rVal);
 
     bool operator==(const BGradient& rGradient) const;
 
@@ -343,9 +324,6 @@ public:
     boost::property_tree::ptree dumpAsJSON() const;
     static BGradient fromJSON(std::u16string_view rJSON);
 
-    /// Tooling method to fill awt::Gradient2 from data contained in the given 
basegfx::BGradient
-    css::awt::Gradient2 getAsGradient2() const;
-
     // Tooling to handle
     // - border correction/integration
     // - apply StartStopIntensity to color stops
diff --git a/include/docmodel/uno/UnoGradientTools.hxx 
b/include/docmodel/uno/UnoGradientTools.hxx
new file mode 100644
index 000000000000..3d748d4930d2
--- /dev/null
+++ b/include/docmodel/uno/UnoGradientTools.hxx
@@ -0,0 +1,33 @@
+/* -*- 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/.
+ */
+
+#pragma once
+
+#include <docmodel/dllapi.h>
+#include <basegfx/utils/bgradient.hxx>
+#include <com/sun/star/awt/Gradient2.hpp>
+#include <com/sun/star/awt/ColorStopSequence.hpp>
+#include <com/sun/star/uno/Any.hxx>
+
+namespace model::gradient
+{
+DOCMODEL_DLLPUBLIC css::awt::Gradient2 createUnoGradient2(basegfx::BGradient 
const& rGradient);
+
+DOCMODEL_DLLPUBLIC basegfx::BGradient getFromUnoGradient2(css::awt::Gradient2 
const& rGradient2);
+DOCMODEL_DLLPUBLIC basegfx::BGradient getFromAny(css::uno::Any const& rAny);
+
+DOCMODEL_DLLPUBLIC css::awt::ColorStopSequence
+createColorStopSequence(basegfx::BColorStops const& rColorStops);
+
+DOCMODEL_DLLPUBLIC basegfx::BColorStops
+getColorStopsFromUno(css::awt::ColorStopSequence const& rColorStopSequence);
+DOCMODEL_DLLPUBLIC basegfx::BColorStops getColorStopsFromAny(css::uno::Any 
const& rAny);
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/oox/qa/unit/drawingml.cxx b/oox/qa/unit/drawingml.cxx
index 27bd3984a1c7..811b7e3ea889 100644
--- a/oox/qa/unit/drawingml.cxx
+++ b/oox/qa/unit/drawingml.cxx
@@ -30,6 +30,7 @@
 #include <com/sun/star/table/XCellRange.hpp>
 #include <com/sun/star/util/XTheme.hpp>
 
+#include <docmodel/uno/UnoGradientTools.hxx>
 #include <docmodel/uno/UnoComplexColor.hxx>
 #include <docmodel/uno/UnoTheme.hxx>
 #include <docmodel/theme/Theme.hxx>
@@ -191,7 +192,8 @@ CPPUNIT_TEST_FIXTURE(OoxDrawingmlTest, 
testGradientMultiStepTransparency)
     // i.e. the end transparency was not 100%, but was 21%, leading to an 
unexpected visible line on
     // the right of this shape.
     // MCGR: Use the completely imported transparency gradient to check for 
correctness
-    const basegfx::BColorStops aColorStops(aTransparence.ColorStops);
+    const basegfx::BColorStops aColorStops
+        = model::gradient::getColorStopsFromUno(aTransparence.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(5), aColorStops.size());
     CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[4].getStopOffset(), 
1.0));
diff --git a/oox/qa/unit/shape.cxx b/oox/qa/unit/shape.cxx
index 68ce372335df..54c19b7aeee5 100644
--- a/oox/qa/unit/shape.cxx
+++ b/oox/qa/unit/shape.cxx
@@ -37,6 +37,7 @@
 #include <svx/svdoashp.hxx>
 #include <tools/color.hxx>
 #include <docmodel/uno/UnoComplexColor.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 #include <basegfx/utils/gradienttools.hxx>
 
 using namespace ::com::sun::star;
@@ -471,7 +472,8 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, testWriterFontwork3)
         xShapeProps->getPropertyValue(u"FillGradient") >>= aGradient;
 
         // MCGR: Use the completely imported transparency gradient to check 
for correctness
-        const basegfx::BColorStops aColorStops(aGradient.ColorStops);
+        basegfx::BColorStops aColorStops;
+        aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
         CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
@@ -496,7 +498,8 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, testWriterFontwork3)
         xShapeProps->getPropertyValue(u"FillGradient") >>= aGradient;
 
         // MCGR: Use the completely imported transparency gradient to check 
for correctness
-        const basegfx::BColorStops aColorStops(aGradient.ColorStops);
+        basegfx::BColorStops aColorStops;
+        aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
         CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.40000000000000002));
@@ -521,7 +524,8 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, testWriterFontwork3)
         xShapeProps->getPropertyValue(u"FillGradient") >>= aGradient;
 
         // MCGR: Use the completely imported transparency gradient to check 
for correctness
-        const basegfx::BColorStops aColorStops(aGradient.ColorStops);
+        basegfx::BColorStops aColorStops;
+        aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
         CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
@@ -638,7 +642,8 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, 
testImportWordArtGradient)
         xShapeProps->getPropertyValue(u"FillGradient") >>= aGradient;
 
         // MCGR: Use the completely imported transparency gradient to check 
for correctness
-        const basegfx::BColorStops aColorStops(aGradient.ColorStops);
+        basegfx::BColorStops aColorStops;
+        aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
         CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
@@ -671,7 +676,8 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, 
testImportWordArtGradient)
         xShapeProps->getPropertyValue(u"FillGradient") >>= aGradient;
 
         // MCGR: Use the completely imported transparency gradient to check 
for correctness
-        basegfx::BColorStops aColorStops(aGradient.ColorStops);
+        basegfx::BColorStops aColorStops;
+        aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
         CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
@@ -687,7 +693,7 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, 
testImportWordArtGradient)
 
         xShapeProps->getPropertyValue(u"FillTransparenceGradient") >>= 
aGradient;
         // MCGR: Use the completely imported transparency gradient to check 
for correctness
-        aColorStops = basegfx::BColorStops(aGradient.ColorStops);
+        aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
         // Transparency is encoded in gray color.
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
@@ -728,7 +734,8 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, 
testImportWordArtGradient)
         xShapeProps->getPropertyValue(u"FillGradient") >>= aGradient;
 
         // MCGR: Use the completely imported transparency gradient to check 
for correctness
-        basegfx::BColorStops aColorStops(aGradient.ColorStops);
+        basegfx::BColorStops aColorStops;
+        aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
         CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
@@ -746,7 +753,7 @@ CPPUNIT_TEST_FIXTURE(OoxShapeTest, 
testImportWordArtGradient)
 
         xShapeProps->getPropertyValue(u"FillTransparenceGradient") >>= 
aGradient;
         // MCGR: Use the completely imported transparency gradient to check 
for correctness
-        aColorStops = basegfx::BColorStops(aGradient.ColorStops);
+        aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
         // Transparency is encoded in gray color.
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
diff --git a/oox/source/drawingml/fillproperties.cxx 
b/oox/source/drawingml/fillproperties.cxx
index b6d6940918ec..e1c73748f919 100644
--- a/oox/source/drawingml/fillproperties.cxx
+++ b/oox/source/drawingml/fillproperties.cxx
@@ -27,6 +27,7 @@
 #include <vcl/BitmapFilter.hxx>
 #include <vcl/BitmapMonochromeFilter.hxx>
 #include <docmodel/uno/UnoComplexColor.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 #include <basegfx/utils/gradienttools.hxx>
 
 #include <com/sun/star/beans/XPropertySet.hpp>
@@ -547,7 +548,7 @@ void FillProperties::pushToPropMap(ShapePropertyMap& 
rPropMap, const GraphicHelp
                 }
 
                 // push gradient or named gradient to property map
-                if (rPropMap.setProperty(ShapeProperty::FillGradient, 
aGradient.getAsGradient2()))
+                if (rPropMap.setProperty(ShapeProperty::FillGradient, 
model::gradient::createUnoGradient2(aGradient)))
                 {
                     eFillStyle = FillStyle_GRADIENT;
                 }
@@ -556,7 +557,7 @@ void FillProperties::pushToPropMap(ShapePropertyMap& 
rPropMap, const GraphicHelp
                 if (!aTransparencyStops.empty())
                 {
                     aGradient.SetColorStops(aTransparencyStops);
-                    rPropMap.setProperty(ShapeProperty::GradientTransparency, 
aGradient.getAsGradient2());
+                    rPropMap.setProperty(ShapeProperty::GradientTransparency, 
model::gradient::createUnoGradient2(aGradient));
                 }
             }
         break;
diff --git a/oox/source/drawingml/fontworkhelpers.cxx 
b/oox/source/drawingml/fontworkhelpers.cxx
index 3061230f9e5b..1f93a02f83af 100644
--- a/oox/source/drawingml/fontworkhelpers.cxx
+++ b/oox/source/drawingml/fontworkhelpers.cxx
@@ -26,6 +26,7 @@
 #include <comphelper/sequence.hxx>
 #include <comphelper/sequenceashashmap.hxx>
 #include <docmodel/uno/UnoComplexColor.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 #include <drawingml/customshapeproperties.hxx>
 #include <drawingml/presetgeometrynames.hxx>
 #include <oox/drawingml/drawingmltypes.hxx>
@@ -1173,7 +1174,7 @@ ColorMapType lcl_createColorMapFromShapeProps(
     basegfx::BColorStops aColorStops;
     if (rbHasColorGradient)
     {
-        aColorBGradient = basegfx::BGradient(rColorGradient);
+        aColorBGradient = model::gradient::getFromUnoGradient2(rColorGradient);
         aColorBGradient.tryToApplyStartEndIntensity();
         aColorBGradient.tryToApplyBorder();
         aColorBGradient.tryToApplyAxial();
@@ -1196,7 +1197,7 @@ ColorMapType lcl_createColorMapFromShapeProps(
     basegfx::BColorStops aTransStops;
     if (rbHasTransparenceGradient)
     {
-        aTransBGradient = basegfx::BGradient(rTransparenceGradient);
+        aTransBGradient = 
model::gradient::getFromUnoGradient2(rTransparenceGradient);
         aTransBGradient.tryToApplyStartEndIntensity(); // usually 100%, but 
might be set by macro
         aTransBGradient.tryToApplyBorder();
         aTransBGradient.tryToApplyAxial();
diff --git a/oox/source/export/chartexport.cxx 
b/oox/source/export/chartexport.cxx
index f0a301f79136..c9db6f8cc431 100644
--- a/oox/source/export/chartexport.cxx
+++ b/oox/source/export/chartexport.cxx
@@ -26,6 +26,7 @@
 #include <oox/export/utils.hxx>
 #include <drawingml/chart/typegroupconverter.hxx>
 #include <basegfx/utils/gradienttools.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 #include <cstdio>
 #include <limits>
@@ -1913,9 +1914,9 @@ void ChartExport::exportSolidFill(const Reference< 
XPropertySet >& xPropSet)
     {
         uno::Reference< lang::XMultiServiceFactory > xFact( getModel(), 
uno::UNO_QUERY );
         uno::Reference< container::XNameAccess > 
xTransparenceGradient(xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"),
 uno::UNO_QUERY);
-        const uno::Any rTransparenceValue = 
xTransparenceGradient->getByName(sFillTransparenceGradientName);
+        const uno::Any rTransparenceAny = 
xTransparenceGradient->getByName(sFillTransparenceGradientName);
 
-        aTransparenceGradient = basegfx::BGradient(rTransparenceValue);
+        aTransparenceGradient = model::gradient::getFromAny(rTransparenceAny);
         basegfx::BColor aSingleColor;
         bNeedGradientFill = 
!aTransparenceGradient.GetColorStops().isSingleColor(aSingleColor);
 
@@ -2001,8 +2002,8 @@ void ChartExport::exportGradientFill( const Reference< 
XPropertySet >& xPropSet
     try
     {
         uno::Reference< container::XNameAccess > xGradient( 
xFact->createInstance("com.sun.star.drawing.GradientTable"), uno::UNO_QUERY );
-        const uno::Any rGradientValue(xGradient->getByName( sFillGradientName 
));
-        const basegfx::BGradient aGradient(rGradientValue);
+        const uno::Any rGradientAny(xGradient->getByName( sFillGradientName ));
+        const basegfx::BGradient aGradient = 
model::gradient::getFromAny(rGradientAny);
         basegfx::BColor aSingleColor;
 
         if (!aGradient.GetColorStops().isSingleColor(aSingleColor))
@@ -2014,9 +2015,9 @@ void ChartExport::exportGradientFill( const Reference< 
XPropertySet >& xPropSet
             if( (xPropSet->getPropertyValue("FillTransparenceGradientName") 
>>= sFillTransparenceGradientName) && !sFillTransparenceGradientName.isEmpty())
             {
                 uno::Reference< container::XNameAccess > 
xTransparenceGradient(xFact->createInstance("com.sun.star.drawing.TransparencyGradientTable"),
 uno::UNO_QUERY);
-                const uno::Any 
rTransparenceValue(xTransparenceGradient->getByName(sFillTransparenceGradientName));
+                const uno::Any 
rTransparenceAny(xTransparenceGradient->getByName(sFillTransparenceGradientName));
 
-                aTransparenceGradient = basegfx::BGradient(rTransparenceValue);
+                aTransparenceGradient = 
model::gradient::getFromAny(rTransparenceAny);
 
                 WriteGradientFill(&aGradient, 0, &aTransparenceGradient);
             }
diff --git a/oox/source/export/drawingml.cxx b/oox/source/export/drawingml.cxx
index 8360a20908b7..1da4a246e37e 100644
--- a/oox/source/export/drawingml.cxx
+++ b/oox/source/export/drawingml.cxx
@@ -135,6 +135,7 @@
 #include <svx/unoshape.hxx>
 #include <svx/EnhancedCustomShape2d.hxx>
 #include <drawingml/presetgeometrynames.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 using namespace ::css;
 using namespace ::css::beans;
@@ -481,7 +482,7 @@ void DrawingML::WriteSolidFill( const Reference< 
XPropertySet >& rXPropSet )
         && !sFillTransparenceGradientName.isEmpty()
         && GetProperty(rXPropSet, "FillTransparenceGradient"))
     {
-        aTransparenceGradient = basegfx::BGradient(mAny);
+        aTransparenceGradient = model::gradient::getFromAny(mAny);
         basegfx::BColor aSingleColor;
         bNeedGradientFill = 
!aTransparenceGradient.GetColorStops().isSingleColor(aSingleColor);
 
@@ -605,7 +606,7 @@ void DrawingML::WriteGradientFill( const Reference< 
XPropertySet >& rXPropSet )
         return;
 
     // use BGradient constructor directly, it will take care of 
Gradient/Gradient2
-    basegfx::BGradient aGradient(mAny);
+    basegfx::BGradient aGradient = model::gradient::getFromAny(mAny);
 
     // get InteropGrabBag and search the relevant attributes
     basegfx::BGradient aOriginalGradient;
@@ -618,8 +619,7 @@ void DrawingML::WriteGradientFill( const Reference< 
XPropertySet >& rXPropSet )
             if( rProp.Name == "GradFillDefinition" )
                 rProp.Value >>= aGradientStops;
             else if( rProp.Name == "OriginalGradFill" )
-                // use BGradient constructor directly, it will take care of 
Gradient/Gradient2
-                aOriginalGradient = basegfx::BGradient(rProp.Value);
+                aOriginalGradient = model::gradient::getFromAny(rProp.Value);
     }
 
     // check if an ooxml gradient had been imported and if the user has 
modified it
@@ -650,7 +650,7 @@ void DrawingML::WriteGradientFill( const Reference< 
XPropertySet >& rXPropSet )
             && GetProperty(rXPropSet, "FillTransparenceGradient"))
         {
             // TransparenceGradient is only used when name is not empty
-            aTransparenceGradient = basegfx::BGradient(mAny);
+            aTransparenceGradient = model::gradient::getFromAny(mAny);
             pTransparenceGradient = &aTransparenceGradient;
         }
         else if (GetProperty(rXPropSet, "FillTransparence"))
@@ -5312,7 +5312,7 @@ void DrawingML::WriteFill(const Reference<XPropertySet>& 
xPropSet, const awt::Si
         {
             // check if a fully transparent TransparenceGradient is used
             // use BGradient constructor & tooling here now
-            const basegfx::BGradient aTransparenceGradient(mAny);
+            const basegfx::BGradient aTransparenceGradient = 
model::gradient::getFromAny(mAny);
             basegfx::BColor aSingleColor;
             const bool 
bSingleColor(aTransparenceGradient.GetColorStops().isSingleColor(aSingleColor));
             const bool bCompletelyTransparent(bSingleColor && 
basegfx::fTools::equal(aSingleColor.luminance(), 1.0));
diff --git a/sd/CppunitTest_sd_misc_tests.mk b/sd/CppunitTest_sd_misc_tests.mk
index 5a382b8c2df0..f98f32a683a8 100644
--- a/sd/CppunitTest_sd_misc_tests.mk
+++ b/sd/CppunitTest_sd_misc_tests.mk
@@ -29,6 +29,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sd_misc_tests, \
     cppu \
     cppuhelper \
     drawinglayer \
+    docmodel \
     editeng \
     for \
     forui \
diff --git a/sd/export_setup.mk b/sd/export_setup.mk
index 326449e3f89a..e9b2a8a88bcd 100644
--- a/sd/export_setup.mk
+++ b/sd/export_setup.mk
@@ -32,6 +32,7 @@ $(eval $(call 
gb_CppunitTest_use_libraries,sd_export_tests$(1), \
     cppu \
     cppuhelper \
     drawinglayer \
+    docmodel \
     editeng \
     for \
     forui \
diff --git a/sd/qa/unit/export-tests-ooxml1.cxx 
b/sd/qa/unit/export-tests-ooxml1.cxx
index afcbc1c542d6..5f08adb09e74 100644
--- a/sd/qa/unit/export-tests-ooxml1.cxx
+++ b/sd/qa/unit/export-tests-ooxml1.cxx
@@ -36,6 +36,7 @@
 #include <com/sun/star/table/BorderLine2.hpp>
 #include <com/sun/star/table/XMergeableCell.hpp>
 
+#include <docmodel/uno/UnoGradientTools.hxx>
 #include <svx/svdotable.hxx>
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 #include <rtl/uri.hxx>
@@ -1226,7 +1227,8 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest1, testTdf94238)
     CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(0), aGradient.Border);
 
     // MCGR: Use the completely imported gradient to check for correctness
-    const basegfx::BColorStops aColorStops(aGradient.ColorStops);
+    const basegfx::BColorStops aColorStops
+        = model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
     // Without the accompanying fix in place, this test would have failed with
     // 'Expected: 0, Actual  : 10592673', i.e. the start color of the gradient
@@ -1485,7 +1487,8 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest1, 
testTdf128345GradientAxial)
     xShapePropSet->getPropertyValue("FillTransparenceGradient") >>= 
aTransparenceGradient;
 
     // MCGR: Use the completely imported gradient to check for correctness
-    const basegfx::BColorStops aColorStops(aTransparenceGradient.ColorStops);
+    const basegfx::BColorStops aColorStops
+        = 
model::gradient::getColorStopsFromUno(aTransparenceGradient.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size());
     CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
diff --git a/sd/qa/unit/export-tests-ooxml2.cxx 
b/sd/qa/unit/export-tests-ooxml2.cxx
index d4521b1ad87f..aaf245f2e90d 100644
--- a/sd/qa/unit/export-tests-ooxml2.cxx
+++ b/sd/qa/unit/export-tests-ooxml2.cxx
@@ -14,6 +14,7 @@
 #include <svx/svdomedia.hxx>
 #include <svx/svdotable.hxx>
 #include <svx/svdpage.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 #include <com/sun/star/animations/TransitionType.hpp>
 #include <com/sun/star/animations/TransitionSubType.hpp>
@@ -1011,7 +1012,8 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest2, testTdf105739)
         aXBackgroundPropSet->getPropertyValue("FillGradient") >>= 
aFillGradient;
 
         // MCGR: Use the completely imported gradient to check for correctness
-        const basegfx::BColorStops aColorStops(aFillGradient.ColorStops);
+        const basegfx::BColorStops aColorStops
+            = model::gradient::getColorStopsFromUno(aFillGradient.ColorStops);
 
         CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
         CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
diff --git a/sd/qa/unit/export-tests-ooxml3.cxx 
b/sd/qa/unit/export-tests-ooxml3.cxx
index bd343497ff59..5b33feacea63 100644
--- a/sd/qa/unit/export-tests-ooxml3.cxx
+++ b/sd/qa/unit/export-tests-ooxml3.cxx
@@ -16,6 +16,7 @@
 #include <editeng/editobj.hxx>
 #include <editeng/numitem.hxx>
 #include <editeng/unoprnms.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 #include <svx/xlineit0.hxx>
 #include <svx/xlndsit.hxx>
@@ -1247,7 +1248,8 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf127372)
     xShape->getPropertyValue("FillTransparenceGradient") >>= 
aTransparenceGradient;
 
     // MCGR: Use the completely imported gradient to check for correctness
-    const basegfx::BColorStops aColorStops(aTransparenceGradient.ColorStops);
+    const basegfx::BColorStops aColorStops
+        = 
model::gradient::getColorStopsFromUno(aTransparenceGradient.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
     CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
@@ -1279,7 +1281,8 @@ CPPUNIT_TEST_FIXTURE(SdOOXMLExportTest3, testTdf127379)
     CPPUNIT_ASSERT(aXBackgroundPropSet->getPropertyValue("FillGradient") >>= 
aGradient);
 
     // MCGR: Use the completely imported gradient to check for correctness
-    const basegfx::BColorStops aColorStops(aGradient.ColorStops);
+    const 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));
diff --git a/sd/qa/unit/import-tests.cxx b/sd/qa/unit/import-tests.cxx
index 10ebc2fae48e..adc7c12e4632 100644
--- a/sd/qa/unit/import-tests.cxx
+++ b/sd/qa/unit/import-tests.cxx
@@ -33,6 +33,7 @@
 #include <animations/animationnodehelper.hxx>
 #include <sax/tools/converter.hxx>
 
+#include <com/sun/star/awt/Gradient.hpp>
 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
 #include <com/sun/star/document/XEventsSupplier.hpp>
 #include <com/sun/star/presentation/ClickAction.hpp>
diff --git a/sd/qa/unit/import-tests2.cxx b/sd/qa/unit/import-tests2.cxx
index fcb3d656c4ac..7702e27d715e 100644
--- a/sd/qa/unit/import-tests2.cxx
+++ b/sd/qa/unit/import-tests2.cxx
@@ -26,6 +26,7 @@
 #include <animations/animationnodehelper.hxx>
 
 #include <com/sun/star/awt/XBitmap.hpp>
+#include <com/sun/star/awt/Gradient.hpp>
 #include <com/sun/star/document/XEventsSupplier.hpp>
 #include <com/sun/star/presentation/ClickAction.hpp>
 #include <com/sun/star/presentation/XPresentationPage.hpp>
diff --git a/sd/qa/unit/misc-tests.cxx b/sd/qa/unit/misc-tests.cxx
index 485feb5bbbd8..232c9e996961 100644
--- a/sd/qa/unit/misc-tests.cxx
+++ b/sd/qa/unit/misc-tests.cxx
@@ -37,10 +37,11 @@
 #include <editeng/adjustitem.hxx>
 #include <editeng/outlobj.hxx>
 #include <editeng/editobj.hxx>
+#include <comphelper/base64.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 #include <undo/undomanager.hxx>
 #include <GraphicViewShell.hxx>
 #include <sdpage.hxx>
-#include <comphelper/base64.hxx>
 #include <LayerTabBar.hxx>
 #include <vcl/event.hxx>
 #include <vcl/keycodes.hxx>
@@ -286,7 +287,8 @@ void SdMiscTest::testFillGradient()
     CPPUNIT_ASSERT(xPropSet2->getPropertyValue("FillGradient") >>= aGradient2);
 
     // MCGR: Use the completely imported gradient to check for correctness
-    const basegfx::BColorStops aColorStops(aGradient2.ColorStops);
+    const basegfx::BColorStops aColorStops
+        = model::gradient::getColorStopsFromUno(aGradient2.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
     CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
diff --git a/svx/source/unodraw/XPropertyTable.cxx 
b/svx/source/unodraw/XPropertyTable.cxx
index 4d47a1290281..ed3bf9d0a697 100644
--- a/svx/source/unodraw/XPropertyTable.cxx
+++ b/svx/source/unodraw/XPropertyTable.cxx
@@ -37,6 +37,7 @@
 
 #include <svx/unoapi.hxx>
 #include <basegfx/polygon/b2dpolypolygontools.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 using namespace com::sun::star;
 using namespace ::cppu;
@@ -533,26 +534,9 @@ uno::Reference< container::XNameContainer > 
SvxUnoXGradientTable_createInstance(
 uno::Any SvxUnoXGradientTable::getAny( const XPropertyEntry* pEntry ) const 
noexcept
 {
     const basegfx::BGradient& aBGradient = static_cast<const 
XGradientEntry*>(pEntry)->GetGradient();
-    awt::Gradient2 aGradient;
-    assert(aGradient.ColorStops.get() && "cid#1524745 
aGradient.ColorStops._pSequence won't be null here");
-
-    // standard values
-    aGradient.Style = aBGradient.GetGradientStyle();
-    aGradient.Angle = static_cast<short>(aBGradient.GetAngle());
-    aGradient.Border = aBGradient.GetBorder();
-    aGradient.XOffset = aBGradient.GetXOffset();
-    aGradient.YOffset = aBGradient.GetYOffset();
-    aGradient.StartIntensity = aBGradient.GetStartIntens();
-    aGradient.EndIntensity = aBGradient.GetEndIntens();
-    aGradient.StepCount = aBGradient.GetSteps();
 
-    // for compatibility, still set StartColor/EndColor
-    const basegfx::BColorStops& rBColorStops(aBGradient.GetColorStops());
-    aGradient.StartColor = 
static_cast<sal_Int32>(Color(rBColorStops.front().getStopColor()));
-    aGradient.EndColor = 
static_cast<sal_Int32>(Color(rBColorStops.back().getStopColor()));
-
-    // fill ColorStops to extended Gradient2
-    aGradient.ColorStops = rBColorStops.getAsColorStopSequence();
+    awt::Gradient2 aGradient = model::gradient::createUnoGradient2(aBGradient);
+    assert(aGradient.ColorStops.get() && "cid#1524745 
aGradient.ColorStops._pSequence won't be null here");
 
     return uno::Any(aGradient);
 }
@@ -562,7 +546,7 @@ std::unique_ptr<XPropertyEntry> 
SvxUnoXGradientTable::createEntry(const OUString
     if (!rAny.has<css::awt::Gradient>() || !rAny.has<css::awt::Gradient2>())
         return std::unique_ptr<XPropertyEntry>();
 
-    const basegfx::BGradient aBGradient(rAny);
+    const basegfx::BGradient aBGradient = model::gradient::getFromAny(rAny);
     return std::make_unique<XGradientEntry>(aBGradient, rName);
 }
 
diff --git a/svx/source/xoutdev/xattr.cxx b/svx/source/xoutdev/xattr.cxx
index 09d76415f11c..c7e1fed33ac2 100644
--- a/svx/source/xoutdev/xattr.cxx
+++ b/svx/source/xoutdev/xattr.cxx
@@ -36,6 +36,7 @@
 #include <o3tl/any.hxx>
 #include <svl/itempool.hxx>
 #include <editeng/memberids.h>
+#include <docmodel/uno/UnoGradientTools.hxx>
 #include <docmodel/uno/UnoComplexColor.hxx>
 #include <docmodel/color/ComplexColorJSON.hxx>
 #include <tools/mapunit.hxx>
@@ -2200,7 +2201,7 @@ bool XFillGradientItem::QueryValue( css::uno::Any& rVal, 
sal_uInt8 nMemberId ) c
         case 0:
         {
             // fill values
-            const css::awt::Gradient2 
aGradient2(GetGradientValue().getAsGradient2());
+            const css::awt::Gradient2 aGradient2 = 
model::gradient::createUnoGradient2(GetGradientValue());
 
             // create sequence
             uno::Sequence< beans::PropertyValue > aPropSeq{
@@ -2214,7 +2215,7 @@ bool XFillGradientItem::QueryValue( css::uno::Any& rVal, 
sal_uInt8 nMemberId ) c
         case MID_FILLGRADIENT:
         {
             // fill values
-            const css::awt::Gradient2 
aGradient2(GetGradientValue().getAsGradient2());
+            const css::awt::Gradient2 aGradient2 = 
model::gradient::createUnoGradient2(GetGradientValue());
 
             // create sequence
             rVal <<= aGradient2;
@@ -2230,8 +2231,7 @@ bool XFillGradientItem::QueryValue( css::uno::Any& rVal, 
sal_uInt8 nMemberId ) c
         case MID_GRADIENT_COLORSTOPSEQUENCE:
         {
             // fill values
-            const css::awt::ColorStopSequence aColorStopSequence(
-                GetGradientValue().GetColorStops().getAsColorStopSequence());
+            const css::awt::ColorStopSequence aColorStopSequence = 
model::gradient::createColorStopSequence(GetGradientValue().GetColorStops());
 
             // create sequence
             rVal <<= aColorStopSequence;
@@ -2282,8 +2282,7 @@ bool XFillGradientItem::PutValue( const css::uno::Any& 
rVal, sal_uInt8 nMemberId
 
                 if (aGradientAny.hasValue() && 
(aGradientAny.has<css::awt::Gradient>() || 
aGradientAny.has<css::awt::Gradient2>()))
                 {
-                    const basegfx::BGradient aBGradient(aGradientAny);
-                    SetGradientValue(aBGradient);
+                    
SetGradientValue(model::gradient::getFromAny(aGradientAny));
                 }
 
                 return true;
@@ -2305,8 +2304,7 @@ bool XFillGradientItem::PutValue( const css::uno::Any& 
rVal, sal_uInt8 nMemberId
         {
             if (rVal.hasValue() && (rVal.has<css::awt::Gradient>() || 
rVal.has<css::awt::Gradient2>()))
             {
-                const basegfx::BGradient aBGradient(rVal);
-                SetGradientValue(aBGradient);
+                SetGradientValue(model::gradient::getFromAny(rVal));
             }
 
             break;
@@ -2317,7 +2315,8 @@ bool XFillGradientItem::PutValue( const css::uno::Any& 
rVal, sal_uInt8 nMemberId
             // check if we have a awt::ColorStopSequence
             if (rVal.hasValue() && rVal.has<css::awt::ColorStopSequence>())
             {
-                const basegfx::BColorStops aColorStops(rVal);
+
+                const basegfx::BColorStops aColorStops = 
model::gradient::getColorStopsFromAny(rVal);
 
                 if (!aColorStops.empty())
                 {
diff --git a/sw/CppunitTest_sw_odfexport.mk b/sw/CppunitTest_sw_odfexport.mk
index a8c175021c3b..0ba20a09326b 100644
--- a/sw/CppunitTest_sw_odfexport.mk
+++ b/sw/CppunitTest_sw_odfexport.mk
@@ -21,6 +21,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_odfexport, \
     comphelper \
     cppu \
     cppuhelper \
+    docmodel \
     sal \
        sfx \
        subsequenttest \
diff --git a/sw/qa/extras/odfexport/odfexport.cxx 
b/sw/qa/extras/odfexport/odfexport.cxx
index 4acb18d36025..bd18ac7a0034 100644
--- a/sw/qa/extras/odfexport/odfexport.cxx
+++ b/sw/qa/extras/odfexport/odfexport.cxx
@@ -52,6 +52,7 @@
 #include <vcl/filter/PDFiumLibrary.hxx>
 #include <comphelper/scopeguard.hxx>
 #include <basegfx/utils/gradienttools.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 #include <docufld.hxx> // for SwHiddenTextField::ParseIfFieldDefinition() 
method call
 #include <unoprnms.hxx>
@@ -790,7 +791,7 @@ DECLARE_ODFEXPORT_TEST(testTextframeGradient, 
"textframe-gradient.odt")
     awt::Gradient2 aGradient = getProperty<awt::Gradient2>(xFrame, 
"FillGradient");
 
     // MCGR: Use the completely imported gradient to check for correctness
-    basegfx::BColorStops aColorStops(aGradient.ColorStops);
+    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));
@@ -804,7 +805,7 @@ DECLARE_ODFEXPORT_TEST(testTextframeGradient, 
"textframe-gradient.odt")
     aGradient = getProperty<awt::Gradient2>(xFrame, "FillGradient");
 
     // MCGR: Use the completely imported gradient to check for correctness
-    aColorStops = basegfx::BColorStops(aGradient.ColorStops);
+    aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(2), aColorStops.size());
     CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
index 607feea76ac7..11738928041b 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport2.cxx
@@ -33,6 +33,7 @@
 
 #include <oox/drawingml/drawingmltypes.hxx>
 #include <basegfx/utils/gradienttools.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 class Test : public SwModelTestBase
 {
@@ -571,7 +572,7 @@ DECLARE_OOXMLEXPORT_TEST(testTextframeGradient, 
"textframe-gradient.docx")
     awt::Gradient2 aGradient(getProperty<awt::Gradient2>(xFrame, 
"FillGradient"));
 
     // MCGR: Use the completely imported transparency gradient to check for 
correctness
-    basegfx::BColorStops aColorStops(aGradient.ColorStops);
+    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));
@@ -587,7 +588,7 @@ DECLARE_OOXMLEXPORT_TEST(testTextframeGradient, 
"textframe-gradient.docx")
     aGradient = getProperty<awt::Gradient2>(xFrame, "FillGradient");
 
     // MCGR: Use the completely imported transparency gradient to check for 
correctness
-    aColorStops = basegfx::BColorStops(aGradient.ColorStops);
+    aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size());
     CPPUNIT_ASSERT(basegfx::fTools::equal(aColorStops[0].getStopOffset(), 
0.0));
diff --git a/sw/qa/extras/rtfexport/rtfexport.cxx 
b/sw/qa/extras/rtfexport/rtfexport.cxx
index 341e688bad8e..0f1ea5e695ea 100644
--- a/sw/qa/extras/rtfexport/rtfexport.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport.cxx
@@ -31,6 +31,7 @@
 
 #include <tools/UnitConversion.hxx>
 #include <basegfx/utils/gradienttools.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 using namespace css;
 
@@ -622,7 +623,7 @@ DECLARE_RTFEXPORT_TEST(testTextframeGradient, 
"textframe-gradient.rtf")
     const basegfx::BColor aColD(0.0, 0.0, 0.0);
 
     // MCGR: Use the completely imported transparency gradient to check for 
correctness
-    basegfx::BColorStops aColorStops(aGradient.ColorStops);
+    basegfx::BColorStops aColorStops = 
model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size());
     CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style);
@@ -639,7 +640,7 @@ DECLARE_RTFEXPORT_TEST(testTextframeGradient, 
"textframe-gradient.rtf")
     aGradient = getProperty<awt::Gradient2>(xFrame, "FillGradient");
 
     // MCGR: Use the completely imported transparency gradient to check for 
correctness
-    aColorStops = basegfx::BColorStops(aGradient.ColorStops);
+    aColorStops = model::gradient::getColorStopsFromUno(aGradient.ColorStops);
 
     CPPUNIT_ASSERT_EQUAL(size_t(3), aColorStops.size());
     CPPUNIT_ASSERT_EQUAL(awt::GradientStyle_LINEAR, aGradient.Style);
diff --git a/sw/rtfexport_setup.mk b/sw/rtfexport_setup.mk
index c24cb812a9ef..a2a1c7109cca 100644
--- a/sw/rtfexport_setup.mk
+++ b/sw/rtfexport_setup.mk
@@ -24,6 +24,7 @@ $(eval $(call gb_CppunitTest_use_libraries,sw_rtfexport$(1), \
     comphelper \
     cppu \
     cppuhelper \
+    docmodel \
     i18nlangtag \
     sal \
     sfx \
diff --git a/xmloff/source/style/GradientStyle.cxx 
b/xmloff/source/style/GradientStyle.cxx
index d80b3f866482..29a277a79bef 100644
--- a/xmloff/source/style/GradientStyle.cxx
+++ b/xmloff/source/style/GradientStyle.cxx
@@ -35,6 +35,7 @@
 #include <xmloff/xmltoken.hxx>
 #include <xmloff/xmluconv.hxx>
 #include <basegfx/utils/bgradient.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 using namespace ::com::sun::star;
 using namespace ::xmloff::token;
@@ -226,7 +227,7 @@ void XMLGradientStyleExport::exportXML(
     if (!rValue.has<css::awt::Gradient2>() && 
!rValue.has<css::awt::Gradient>())
         return;
 
-    basegfx::BGradient aGradient(rValue);
+    basegfx::BGradient aGradient = model::gradient::getFromAny(rValue);
 
     // Export of axial gradient to OOXML produces a symmetrical linear 
multi-color gradient. Import
     // does not regenerate it as 'axial' because that is not needed for MCGR. 
For export to ODF we
diff --git a/xmloff/source/style/TransGradientStyle.cxx 
b/xmloff/source/style/TransGradientStyle.cxx
index 3e89edb683f5..74b7670c024f 100644
--- a/xmloff/source/style/TransGradientStyle.cxx
+++ b/xmloff/source/style/TransGradientStyle.cxx
@@ -35,6 +35,7 @@
 #include <xmloff/xmlnamespace.hxx>
 #include <xmloff/xmltkmap.hxx>
 #include <xmloff/xmluconv.hxx>
+#include <docmodel/uno/UnoGradientTools.hxx>
 
 using namespace ::com::sun::star;
 
@@ -178,7 +179,7 @@ void XMLTransGradientStyleExport::exportXML(
     if (!rValue.has<css::awt::Gradient2>() && 
!rValue.has<css::awt::Gradient>())
         return;
 
-    basegfx::BGradient aGradient(rValue);
+    basegfx::BGradient aGradient = model::gradient::getFromAny(rValue);
 
     aGradient.tryToConvertToAxial();
 

Reply via email to