MCGR: Model data changes for ColorSteps

Added tooling replaceStart/EndColor to allow simple
transition for code that does not immediately adapt
to multi color gradients. Also added
createColorStepsFromStartEndColor for the same
purpose.

Adapted XGradient to no longer have Start/EndColor
at all, but only use ColorSteps.

Adapted all usages of XGradient to no longer use
Get/Set/Start/EndColor, but access the ColorSteps
instead.

Replaced quite some XGradient constructors that
used XGradient() as Start/EndColor since this is
already the default.

Adapted ColorBlending to black AKA Start/EndIntens
in XGradient to work now on all ColorSteps in the
required linearly-scaled manner.

UNO API changes:

Added com::sun::star::awt::ColorStep as basic data
element that holds a pair of Offset and Color.

Added com::sun::star::awt::ColorStepSequence to
handle an array of sorted entries.

Added com::sun::star::awt::Gradient2 derived from
com::sun::star::awt::Gradient, extended by the
needed com::sun::star::awt::ColorStepSequence.

Added MID_GRADIENT_COLORSTEPSEQUENCE to UNO API
to provide access to ColorSteps directly.

Adapted XFillGradientItem::QueryValue/PutValue to
make use of new UNO API data structures. To do so,
added tooling methods for data transition:
    - fillColorStepSequenceFromColorSteps
    - fillGradient2FromXGradient
    - fillColorStepsFromAny
    - fillXGradientFromAny
and adapted
    - case '0' (all data)
    - MID_FILLGRADIENT
    - MID_GRADIENT_COLORSTEPSEQUENCE
    - MID_GRADIENT_START/ENDCOLOR
to make use of these.

Tested usage of these in the office.

Renamed from GradientStep to GradientStop after
discussions with members on the list to make this
closer related to other norms/definitions.

Also renamed classes and class members to better
reflect to GradientStop, so grepping/finding will
be easier (e.g. 'Color' just exists pretty often,
but 'StopColor' is more precise).

Changed the used UNO API class for reprsenting the
Color to better reflect to ranges [0.0 .. 1.0] and
usage of RGB.

Change-Id: I1eeb3e97e81d6785967615d1ff256551fc3b882d
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148849
Tested-by: Jenkins
Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
diff --git a/basegfx/source/tools/gradienttools.cxx b/basegfx/source/tools/gradienttools.cxx
index 0bb45ba..d43f789 100644
--- a/basegfx/source/tools/gradienttools.cxx
+++ b/basegfx/source/tools/gradienttools.cxx
@@ -21,6 +21,7 @@
#include <basegfx/point/b2dpoint.hxx>
#include <basegfx/range/b2drange.hxx>
#include <basegfx/matrix/b2dhommatrixtools.hxx>
#include <com/sun/star/awt/Gradient2.hpp>

#include <algorithm>
#include <cmath>
@@ -263,19 +264,123 @@ namespace basegfx

    namespace utils
    {
        /* Tooling method to convert UNO API data to ColorStops
           This will try to extract ColorStop data from the given
           Any, so if it's of type awt::Gradient2 that data will be
           extracted, converted and copied into the given ColorStops.
        */
        void fillColorStopsFromAny(ColorStops& rColorStops, const css::uno::Any& rVal)
        {
            css::awt::Gradient2 aGradient2;
            if (!(rVal >>= aGradient2))
                return;

            const sal_Int32 nLen(aGradient2.ColorStops.getLength());

            if (0 == nLen)
                return;

            // we have ColorStops
            rColorStops.clear();
            rColorStops.reserve(nLen);
            const css::awt::ColorStop* pSourceColorStop(aGradient2.ColorStops.getConstArray());

            for (sal_Int32 a(0); a < nLen; a++, pSourceColorStop++)
            {
                rColorStops.emplace_back(
                    pSourceColorStop->StopOffset,
                    BColor(pSourceColorStop->StopColor.Red, pSourceColorStop->StopColor.Green, pSourceColorStop->StopColor.Blue));
            }
        }

        /* Tooling method to fill a awt::ColorStopSequence with
           the data from the given ColorStops. This is used in
           UNO API implementations.
        */
        void fillColorStopSequenceFromColorStops(css::awt::ColorStopSequence& rColorStopSequence, const ColorStops& rColorStops)
        {
            // fill ColorStops to extended Gradient2
            rColorStopSequence.realloc(rColorStops.size());
            css::awt::ColorStop* pTargetColorStop(rColorStopSequence.getArray());

            for (const auto& candidate : rColorStops)
            {
                pTargetColorStop->StopOffset = candidate.getStopOffset();
                pTargetColorStop->StopColor = css::rendering::RGBColor(
                    candidate.getStopColor().getRed(),
                    candidate.getStopColor().getGreen(),
                    candidate.getStopColor().getBlue());
                pTargetColorStop++;
            }
        }

        /* Tooling method that allows to replace the StartColor in a
           vector of ColorStops. A vector in 'ordered state' is expected,
           so you may use/have used sortAndCorrectColorStops, see below.
           This method is for convenience & backwards compatibility, please
           think about handling multi-colored gradients directly.
        */
        void replaceStartColor(ColorStops& rColorStops, const BColor& rStart)
        {
            ColorStops::iterator a1stNonStartColor(rColorStops.begin());

            // search for highest existing non-StartColor
            while (a1stNonStartColor != rColorStops.end() && basegfx::fTools::lessOrEqual(a1stNonStartColor->getStopOffset(), 0.0))
                a1stNonStartColor++;

            // create new ColorStops by 1st adding new one and then all
            // non-StartColor entries
            ColorStops aNewColorStops;

            aNewColorStops.reserve(rColorStops.size() + 1);
            aNewColorStops.emplace_back(0.0, rStart);
            aNewColorStops.insert(aNewColorStops.end(), a1stNonStartColor, rColorStops.end());

            // assign & done
            rColorStops = aNewColorStops;
        }

        /* Tooling method that allows to replace the EndColor in a
           vector of ColorStops. A vector in 'ordered state' is expected,
           so you may use/have used sortAndCorrectColorStops, see below.
           This method is for convenience & backwards compatibility, please
           think about handling multi-colored gradients directly.
        */
        void replaceEndColor(ColorStops& rColorStops, const BColor& rEnd)
        {
            // erase all evtl. existing EndColor(s)
            while (!rColorStops.empty() && basegfx::fTools::moreOrEqual(rColorStops.back().getStopOffset(), 1.0))
                rColorStops.pop_back();

            // add at the end of existing ColorStops
            rColorStops.emplace_back(1.0, rEnd);
        }

        // Tooling method to quickly create a ColorStop vector for a given set of Start/EndColor
        ColorStops createColorStopsFromStartEndColor(const BColor& rStart, const BColor& rEnd)
        {
            return ColorStops {
                ColorStop(0.0, rStart),
                ColorStop(1.0, rEnd) };
        }

        /* Tooling method to guarantee sort and correctness for
           the given ColorSteps vector.
           the given ColorStops vector.
           A vector fulfilling these conditions is called to be
           in 'ordered state'.

           At return, the following conditions are guaranteed:
           - contains no ColorSteps with offset < 0.0 (will
           - contains no ColorStops with offset < 0.0 (will
             be removed)
           - contains no ColorSteps with offset > 0.0 (will
           - contains no ColorStops with offset > 1.0 (will
             be removed)
           - contains no ColorSteps with identical offset
             (will be removed, 1st one wins)
           - contains no two ColorStops with identical offsets
             (will be removed, 1st one/smallest offset wins
             which is also given by sort tooling)
           - will be sorted from lowest offset to highest
           - if all colors are the same, the content will
             be reduced to a single entry with offset 0.0
             (StartColor)
             (force to StartColor)

           Some more notes:
           - It can happen that the result is empty
@@ -283,30 +388,30 @@ namespace basegfx
             the same color, this represents single-color
             regions inside the gradient
           - A entry with 0.0 is not required or forced, so
             no 'StartColor' is required on this level
             no 'StartColor' is technically required
           - A entry with 1.0 is not required or forced, so
             no 'EndColor' is required on this level
             no 'EndColor' is technically required

           All this is done in one run (sort + O(N)) without
           creating a copy of the data in any form
        */
        void sortAndCorrectColorSteps(ColorSteps& rColorSteps)
        void sortAndCorrectColorStops(ColorStops& rColorStops)
        {
            // no content, we are done
            if (rColorSteps.empty())
            if (rColorStops.empty())
                return;

            if (1 == rColorSteps.size())
            if (1 == rColorStops.size())
            {
                // no gradient at all, but preserve given color
                // and force it to be the StartColor
                rColorSteps[0] = ColorStep(0.0, rColorSteps[0].getColor());
                rColorStops[0] = ColorStop(0.0, rColorStops[0].getStopColor());
            }

            // start with sorting the input data. Remember that
            // this preserves the order of equal entries, where
            // equal is defined here by offset (see use operator==)
            std::sort(rColorSteps.begin(), rColorSteps.end());
            std::sort(rColorStops.begin(), rColorStops.end());

            // prepare status values
            bool bSameColorInit(false);
@@ -318,10 +423,10 @@ namespace basegfx
            // and write with write <= read all the time. Step over the
            // data using read and check for valid entry. If valid, decide
            // how to keep it
            for (size_t read(0); read < rColorSteps.size(); read++)
            for (size_t read(0); read < rColorStops.size(); read++)
            {
                // get offset of entry at read position
                const double rOff(rColorSteps[read].getOffset());
                const double rOff(rColorStops[read].getStopOffset());

                // step over < 0 values
                if (basegfx::fTools::less(rOff, 0.0))
@@ -338,23 +443,23 @@ namespace basegfx
                if(bSameColorInit)
                {
                    // already initialized, compare
                    bAllTheSameColor = bAllTheSameColor && aFirstColor == rColorSteps[read].getColor();
                    bAllTheSameColor = bAllTheSameColor && aFirstColor == rColorStops[read].getStopColor();
                }
                else
                {
                    // do initialize, remember 1st valid color
                    bSameColorInit = true;
                    aFirstColor = rColorSteps[read].getColor();
                    aFirstColor = rColorStops[read].getStopColor();
                }

                // copy if write target is empty (write at start) or when
                // write target is different to read
                if (0 == write || rOff != rColorSteps[write-1].getOffset())
                if (0 == write || rOff != rColorStops[write-1].getStopOffset())
                {
                    if (write != read)
                    {
                        // copy read to write backwards to close gaps
                        rColorSteps[write] = rColorSteps[read];
                        rColorStops[write] = rColorStops[read];
                    }

                    // always forward write position
@@ -364,44 +469,44 @@ namespace basegfx

            // correct size when length is reduced. write is always at
            // last used position + 1
            if (rColorSteps.size() > write)
            if (rColorStops.size() > write)
            {
                rColorSteps.resize(write);
                rColorStops.resize(write);
            }

            if (bSameColorInit && bAllTheSameColor && rColorSteps.size() > 1)
            if (bSameColorInit && bAllTheSameColor && rColorStops.size() > 1)
            {
                // id all-the-same color is detected, reset to single
                // entry, but also force to StartColor and preserve the color
                rColorSteps.resize(1);
                rColorSteps[0] = ColorStep(0.0, aFirstColor);
                rColorStops.resize(1);
                rColorStops[0] = ColorStop(0.0, aFirstColor);
            }
        }

        BColor modifyBColor(
            const ColorSteps& rColorSteps,
            const ColorStops& rColorStops,
            double fScaler,
            sal_uInt32 nRequestedSteps)
        {
            // no color at all, done
            if (rColorSteps.empty())
            if (rColorStops.empty())
                return BColor();

            // outside range -> at start
            if (fScaler <= 0.0)
                return rColorSteps.front().getColor();
                return rColorStops.front().getStopColor();

            // outside range -> at end
            if (fScaler >= 1.0)
                return rColorSteps.back().getColor();
                return rColorStops.back().getStopColor();

            // special case for the 'classic' case with just two colors:
            // we can optimize that and keep the speed/resources low
            // by avoiding some calculations and an O(log(N)) array access
            if (2 == rColorSteps.size())
            if (2 == rColorStops.size())
            {
                const basegfx::BColor aCStart(rColorSteps.front().getColor());
                const basegfx::BColor aCEnd(rColorSteps.back().getColor());
                const basegfx::BColor aCStart(rColorStops.front().getStopColor());
                const basegfx::BColor aCEnd(rColorStops.back().getStopColor());
                const sal_uInt32 nSteps(
                    calculateNumberOfSteps(
                        nRequestedSteps,
@@ -421,25 +526,25 @@ namespace basegfx
            //       all is good/fast as expected
            const auto upperBound(
                std::lower_bound(
                    rColorSteps.begin(),
                    rColorSteps.end(),
                    ColorStep(fScaler),
                    [](const ColorStep& x, const ColorStep& y) { return x.getOffset() < y.getOffset(); }));
                    rColorStops.begin(),
                    rColorStops.end(),
                    ColorStop(fScaler),
                    [](const ColorStop& x, const ColorStop& y) { return x.getStopOffset() < y.getStopOffset(); }));

            // no upper bound, done
            if (rColorSteps.end() == upperBound)
                return rColorSteps.back().getColor();
            if (rColorStops.end() == upperBound)
                return rColorStops.back().getStopColor();

            // lower bound is one entry back
            const auto lowerBound(upperBound - 1);

            // no lower bound, done
            if (rColorSteps.end() == lowerBound)
                return rColorSteps.back().getColor();
            if (rColorStops.end() == lowerBound)
                return rColorStops.back().getStopColor();

            // we have lower and upper bound, get colors
            const BColor aCStart(lowerBound->getColor());
            const BColor aCEnd(upperBound->getColor());
            const BColor aCStart(lowerBound->getStopColor());
            const BColor aCEnd(upperBound->getStopColor());

            // when there are just two color steps this cannot happen, but when using
            // a range of colors this *may* be used inside the range to represent
@@ -456,8 +561,8 @@ namespace basegfx

            // get offsets and scale to new [0.0 .. 1.0] relative range for
            // partial outer range
            const double fOffsetStart(lowerBound->getOffset());
            const double fOffsetEnd(upperBound->getOffset());
            const double fOffsetStart(lowerBound->getStopOffset());
            const double fOffsetEnd(upperBound->getStopOffset());
            const double fAdaptedScaler((fScaler - fOffsetStart) / (fOffsetEnd - fOffsetStart));

            // interpolate & evtl. apply steps
diff --git a/chart2/source/controller/main/ChartController_Tools.cxx b/chart2/source/controller/main/ChartController_Tools.cxx
index e2f11c7..8cd3fd9 100644
--- a/chart2/source/controller/main/ChartController_Tools.cxx
+++ b/chart2/source/controller/main/ChartController_Tools.cxx
@@ -972,9 +972,10 @@ void ChartController::executeDispatch_FillGradient(std::u16string_view sJSONGrad

            if( xPropSet.is() )
            {
                OUString aPrefferedName = OUString::number(static_cast<sal_Int32>(aXGradient.GetStartColor()))
                                + OUString::number(static_cast<sal_Int32>(aXGradient.GetEndColor()))
                                + OUString::number(static_cast<sal_Int32>(aXGradient.GetAngle().get()));
                OUString aPrefferedName =
                    OUString::number(static_cast<sal_Int32>(Color(aXGradient.GetColorStops().front().getStopColor())))
                    + OUString::number(static_cast<sal_Int32>(Color(aXGradient.GetColorStops().back().getStopColor())))
                    + OUString::number(static_cast<sal_Int32>(aXGradient.GetAngle().get()));

                OUString aNewName = PropertyHelper::addGradientUniqueNameToTable(css::uno::Any(aGradient),
                                        xChartModel,
diff --git a/cui/source/tabpages/tpgradnt.cxx b/cui/source/tabpages/tpgradnt.cxx
index 31a846d..dfe59e8 100644
--- a/cui/source/tabpages/tpgradnt.cxx
+++ b/cui/source/tabpages/tpgradnt.cxx
@@ -34,6 +34,7 @@
#include <dialmgr.hxx>
#include <svx/dialmgr.hxx>
#include <svx/strings.hrc>
#include <basegfx/utils/gradienttools.hxx>
#include <sal/log.hxx>

#define DEFAULT_GRADIENTSTEP 64
@@ -83,7 +84,8 @@ SvxGradientTabPage::SvxGradientTabPage(weld::Container* pPage, weld::DialogContr

    // setting the output device
    m_rXFSet.Put( XFillStyleItem(drawing::FillStyle_GRADIENT) );
    m_rXFSet.Put( XFillGradientItem(OUString(), XGradient( COL_BLACK, COL_WHITE )) );
    // XGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
    m_rXFSet.Put( XFillGradientItem(OUString(), XGradient()));
    m_aCtlPreview.SetAttributes(m_aXFillAttr.GetItemSet());

    // set handler
@@ -194,8 +196,10 @@ bool SvxGradientTabPage::FillItemSet( SfxItemSet* rSet )
    else
    // gradient was passed (unidentified)
    {
        pXGradient.reset(new XGradient( m_xLbColorFrom->GetSelectEntryColor(),
                    m_xLbColorTo->GetSelectEntryColor(),
        pXGradient.reset(new XGradient(
                    basegfx::utils::createColorStopsFromStartEndColor(
                        m_xLbColorFrom->GetSelectEntryColor().getBColor(),
                        m_xLbColorTo->GetSelectEntryColor().getBColor()),
                    static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
                    Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
                    static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
@@ -292,8 +296,10 @@ void SvxGradientTabPage::ModifiedHdl_Impl( void const * pControl )

    css::awt::GradientStyle eXGS = static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active());

    XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
                          m_xLbColorTo->GetSelectEntryColor(),
    XGradient aXGradient(
                          basegfx::utils::createColorStopsFromStartEndColor(
                              m_xLbColorFrom->GetSelectEntryColor().getBColor(),
                              m_xLbColorTo->GetSelectEntryColor().getBColor()),
                          eXGS,
                          Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
                          static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
@@ -359,8 +365,10 @@ IMPL_LINK_NOARG(SvxGradientTabPage, ClickAddHdl_Impl, weld::Button&, void)

    if( !nError )
    {
        XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
                              m_xLbColorTo->GetSelectEntryColor(),
        XGradient aXGradient(
                            basegfx::utils::createColorStopsFromStartEndColor(
                                m_xLbColorFrom->GetSelectEntryColor().getBColor(),
                                m_xLbColorTo->GetSelectEntryColor().getBColor()),
                              static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
                              Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
                              static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
@@ -399,8 +407,10 @@ IMPL_LINK_NOARG(SvxGradientTabPage, ClickModifyHdl_Impl, weld::Button&, void)

    OUString aName( m_pGradientList->GetGradient( static_cast<sal_uInt16>(nPos) )->GetName() );

    XGradient aXGradient( m_xLbColorFrom->GetSelectEntryColor(),
                          m_xLbColorTo->GetSelectEntryColor(),
    XGradient aXGradient(
                          basegfx::utils::createColorStopsFromStartEndColor(
                              m_xLbColorFrom->GetSelectEntryColor().getBColor(),
                              m_xLbColorTo->GetSelectEntryColor().getBColor()),
                          static_cast<css::awt::GradientStyle>(m_xLbGradientType->get_active()),
                          Degree10(static_cast<sal_Int16>(m_xMtrAngle->get_value(FieldUnit::NONE) * 10)), // should be changed in resource
                          static_cast<sal_uInt16>(m_xMtrCenterX->get_value(FieldUnit::NONE)),
@@ -542,10 +552,10 @@ void SvxGradientTabPage::ChangeGradientHdl_Impl()
    // if the entry is not in the listbox,
    // colors are added temporarily
    m_xLbColorFrom->SetNoSelection();
    m_xLbColorFrom->SelectEntry( pGradient->GetStartColor() );
    m_xLbColorFrom->SelectEntry(Color(pGradient->GetColorStops().front().getStopColor()));

    m_xLbColorTo->SetNoSelection();
    m_xLbColorTo->SelectEntry( pGradient->GetEndColor() );
    m_xLbColorTo->SelectEntry(Color(pGradient->GetColorStops().back().getStopColor()));

    m_xMtrAngle->set_value(pGradient->GetAngle().get() / 10, FieldUnit::NONE); // should be changed in resource
    m_xSliderAngle->set_value(pGradient->GetAngle().get() / 10);
diff --git a/cui/source/tabpages/tptrans.cxx b/cui/source/tabpages/tptrans.cxx
index 7518002..259446e 100644
--- a/cui/source/tabpages/tptrans.cxx
+++ b/cui/source/tabpages/tptrans.cxx
@@ -122,8 +122,9 @@ void SvxTransparenceTabPage::ModifiedTrgrHdl_Impl(const weld::ComboBox* pControl
    sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
    sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
    XGradient aTmpGradient(
                Color(nStartCol, nStartCol, nStartCol),
                Color(nEndCol, nEndCol, nEndCol),
                basegfx::utils::createColorStopsFromStartEndColor(
                    Color(nStartCol, nStartCol, nStartCol).getBColor(),
                    Color(nEndCol, nEndCol, nEndCol).getBColor()),
                static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active()),
                Degree10(static_cast<sal_Int16>(m_xMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10),
                static_cast<sal_uInt16>(m_xMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
@@ -293,8 +294,9 @@ bool SvxTransparenceTabPage::FillItemSet(SfxItemSet* rAttrs)
            sal_uInt8 nStartCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrStartValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
            sal_uInt8 nEndCol = static_cast<sal_uInt8>((static_cast<sal_uInt16>(m_xMtrTrgrEndValue->get_value(FieldUnit::PERCENT)) * 255) / 100);
            XGradient aTmpGradient(
                        Color(nStartCol, nStartCol, nStartCol),
                        Color(nEndCol, nEndCol, nEndCol),
                        basegfx::utils::createColorStopsFromStartEndColor(
                            Color(nStartCol, nStartCol, nStartCol).getBColor(),
                            Color(nEndCol, nEndCol, nEndCol).getBColor()),
                        static_cast<css::awt::GradientStyle>(m_xLbTrgrGradientType->get_active()),
                        Degree10(static_cast<sal_Int16>(m_xMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10),
                        static_cast<sal_uInt16>(m_xMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
@@ -323,9 +325,10 @@ bool SvxTransparenceTabPage::FillItemSet(SfxItemSet* rAttrs)
    // disable unused XFillFloatTransparenceItem
    if(bSwitchOffGradient && (bGradActive || bGradUsed))
    {
        XGradient aGrad(COL_BLACK, COL_WHITE);
        aGrad.SetStartIntens(100);
        aGrad.SetEndIntens(100);
        // XGradient() default already creates [COL_BLACK, COL_WHITE] with same defaults
        // XGradient() default also sets the Start/EndIntensity to 100 already
        XGradient aGrad;

        XFillFloatTransparenceItem aItem(aGrad);
        aItem.SetEnabled(false);
        rAttrs->Put(aItem);
@@ -367,8 +370,10 @@ void SvxTransparenceTabPage::Reset(const SfxItemSet* rAttrs)
    m_xMtrTrgrBorder->set_value(rGradient.GetBorder(), FieldUnit::PERCENT);
    m_xMtrTrgrCenterX->set_value(rGradient.GetXOffset(), FieldUnit::PERCENT);
    m_xMtrTrgrCenterY->set_value(rGradient.GetYOffset(), FieldUnit::PERCENT);
    m_xMtrTrgrStartValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetStartColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
    m_xMtrTrgrEndValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetEndColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
    const Color aStart(rGradient.GetColorStops().front().getStopColor());
    const Color aEnd(rGradient.GetColorStops().back().getStopColor());
    m_xMtrTrgrStartValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aStart.GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
    m_xMtrTrgrEndValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aEnd.GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);

    // linear transparence
    sal_uInt16 nTransp = pLinearItem->GetValue();
diff --git a/drawinglayer/inc/texture/texture.hxx b/drawinglayer/inc/texture/texture.hxx
index 567a244..8eff5be 100644
--- a/drawinglayer/inc/texture/texture.hxx
+++ b/drawinglayer/inc/texture/texture.hxx
@@ -57,14 +57,14 @@ namespace drawinglayer::texture
            basegfx::ODFGradientInfo            maGradientInfo;
            basegfx::B2DRange                   maDefinitionRange;
            sal_uInt32                          mnRequestedSteps;
            basegfx::ColorSteps                 mnColorSteps;
            basegfx::ColorStops                 mnColorStops;
            double                              mfBorder;

        public:
            GeoTexSvxGradient(
                const basegfx::B2DRange& rDefinitionRange,
                sal_uInt32 nRequestedSteps,
                const basegfx::ColorSteps& rColorSteps,
                const basegfx::ColorStops& rColorStops,
                double fBorder);
            virtual ~GeoTexSvxGradient() override;

@@ -88,7 +88,7 @@ namespace drawinglayer::texture
                const basegfx::B2DRange& rDefinitionRange,
                const basegfx::B2DRange& rOutputRange,
                sal_uInt32 nRequestedSteps,
                const basegfx::ColorSteps& rColorSteps,
                const basegfx::ColorStops& rColorStops,
                double fBorder,
                double fAngle);
            virtual ~GeoTexSvxGradientLinear() override;
@@ -109,7 +109,7 @@ namespace drawinglayer::texture
                const basegfx::B2DRange& rDefinitionRange,
                const basegfx::B2DRange& rOutputRange,
                sal_uInt32 nRequestedSteps,
                const basegfx::ColorSteps& rColorSteps,
                const basegfx::ColorStops& rColorStops,
                double fBorder,
                double fAngle);
            virtual ~GeoTexSvxGradientAxial() override;
@@ -126,7 +126,7 @@ namespace drawinglayer::texture
            GeoTexSvxGradientRadial(
                const basegfx::B2DRange& rDefinitionRange,
                sal_uInt32 nRequestedSteps,
                const basegfx::ColorSteps& rColorSteps,
                const basegfx::ColorStops& rColorStops,
                double fBorder,
                double fOffsetX,
                double fOffsetY);
@@ -144,7 +144,7 @@ namespace drawinglayer::texture
            GeoTexSvxGradientElliptical(
                const basegfx::B2DRange& rDefinitionRange,
                sal_uInt32 nRequestedSteps,
                const basegfx::ColorSteps& rColorSteps,
                const basegfx::ColorStops& rColorStops,
                double fBorder,
                double fOffsetX,
                double fOffsetY,
@@ -163,7 +163,7 @@ namespace drawinglayer::texture
            GeoTexSvxGradientSquare(
                const basegfx::B2DRange& rDefinitionRange,
                sal_uInt32 nRequestedSteps,
                const basegfx::ColorSteps& rColorSteps,
                const basegfx::ColorStops& rColorStops,
                double fBorder,
                double fOffsetX,
                double fOffsetY,
@@ -182,7 +182,7 @@ namespace drawinglayer::texture
            GeoTexSvxGradientRect(
                const basegfx::B2DRange& rDefinitionRange,
                sal_uInt32 nRequestedSteps,
                const basegfx::ColorSteps& rColorSteps,
                const basegfx::ColorStops& rColorStops,
                double fBorder,
                double fOffsetX,
                double fOffsetY,
diff --git a/drawinglayer/qa/unit/vclpixelprocessor2d.cxx b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx
index 343556a..4c26c2d 100644
--- a/drawinglayer/qa/unit/vclpixelprocessor2d.cxx
+++ b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx
@@ -60,10 +60,10 @@ public:

        basegfx::B2DRange definitionRange(0, 0, 100, 200);
        basegfx::B2DRange outputRange(0, 100, 100, 200); // Paint only lower half of the gradient.
        const basegfx::ColorSteps aColorSteps{ basegfx::ColorStep(0.0, COL_WHITE.getBColor()),
                                               basegfx::ColorStep(1.0, COL_BLACK.getBColor()) };
        attribute::FillGradientAttribute attributes(attribute::GradientStyle::Linear, 0, 0, 0, 0,
                                                    aColorSteps);
        attribute::FillGradientAttribute attributes(
            attribute::GradientStyle::Linear, 0, 0, 0, 0,
            basegfx::utils::createColorStopsFromStartEndColor(COL_WHITE.getBColor(),
                                                              COL_BLACK.getBColor()));
        rtl::Reference<primitive2d::FillGradientPrimitive2D> gradientPrimitive(
            new primitive2d::FillGradientPrimitive2D(outputRange, definitionRange, attributes));
        primitive2d::Primitive2DContainer primitives;
diff --git a/drawinglayer/source/attribute/fillgradientattribute.cxx b/drawinglayer/source/attribute/fillgradientattribute.cxx
index 3d78273..62bde03 100644
--- a/drawinglayer/source/attribute/fillgradientattribute.cxx
+++ b/drawinglayer/source/attribute/fillgradientattribute.cxx
@@ -30,7 +30,7 @@ namespace drawinglayer::attribute
            double                                  mfOffsetX;
            double                                  mfOffsetY;
            double                                  mfAngle;
            basegfx::ColorSteps                     maColorSteps;
            basegfx::ColorStops                     maColorStops;
            GradientStyle                           meStyle;
            sal_uInt16                              mnSteps;

@@ -40,31 +40,31 @@ namespace drawinglayer::attribute
                double fOffsetX,
                double fOffsetY,
                double fAngle,
                const basegfx::ColorSteps& rColorSteps,
                const basegfx::ColorStops& rColorStops,
                sal_uInt16 nSteps)
            :   mfBorder(fBorder),
                mfOffsetX(fOffsetX),
                mfOffsetY(fOffsetY),
                mfAngle(fAngle),
                maColorSteps(rColorSteps), // copy ColorSteps
                maColorStops(rColorStops), // copy ColorStops
                meStyle(eStyle),
                mnSteps(nSteps)
            {
                // Correct the local ColorSteps. That will guarantee that the
                // Correct the local ColorStops. That will guarantee that the
                // content does contain no offsets < 0.0, > 1.0 or double
                // ones, also secures sorted arrangement and checks for
                // double colors, too (see there for more information).
                // This is what the usages of this in primitives need.
                // Since FillGradientAttribute is read-only doing this
                // once here in the constructor is sufficient
                basegfx::utils::sortAndCorrectColorSteps(maColorSteps);
                basegfx::utils::sortAndCorrectColorStops(maColorStops);

                // sortAndCorrectColorSteps is rigid and can return
                // sortAndCorrectColorStops is rigid and can return
                // an empty result. To keep things simple, add a single
                // fallback value
                if (maColorSteps.empty())
                if (maColorStops.empty())
                {
                    maColorSteps.emplace_back(0.0, basegfx::BColor());
                    maColorStops.emplace_back(0.0, basegfx::BColor());
                }
            }

@@ -73,12 +73,12 @@ namespace drawinglayer::attribute
                mfOffsetX(0.0),
                mfOffsetY(0.0),
                mfAngle(0.0),
                maColorSteps(),
                maColorStops(),
                meStyle(GradientStyle::Linear),
                mnSteps(0)
            {
                // always add a fallback color, see above
                maColorSteps.emplace_back(0.0, basegfx::BColor());
                maColorStops.emplace_back(0.0, basegfx::BColor());
            }

            // data read access
@@ -87,7 +87,7 @@ namespace drawinglayer::attribute
            double getOffsetX() const { return mfOffsetX; }
            double getOffsetY() const { return mfOffsetY; }
            double getAngle() const { return mfAngle; }
            const basegfx::ColorSteps& getColorSteps() const { return maColorSteps; }
            const basegfx::ColorStops& getColorStops() const { return maColorStops; }
            sal_uInt16 getSteps() const { return mnSteps; }

            bool hasSingleColor() const
@@ -96,7 +96,7 @@ namespace drawinglayer::attribute
                // or single entry -> no gradient.
                // No need to check for all-the-same color since this is checked/done
                // in the constructor already, see there
                return maColorSteps.size() < 2;
                return maColorStops.size() < 2;
            }

            bool operator==(const ImpFillGradientAttribute& rCandidate) const
@@ -106,7 +106,7 @@ namespace drawinglayer::attribute
                    && getOffsetX() == rCandidate.getOffsetX()
                    && getOffsetY() == rCandidate.getOffsetY()
                    && getAngle() == rCandidate.getAngle()
                    && getColorSteps() == rCandidate.getColorSteps()
                    && getColorStops() == rCandidate.getColorStops()
                    && getSteps() == rCandidate.getSteps());
            }
        };
@@ -126,10 +126,10 @@ namespace drawinglayer::attribute
            double fOffsetX,
            double fOffsetY,
            double fAngle,
            const basegfx::ColorSteps& rColorSteps,
            const basegfx::ColorStops& rColorStops,
            sal_uInt16 nSteps)
        :   mpFillGradientAttribute(ImpFillGradientAttribute(
                eStyle, fBorder, fOffsetX, fOffsetY, fAngle, rColorSteps, nSteps))
                eStyle, fBorder, fOffsetX, fOffsetY, fAngle, rColorStops, nSteps))
        {
        }

@@ -167,9 +167,9 @@ namespace drawinglayer::attribute
            return rCandidate.mpFillGradientAttribute == mpFillGradientAttribute;
        }

        const basegfx::ColorSteps& FillGradientAttribute::getColorSteps() const
        const basegfx::ColorStops& FillGradientAttribute::getColorStops() const
        {
            return mpFillGradientAttribute->getColorSteps();
            return mpFillGradientAttribute->getColorStops();
        }

        double FillGradientAttribute::getBorder() const
diff --git a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
index a92a5f9..c1246f1 100644
--- a/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
@@ -45,7 +45,7 @@ namespace drawinglayer::primitive2d
                        getDefinitionRange(),
                        getOutputRange(),
                        getFillGradient().getSteps(),
                        getFillGradient().getColorSteps(),
                        getFillGradient().getColorStops(),
                        getFillGradient().getBorder(),
                        getFillGradient().getAngle());
                    aGradient.appendTransformationsAndColors(rEntries, rOuterColor);
@@ -57,7 +57,7 @@ namespace drawinglayer::primitive2d
                        getDefinitionRange(),
                        getOutputRange(),
                        getFillGradient().getSteps(),
                        getFillGradient().getColorSteps(),
                        getFillGradient().getColorStops(),
                        getFillGradient().getBorder(),
                        getFillGradient().getAngle());
                    aGradient.appendTransformationsAndColors(rEntries, rOuterColor);
@@ -68,7 +68,7 @@ namespace drawinglayer::primitive2d
                    texture::GeoTexSvxGradientRadial aGradient(
                        getDefinitionRange(),
                        getFillGradient().getSteps(),
                        getFillGradient().getColorSteps(),
                        getFillGradient().getColorStops(),
                        getFillGradient().getBorder(),
                        getFillGradient().getOffsetX(),
                        getFillGradient().getOffsetY());
@@ -80,7 +80,7 @@ namespace drawinglayer::primitive2d
                    texture::GeoTexSvxGradientElliptical aGradient(
                        getDefinitionRange(),
                        getFillGradient().getSteps(),
                        getFillGradient().getColorSteps(),
                        getFillGradient().getColorStops(),
                        getFillGradient().getBorder(),
                        getFillGradient().getOffsetX(),
                        getFillGradient().getOffsetY(),
@@ -93,7 +93,7 @@ namespace drawinglayer::primitive2d
                    texture::GeoTexSvxGradientSquare aGradient(
                        getDefinitionRange(),
                        getFillGradient().getSteps(),
                        getFillGradient().getColorSteps(),
                        getFillGradient().getColorStops(),
                        getFillGradient().getBorder(),
                        getFillGradient().getOffsetX(),
                        getFillGradient().getOffsetY(),
@@ -106,7 +106,7 @@ namespace drawinglayer::primitive2d
                    texture::GeoTexSvxGradientRect aGradient(
                        getDefinitionRange(),
                        getFillGradient().getSteps(),
                        getFillGradient().getColorSteps(),
                        getFillGradient().getColorStops(),
                        getFillGradient().getBorder(),
                        getFillGradient().getOffsetX(),
                        getFillGradient().getOffsetY(),
diff --git a/drawinglayer/source/primitive3d/textureprimitive3d.cxx b/drawinglayer/source/primitive3d/textureprimitive3d.cxx
index ae89ebb..9776704 100644
--- a/drawinglayer/source/primitive3d/textureprimitive3d.cxx
+++ b/drawinglayer/source/primitive3d/textureprimitive3d.cxx
@@ -94,12 +94,12 @@ namespace drawinglayer::primitive3d
                // create TransparenceTexturePrimitive3D with fixed transparence as replacement
                const basegfx::BColor aGray(getTransparence(), getTransparence(), getTransparence());

                // create ColorSteps with StartColor == EndColor == aGray
                const basegfx::ColorSteps aColorSteps {
                    basegfx::ColorStep(0.0, aGray),
                    basegfx::ColorStep(1.0, aGray) };
                // create ColorStops with StartColor == EndColor == aGray
                const basegfx::ColorStops aColorStops {
                    basegfx::ColorStop(0.0, aGray),
                    basegfx::ColorStop(1.0, aGray) };

                const attribute::FillGradientAttribute aFillGradient(attribute::GradientStyle::Linear, 0.0, 0.0, 0.0, 0.0, aColorSteps);
                const attribute::FillGradientAttribute aFillGradient(attribute::GradientStyle::Linear, 0.0, 0.0, 0.0, 0.0, aColorStops);
                const Primitive3DReference xRef(new TransparenceTexturePrimitive3D(aFillGradient, getChildren(), getTextureSize()));
                return { xRef };
            }
diff --git a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
index c2c3ad6..d75b677 100644
--- a/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclmetafileprocessor2d.cxx
@@ -259,8 +259,8 @@ void VclMetafileProcessor2D::impConvertFillGradientAttributeToVCLGradient(
    Gradient& o_rVCLGradient, const attribute::FillGradientAttribute& rFiGrAtt,
    bool bIsTransparenceGradient) const
{
    const basegfx::BColor aStartColor(rFiGrAtt.getColorSteps().front().getColor());
    const basegfx::BColor aEndColor(rFiGrAtt.getColorSteps().back().getColor());
    const basegfx::BColor aStartColor(rFiGrAtt.getColorStops().front().getStopColor());
    const basegfx::BColor aEndColor(rFiGrAtt.getColorStops().back().getStopColor());

    if (bIsTransparenceGradient)
    {
@@ -2006,9 +2006,9 @@ void VclMetafileProcessor2D::processPolyPolygonGradientPrimitive2D(
        return;
    }

    if (!rGradientCandidate.getFillGradient().getColorSteps().empty())
    if (!rGradientCandidate.getFillGradient().getColorStops().empty())
    {
        // MCGR: if we have COlorSteps, do not try to fallback to old VCL-Gradient,
        // MCGR: if we have ColorStops, do not try to fallback to old VCL-Gradient,
        // that will *not* be capable of representing this properly. Use the
        // correct decomposition instead
        process(rGradientCandidate);
diff --git a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
index 7efb80d..1b85cf9 100644
--- a/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
+++ b/drawinglayer/source/processor2d/vclpixelprocessor2d.cxx
@@ -500,9 +500,9 @@ void VclPixelProcessor2D::processPolyPolygonGradientPrimitive2D(
    // direct draw of gradient
    const attribute::FillGradientAttribute& rGradient(rPolygonCandidate.getFillGradient());
    basegfx::BColor aStartColor(
        maBColorModifierStack.getModifiedColor(rGradient.getColorSteps().front().getColor()));
        maBColorModifierStack.getModifiedColor(rGradient.getColorStops().front().getStopColor()));
    basegfx::BColor aEndColor(
        maBColorModifierStack.getModifiedColor(rGradient.getColorSteps().back().getColor()));
        maBColorModifierStack.getModifiedColor(rGradient.getColorStops().back().getStopColor()));
    basegfx::B2DPolyPolygon aLocalPolyPolygon(rPolygonCandidate.getB2DPolyPolygon());

    if (!aLocalPolyPolygon.count())
@@ -938,9 +938,9 @@ void VclPixelProcessor2D::processFillGradientPrimitive2D(
{
    const attribute::FillGradientAttribute& rFillGradient = rPrimitive.getFillGradient();

    // MCGR: If GradientSteps are used, use decomposition since vcl is not able
    // MCGR: If GradientStops are used, use decomposition since vcl is not able
    // to render multi-color gradients
    if (rFillGradient.getColorSteps().size() > 2)
    if (rFillGradient.getColorStops().size() > 2)
    {
        process(rPrimitive);
        return;
@@ -994,8 +994,8 @@ void VclPixelProcessor2D::processFillGradientPrimitive2D(

    GradientStyle eGradientStyle = convertGradientStyle(rFillGradient.getStyle());

    Gradient aGradient(eGradientStyle, Color(rFillGradient.getColorSteps().front().getColor()),
                       Color(rFillGradient.getColorSteps().back().getColor()));
    Gradient aGradient(eGradientStyle, Color(rFillGradient.getColorStops().front().getStopColor()),
                       Color(rFillGradient.getColorStops().back().getStopColor()));

    aGradient.SetAngle(Degree10(static_cast<int>(basegfx::rad2deg<10>(rFillGradient.getAngle()))));
    aGradient.SetBorder(rFillGradient.getBorder() * 100);
diff --git a/drawinglayer/source/processor3d/defaultprocessor3d.cxx b/drawinglayer/source/processor3d/defaultprocessor3d.cxx
index caf31e9..a2a5111 100644
--- a/drawinglayer/source/processor3d/defaultprocessor3d.cxx
+++ b/drawinglayer/source/processor3d/defaultprocessor3d.cxx
@@ -72,7 +72,7 @@ namespace drawinglayer::processor3d
                                aOutlineRange,
                                aOutlineRange,
                                rFillGradient.getSteps(),
                                rFillGradient.getColorSteps(),
                                rFillGradient.getColorStops(),
                                rFillGradient.getBorder(),
                                rFillGradient.getAngle());
                        break;
@@ -83,7 +83,7 @@ namespace drawinglayer::processor3d
                                aOutlineRange,
                                aOutlineRange,
                                rFillGradient.getSteps(),
                                rFillGradient.getColorSteps(),
                                rFillGradient.getColorStops(),
                                rFillGradient.getBorder(),
                                rFillGradient.getAngle());
                        break;
@@ -94,7 +94,7 @@ namespace drawinglayer::processor3d
                            std::make_shared<texture::GeoTexSvxGradientRadial>(
                                aOutlineRange,
                                rFillGradient.getSteps(),
                                rFillGradient.getColorSteps(),
                                rFillGradient.getColorStops(),
                                rFillGradient.getBorder(),
                                rFillGradient.getOffsetX(),
                                rFillGradient.getOffsetY());
@@ -106,7 +106,7 @@ namespace drawinglayer::processor3d
                            std::make_shared<texture::GeoTexSvxGradientElliptical>(
                                aOutlineRange,
                                rFillGradient.getSteps(),
                                rFillGradient.getColorSteps(),
                                rFillGradient.getColorStops(),
                                rFillGradient.getBorder(),
                                rFillGradient.getOffsetX(),
                                rFillGradient.getOffsetY(),
@@ -119,7 +119,7 @@ namespace drawinglayer::processor3d
                            std::make_shared<texture::GeoTexSvxGradientSquare>(
                                aOutlineRange,
                                rFillGradient.getSteps(),
                                rFillGradient.getColorSteps(),
                                rFillGradient.getColorStops(),
                                rFillGradient.getBorder(),
                                rFillGradient.getOffsetX(),
                                rFillGradient.getOffsetY(),
@@ -132,7 +132,7 @@ namespace drawinglayer::processor3d
                            std::make_shared<texture::GeoTexSvxGradientRect>(
                                aOutlineRange,
                                rFillGradient.getSteps(),
                                rFillGradient.getColorSteps(),
                                rFillGradient.getColorStops(),
                                rFillGradient.getBorder(),
                                rFillGradient.getOffsetX(),
                                rFillGradient.getOffsetY(),
@@ -146,7 +146,7 @@ namespace drawinglayer::processor3d
            else
            {
                // only one color, so no real gradient -> use simple texture
                const basegfx::BColor aStart(rFillGradient.getColorSteps().front().getColor());
                const basegfx::BColor aStart(rFillGradient.getColorStops().front().getStopColor());
                pNewTex = std::make_shared<texture::GeoTexSvxMono>(aStart, 1.0 - aStart.luminance());
                mbSimpleTextureActive = true;
            }
diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx
index 375e83f..5cd7082 100644
--- a/drawinglayer/source/texture/texture.cxx
+++ b/drawinglayer/source/texture/texture.cxx
@@ -72,11 +72,11 @@ namespace drawinglayer::texture
        GeoTexSvxGradient::GeoTexSvxGradient(
            const basegfx::B2DRange& rDefinitionRange,
            sal_uInt32 nRequestedSteps,
            const basegfx::ColorSteps& rColorSteps,
            const basegfx::ColorStops& rColorStops,
            double fBorder)
        : maDefinitionRange(rDefinitionRange)
        , mnRequestedSteps(nRequestedSteps)
        , mnColorSteps(rColorSteps)
        , mnColorStops(rColorStops)
        , mfBorder(fBorder)
        {
        }
@@ -93,7 +93,7 @@ namespace drawinglayer::texture
                && maGradientInfo == pCompare->maGradientInfo
                && maDefinitionRange == pCompare->maDefinitionRange
                && mnRequestedSteps == pCompare->mnRequestedSteps
                && mnColorSteps == pCompare->mnColorSteps
                && mnColorStops == pCompare->mnColorStops
                && mfBorder == pCompare->mfBorder);
        }

@@ -101,10 +101,10 @@ namespace drawinglayer::texture
            const basegfx::B2DRange& rDefinitionRange,
            const basegfx::B2DRange& rOutputRange,
            sal_uInt32 nRequestedSteps,
            const basegfx::ColorSteps& rColorSteps,
            const basegfx::ColorStops& rColorStops,
            double fBorder,
            double fAngle)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorSteps, fBorder)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorStops, fBorder)
        , mfUnitMinX(0.0)
        , mfUnitWidth(1.0)
        , mfUnitMaxY(1.0)
@@ -135,14 +135,14 @@ namespace drawinglayer::texture
            basegfx::BColor& rOuterColor)
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // fill in return parameter rOuterColor before returning
            rOuterColor = mnColorSteps.front().getColor();
            rOuterColor = mnColorStops.front().getStopColor();

            // only one color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
                return;

            // prepare unit range transform
@@ -156,19 +156,19 @@ namespace drawinglayer::texture
            aPattern.scale(mfUnitWidth, 1.0);
            aPattern.translate(mfUnitMinX, 0.0);

            // outer loop over ColorSteps, each is from cs_l to cs_r
            for (auto cs_l(mnColorSteps.begin()), cs_r(cs_l + 1); cs_r != mnColorSteps.end(); cs_l++, cs_r++)
            // outer loop over ColorStops, each is from cs_l to cs_r
            for (auto cs_l(mnColorStops.begin()), cs_r(cs_l + 1); cs_r != mnColorStops.end(); cs_l++, cs_r++)
            {
                // get colors & calculate steps
                const basegfx::BColor aCStart(cs_l->getColor());
                const basegfx::BColor aCEnd(cs_r->getColor());
                const basegfx::BColor aCStart(cs_l->getStopColor());
                const basegfx::BColor aCEnd(cs_r->getStopColor());
                const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
                    maGradientInfo.getRequestedSteps(), aCStart, aCEnd));

                // get offsets & calculate StripeWidth
                // nSteps is >= 1, see getRequestedSteps, so no check needed here
                const double fOffsetStart(cs_l->getOffset());
                const double fOffsetEnd(cs_r->getOffset());
                const double fOffsetStart(cs_l->getStopOffset());
                const double fOffsetEnd(cs_r->getStopOffset());
                const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);

                // for the 1st color range we do not need to create the 1st step
@@ -177,7 +177,7 @@ namespace drawinglayer::texture
                // colored using rOuterColor.
                // We *need* to create this though for all 'inner' color ranges
                // to get a correct start
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0);
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorStops.begin() ? 1 : 0);

                for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
                {
@@ -211,29 +211,29 @@ namespace drawinglayer::texture
        void GeoTexSvxGradientLinear::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // just single color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
            {
                rBColor = mnColorSteps.front().getColor();
                rBColor = mnColorStops.front().getStopColor();
                return;
            }

            // texture-back-transform X/Y -> t [0.0..1.0] and determine color
            const double fScaler(basegfx::utils::getLinearGradientAlpha(rUV, maGradientInfo));
            rBColor = basegfx::utils::modifyBColor(mnColorSteps, fScaler, mnRequestedSteps);
            rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps);
        }

        GeoTexSvxGradientAxial::GeoTexSvxGradientAxial(
            const basegfx::B2DRange& rDefinitionRange,
            const basegfx::B2DRange& rOutputRange,
            sal_uInt32 nRequestedSteps,
            const basegfx::ColorSteps& rColorSteps,
            const basegfx::ColorStops& rColorStops,
            double fBorder,
            double fAngle)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorSteps, fBorder)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorStops, fBorder)
        , mfUnitMinX(0.0)
        , mfUnitWidth(1.0)
        {
@@ -262,15 +262,15 @@ namespace drawinglayer::texture
            basegfx::BColor& rOuterColor)
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // fill in return parameter rOuterColor before returning
            // CAUTION: for GradientAxial the color range is inverted (!)
            rOuterColor = mnColorSteps.back().getColor();
            rOuterColor = mnColorStops.back().getStopColor();

            // only one color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
                return;

            // prepare unit range transform
@@ -284,25 +284,25 @@ namespace drawinglayer::texture
            aPattern.scale(mfUnitWidth, 1.0);
            aPattern.translate(mfUnitMinX, 0.0);

            // outer loop over ColorSteps, each is from cs_l to cs_r
            // outer loop over ColorStops, each is from cs_l to cs_r
            // CAUTION: for GradientAxial the color range is used inverted (!)
            //          thus, to loop backward, use rbegin/rend
            for (auto cs_r(mnColorSteps.rbegin()), cs_l(cs_r + 1); cs_l != mnColorSteps.rend(); cs_l++, cs_r++)
            for (auto cs_r(mnColorStops.rbegin()), cs_l(cs_r + 1); cs_l != mnColorStops.rend(); cs_l++, cs_r++)
            {
                // get colors & calculate steps
                const basegfx::BColor aCStart(cs_l->getColor());
                const basegfx::BColor aCEnd(cs_r->getColor());
                const basegfx::BColor aCStart(cs_l->getStopColor());
                const basegfx::BColor aCEnd(cs_r->getStopColor());
                const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
                    maGradientInfo.getRequestedSteps(), aCStart, aCEnd));

                // get offsets & calculate StripeWidth
                // nSteps is >= 1, see getRequestedSteps, so no check needed here
                const double fOffsetStart(cs_l->getOffset());
                const double fOffsetEnd(cs_r->getOffset());
                const double fOffsetStart(cs_l->getStopOffset());
                const double fOffsetEnd(cs_r->getStopOffset());
                const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);

                // for the 1st color range we do not need to create the 1st step, see above
                const sal_uInt32 nStartInnerLoop(cs_r == mnColorSteps.rbegin() ? 1 : 0);
                const sal_uInt32 nStartInnerLoop(cs_r == mnColorStops.rbegin() ? 1 : 0);

                for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
                {
@@ -326,31 +326,31 @@ namespace drawinglayer::texture
        void GeoTexSvxGradientAxial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // just single color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
            {
                // CAUTION: for GradientAxial the color range is used inverted (!)
                rBColor = mnColorSteps.back().getColor();
                rBColor = mnColorStops.back().getStopColor();
                return;
            }

            // texture-back-transform X/Y -> t [0.0..1.0] and determine color
            const double fScaler(basegfx::utils::getAxialGradientAlpha(rUV, maGradientInfo));
            rBColor = basegfx::utils::modifyBColor(mnColorSteps, fScaler, mnRequestedSteps);
            rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps);
        }


        GeoTexSvxGradientRadial::GeoTexSvxGradientRadial(
            const basegfx::B2DRange& rDefinitionRange,
            sal_uInt32 nRequestedSteps,
            const basegfx::ColorSteps& rColorSteps,
            const basegfx::ColorStops& rColorStops,
            double fBorder,
            double fOffsetX,
            double fOffsetY)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorSteps, fBorder)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorStops, fBorder)
        {
            maGradientInfo = basegfx::utils::createRadialODFGradientInfo(
                rDefinitionRange,
@@ -368,32 +368,32 @@ namespace drawinglayer::texture
            basegfx::BColor& rOuterColor)
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // fill in return parameter rOuterColor before returning
            rOuterColor = mnColorSteps.front().getColor();
            rOuterColor = mnColorStops.front().getStopColor();

            // only one color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
                return;

            // outer loop over ColorSteps, each is from cs_l to cs_r
            for (auto cs_l(mnColorSteps.begin()), cs_r(cs_l + 1); cs_r != mnColorSteps.end(); cs_l++, cs_r++)
            // outer loop over ColorStops, each is from cs_l to cs_r
            for (auto cs_l(mnColorStops.begin()), cs_r(cs_l + 1); cs_r != mnColorStops.end(); cs_l++, cs_r++)
            {
                // get colors & calculate steps
                const basegfx::BColor aCStart(cs_l->getColor());
                const basegfx::BColor aCEnd(cs_r->getColor());
                const basegfx::BColor aCStart(cs_l->getStopColor());
                const basegfx::BColor aCEnd(cs_r->getStopColor());
                const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
                    maGradientInfo.getRequestedSteps(), aCStart, aCEnd));

                // get offsets & calculate StripeWidth
                const double fOffsetStart(cs_l->getOffset());
                const double fOffsetEnd(cs_r->getOffset());
                const double fOffsetStart(cs_l->getStopOffset());
                const double fOffsetEnd(cs_r->getStopOffset());
                const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);

                // get correct start for inner loop (see above)
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0);
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorStops.begin() ? 1 : 0);

                for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
                {
@@ -413,31 +413,31 @@ namespace drawinglayer::texture
        void GeoTexSvxGradientRadial::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // just single color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
            {
                rBColor = mnColorSteps.front().getColor();
                rBColor = mnColorStops.front().getStopColor();
                return;
            }

            // texture-back-transform X/Y -> t [0.0..1.0] and determine color
            const double fScaler(basegfx::utils::getRadialGradientAlpha(rUV, maGradientInfo));
            rBColor = basegfx::utils::modifyBColor(mnColorSteps, fScaler, mnRequestedSteps);
            rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps);
        }


        GeoTexSvxGradientElliptical::GeoTexSvxGradientElliptical(
            const basegfx::B2DRange& rDefinitionRange,
            sal_uInt32 nRequestedSteps,
            const basegfx::ColorSteps& rColorSteps,
            const basegfx::ColorStops& rColorStops,
            double fBorder,
            double fOffsetX,
            double fOffsetY,
            double fAngle)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorSteps, fBorder)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorStops, fBorder)
        {
            maGradientInfo = basegfx::utils::createEllipticalODFGradientInfo(
                rDefinitionRange,
@@ -456,36 +456,36 @@ namespace drawinglayer::texture
            basegfx::BColor& rOuterColor)
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // fill in return parameter rOuterColor before returning
            rOuterColor = mnColorSteps.front().getColor();
            rOuterColor = mnColorStops.front().getStopColor();

            // only one color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
                return;

            // prepare vars dependent on aspect ratio
            const double fAR(maGradientInfo.getAspectRatio());
            const bool bMTO(fAR > 1.0);

            // outer loop over ColorSteps, each is from cs_l to cs_r
            for (auto cs_l(mnColorSteps.begin()), cs_r(cs_l + 1); cs_r != mnColorSteps.end(); cs_l++, cs_r++)
            // outer loop over ColorStops, each is from cs_l to cs_r
            for (auto cs_l(mnColorStops.begin()), cs_r(cs_l + 1); cs_r != mnColorStops.end(); cs_l++, cs_r++)
            {
                // get colors & calculate steps
                const basegfx::BColor aCStart(cs_l->getColor());
                const basegfx::BColor aCEnd(cs_r->getColor());
                const basegfx::BColor aCStart(cs_l->getStopColor());
                const basegfx::BColor aCEnd(cs_r->getStopColor());
                const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
                    maGradientInfo.getRequestedSteps(), aCStart, aCEnd));

                // get offsets & calculate StripeWidth
                const double fOffsetStart(cs_l->getOffset());
                const double fOffsetEnd(cs_r->getOffset());
                const double fOffsetStart(cs_l->getStopOffset());
                const double fOffsetEnd(cs_r->getStopOffset());
                const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);

                // get correct start for inner loop (see above)
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0);
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorStops.begin() ? 1 : 0);

                for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
                {
@@ -508,31 +508,31 @@ namespace drawinglayer::texture
        void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // just single color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
            {
                rBColor = mnColorSteps.front().getColor();
                rBColor = mnColorStops.front().getStopColor();
                return;
            }

            // texture-back-transform X/Y -> t [0.0..1.0] and determine color
            const double fScaler(basegfx::utils::getEllipticalGradientAlpha(rUV, maGradientInfo));
            rBColor = basegfx::utils::modifyBColor(mnColorSteps, fScaler, mnRequestedSteps);
            rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps);
        }


        GeoTexSvxGradientSquare::GeoTexSvxGradientSquare(
            const basegfx::B2DRange& rDefinitionRange,
            sal_uInt32 nRequestedSteps,
            const basegfx::ColorSteps& rColorSteps,
            const basegfx::ColorStops& rColorStops,
            double fBorder,
            double fOffsetX,
            double fOffsetY,
            double fAngle)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorSteps, fBorder)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorStops, fBorder)
        {
            maGradientInfo = basegfx::utils::createSquareODFGradientInfo(
                rDefinitionRange,
@@ -551,32 +551,32 @@ namespace drawinglayer::texture
            basegfx::BColor& rOuterColor)
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // fill in return parameter rOuterColor before returning
            rOuterColor = mnColorSteps.front().getColor();
            rOuterColor = mnColorStops.front().getStopColor();

            // only one color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
                return;

            // outer loop over ColorSteps, each is from cs_l to cs_r
            for (auto cs_l(mnColorSteps.begin()), cs_r(cs_l + 1); cs_r != mnColorSteps.end(); cs_l++, cs_r++)
            // outer loop over ColorStops, each is from cs_l to cs_r
            for (auto cs_l(mnColorStops.begin()), cs_r(cs_l + 1); cs_r != mnColorStops.end(); cs_l++, cs_r++)
            {
                // get colors & calculate steps
                const basegfx::BColor aCStart(cs_l->getColor());
                const basegfx::BColor aCEnd(cs_r->getColor());
                const basegfx::BColor aCStart(cs_l->getStopColor());
                const basegfx::BColor aCEnd(cs_r->getStopColor());
                const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
                    maGradientInfo.getRequestedSteps(), aCStart, aCEnd));

                // get offsets & calculate StripeWidth
                const double fOffsetStart(cs_l->getOffset());
                const double fOffsetEnd(cs_r->getOffset());
                const double fOffsetStart(cs_l->getStopOffset());
                const double fOffsetEnd(cs_r->getStopOffset());
                const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);

                // get correct start for inner loop (see above)
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0);
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorStops.begin() ? 1 : 0);

                for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
                {
@@ -596,31 +596,31 @@ namespace drawinglayer::texture
        void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // just single color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
            {
                rBColor = mnColorSteps.front().getColor();
                rBColor = mnColorStops.front().getStopColor();
                return;
            }

            // texture-back-transform X/Y -> t [0.0..1.0] and determine color
            const double fScaler(basegfx::utils::getSquareGradientAlpha(rUV, maGradientInfo));
            rBColor = basegfx::utils::modifyBColor(mnColorSteps, fScaler, mnRequestedSteps);
            rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps);
        }


        GeoTexSvxGradientRect::GeoTexSvxGradientRect(
            const basegfx::B2DRange& rDefinitionRange,
            sal_uInt32 nRequestedSteps,
            const basegfx::ColorSteps& rColorSteps,
            const basegfx::ColorStops& rColorStops,
            double fBorder,
            double fOffsetX,
            double fOffsetY,
            double fAngle)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorSteps, fBorder)
        : GeoTexSvxGradient(rDefinitionRange, nRequestedSteps, rColorStops, fBorder)
        {
            maGradientInfo = basegfx::utils::createRectangularODFGradientInfo(
                rDefinitionRange,
@@ -639,36 +639,36 @@ namespace drawinglayer::texture
            basegfx::BColor& rOuterColor)
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // fill in return parameter rOuterColor before returning
            rOuterColor = mnColorSteps.front().getColor();
            rOuterColor = mnColorStops.front().getStopColor();

            // only one color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
                return;

            // prepare vars dependent on aspect ratio
            const double fAR(maGradientInfo.getAspectRatio());
            const bool bMTO(fAR > 1.0);

            // outer loop over ColorSteps, each is from cs_l to cs_r
            for (auto cs_l(mnColorSteps.begin()), cs_r(cs_l + 1); cs_r != mnColorSteps.end(); cs_l++, cs_r++)
            // outer loop over ColorStops, each is from cs_l to cs_r
            for (auto cs_l(mnColorStops.begin()), cs_r(cs_l + 1); cs_r != mnColorStops.end(); cs_l++, cs_r++)
            {
                // get colors & calculate steps
                const basegfx::BColor aCStart(cs_l->getColor());
                const basegfx::BColor aCEnd(cs_r->getColor());
                const basegfx::BColor aCStart(cs_l->getStopColor());
                const basegfx::BColor aCEnd(cs_r->getStopColor());
                const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
                    maGradientInfo.getRequestedSteps(), aCStart, aCEnd));

                // get offsets & calculate StripeWidth
                const double fOffsetStart(cs_l->getOffset());
                const double fOffsetEnd(cs_r->getOffset());
                const double fOffsetStart(cs_l->getStopOffset());
                const double fOffsetEnd(cs_r->getStopOffset());
                const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);

                // get correct start for inner loop (see above)
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0);
                const sal_uInt32 nStartInnerLoop(cs_l == mnColorStops.begin() ? 1 : 0);

                for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
                {
@@ -691,19 +691,19 @@ namespace drawinglayer::texture
        void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
        {
            // no color at all, done
            if (mnColorSteps.empty())
            if (mnColorStops.empty())
                return;

            // just single color, done
            if (mnColorSteps.size() < 2)
            if (mnColorStops.size() < 2)
            {
                rBColor = mnColorSteps.front().getColor();
                rBColor = mnColorStops.front().getStopColor();
                return;
            }

            // texture-back-transform X/Y -> t [0.0..1.0] and determine color
            const double fScaler(basegfx::utils::getRectangularGradientAlpha(rUV, maGradientInfo));
            rBColor = basegfx::utils::modifyBColor(mnColorSteps, fScaler, mnRequestedSteps);
            rBColor = basegfx::utils::modifyBColor(mnColorStops, fScaler, mnRequestedSteps);
        }


diff --git a/drawinglayer/source/tools/primitive2dxmldump.cxx b/drawinglayer/source/tools/primitive2dxmldump.cxx
index 55d2c6a..31c88c6 100644
--- a/drawinglayer/source/tools/primitive2dxmldump.cxx
+++ b/drawinglayer/source/tools/primitive2dxmldump.cxx
@@ -301,18 +301,19 @@ void writeSdrFillAttribute(::tools::XmlWriter& rWriter,
        rWriter.attribute("angle", rGradient.getAngle());
        rWriter.attribute("steps", rGradient.getSteps());

        auto const& rColorSteps(rGradient.getColorSteps());
        for (size_t a(0); a < rColorSteps.size(); a++)
        auto const& rColorStops(rGradient.getColorStops());
        for (size_t a(0); a < rColorStops.size(); a++)
        {
            if (0 == a)
                rWriter.attribute("startColor", convertColorToString(rColorSteps[a].getColor()));
            else if (rColorSteps.size() == a + 1)
                rWriter.attribute("endColor", convertColorToString(rColorSteps[a].getColor()));
                rWriter.attribute("startColor",
                                  convertColorToString(rColorStops[a].getStopColor()));
            else if (rColorStops.size() == a + 1)
                rWriter.attribute("endColor", convertColorToString(rColorStops[a].getStopColor()));
            else
            {
                rWriter.startElement("colorStep");
                rWriter.attribute("offset", rColorSteps[a].getOffset());
                rWriter.attribute("color", convertColorToString(rColorSteps[a].getColor()));
                rWriter.startElement("colorStop");
                rWriter.attribute("stopOffset", rColorStops[a].getStopOffset());
                rWriter.attribute("stopColor", convertColorToString(rColorStops[a].getStopColor()));
                rWriter.endElement();
            }
        }
diff --git a/drawinglayer/source/tools/wmfemfhelper.cxx b/drawinglayer/source/tools/wmfemfhelper.cxx
index 27e6a6c..e6eb4018 100644
--- a/drawinglayer/source/tools/wmfemfhelper.cxx
+++ b/drawinglayer/source/tools/wmfemfhelper.cxx
@@ -711,17 +711,13 @@ namespace wmfemfhelper
            }
        }

        const basegfx::ColorSteps aColorSteps {
            basegfx::ColorStep(0.0, aStart),
            basegfx::ColorStep(1.0, aEnd) };

        return drawinglayer::attribute::FillGradientAttribute(
            aGradientStyle,
            static_cast<double>(rGradient.GetBorder()) * 0.01,
            static_cast<double>(rGradient.GetOfsX()) * 0.01,
            static_cast<double>(rGradient.GetOfsY()) * 0.01,
            toRadians(rGradient.GetAngle()),
            aColorSteps,
            basegfx::utils::createColorStopsFromStartEndColor(aStart, aEnd),
            rGradient.GetSteps());
    }

@@ -926,7 +922,7 @@ namespace wmfemfhelper
        if(aAttribute.hasSingleColor())
        {
            // not really a gradient. Create filled rectangle
            return CreateColorWallpaper(rRange, aAttribute.getColorSteps().front().getColor(), rPropertyHolder);
            return CreateColorWallpaper(rRange, aAttribute.getColorStops().front().getStopColor(), rPropertyHolder);
        }
        else
        {
@@ -2809,7 +2805,7 @@ namespace wmfemfhelper
                                    rTargetHolders.Current().append(
                                        new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
                                            std::move(xSubContent),
                                            aAttribute.getColorSteps().front().getColor().luminance()));
                                            aAttribute.getColorStops().front().getStopColor().luminance()));
                                }
                                else
                                {
@@ -2929,7 +2925,7 @@ namespace wmfemfhelper
                                    rTargetHolders.Current().append(
                                        new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(
                                            std::move(aPolyPolygon),
                                            aAttribute.getColorSteps().front().getColor()));
                                            aAttribute.getColorStops().front().getStopColor()));
                                }
                                else
                                {
diff --git a/filter/source/msfilter/msdffimp.cxx b/filter/source/msfilter/msdffimp.cxx
index 144d640..53818a5 100644
--- a/filter/source/msfilter/msdffimp.cxx
+++ b/filter/source/msfilter/msdffimp.cxx
@@ -2924,7 +2924,9 @@ void DffPropertyReader::ImportGradientColor( SfxItemSet& aSet, sal_uInt32 eMSO_F
    }

    //Construct gradient item
    XGradient aGrad( aCol2, aCol1, eGrad, nAngle, nFocusX, nFocusY );
    XGradient aGrad(
        basegfx::utils::createColorStopsFromStartEndColor(aCol2.getBColor(), aCol1.getBColor()),
        eGrad, nAngle, nFocusX, nFocusY );
    //Intensity has been merged into color. So here just set is as 100
    aGrad.SetStartIntens( 100 );
    aGrad.SetEndIntens( 100 );
@@ -2937,7 +2939,9 @@ void DffPropertyReader::ImportGradientColor( SfxItemSet& aSet, sal_uInt32 eMSO_F
        aCol1 = Color(nStartCol, nStartCol, nStartCol);
        aCol2 = Color(nEndCol, nEndCol, nEndCol);

        XGradient aGrad2( aCol2 ,  aCol1 , eGrad, nAngle, nFocusX, nFocusY );
        XGradient aGrad2(
            basegfx::utils::createColorStopsFromStartEndColor(aCol2.getBColor(), aCol1.getBColor()),
            eGrad, nAngle, nFocusX, nFocusY );
        aSet.Put( XFillFloatTransparenceItem( OUString(), aGrad2 ) );
    }
}
diff --git a/filter/source/msfilter/svdfppt.cxx b/filter/source/msfilter/svdfppt.cxx
index faded37..013ff44 100644
--- a/filter/source/msfilter/svdfppt.cxx
+++ b/filter/source/msfilter/svdfppt.cxx
@@ -5747,7 +5747,7 @@ void PPTPortionObj::ApplyTo(  SfxItemSet& rSet, SdrPowerPointImport& rManager, T
                                {
                                    const XFillGradientItem* pGradientItem = pItemSet->GetItemIfSet( XATTR_FILLGRADIENT, false );
                                    if ( pGradientItem )
                                        aDefColor = pGradientItem->GetGradientValue().GetStartColor();
                                        aDefColor = Color(pGradientItem->GetGradientValue().GetColorStops().front().getStopColor());
                                }
                                break;
                                case drawing::FillStyle_HATCH :
@@ -7399,8 +7399,8 @@ static void ApplyCellAttributes( const SdrObject* pObj, Reference< XCell > const

                    css::awt::Gradient aGradient;
                    aGradient.Style = aXGradient.GetGradientStyle();
                    aGradient.StartColor = static_cast<sal_Int32>(aXGradient.GetStartColor());
                    aGradient.EndColor = static_cast<sal_Int32>(aXGradient.GetEndColor());
                    aGradient.StartColor = static_cast<sal_Int32>(Color(aXGradient.GetColorStops().front().getStopColor()));
                    aGradient.EndColor = static_cast<sal_Int32>(Color(aXGradient.GetColorStops().back().getStopColor()));
                    aGradient.Angle = static_cast<short>(aXGradient.GetAngle());
                    aGradient.Border = aXGradient.GetBorder();
                    aGradient.XOffset = aXGradient.GetXOffset();
diff --git a/include/basegfx/utils/gradienttools.hxx b/include/basegfx/utils/gradienttools.hxx
index 4e42efa..8580274 100644
--- a/include/basegfx/utils/gradienttools.hxx
+++ b/include/basegfx/utils/gradienttools.hxx
@@ -27,12 +27,14 @@
#include <utility>
#include <basegfx/basegfxdllapi.h>
#include <vector>
#include <com/sun/star/awt/ColorStopSequence.hdl>

namespace com { namespace sun { namespace star { namespace uno { class Any; } } } }
namespace basegfx { class B2DRange; }

namespace basegfx
{
    /* MCGR: Provide ColorStep definition
    /* MCGR: Provide ColorStop definition

        This is the needed combination of offset and color:

@@ -52,59 +54,60 @@ namespace basegfx
        Color is defined as:
        - RGB with unit values [0.0 .. 1.0]

        These definitions are packed in a std::vector<ColorStep> ColorSteps,
        These definitions are packed in a std::vector<ColorStop> ColorStops,
        see typedef below.
    */
    class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) ColorStep
    class UNLESS_MERGELIBS(BASEGFX_DLLPUBLIC) ColorStop
    {
    private:
        // offset in the range of [0.0 .. 1.0], checked & force by constructor
        double mfOffset;
        // offset in the range of [0.0 .. 1.0]
        double mfStopOffset;

        // color of ColorStep entry
        BColor maColor;
        // RGB color of ColorStop entry
        BColor maStopColor;

    public:
        // constructor - defaults are needed to have a default constructor
        // e.g. for usage in std::vector::insert
        // ensure [0.0 .. 1.0] range for mfOffset
        ColorStep(double fOffset = 0.0, const BColor& rColor = BColor())
            : mfOffset(fOffset)
            , maColor(rColor)
        // e.g. for usage in std::vector::insert (even when only reducing)
        // ensure [0.0 .. 1.0] range for mfStopOffset
        ColorStop(double fStopOffset = 0.0, const BColor& rStopColor = BColor())
            : mfStopOffset(fStopOffset)
            , maStopColor(rStopColor)
        {
            // NOTE: I originally *corrected* mfOffset here by using
            //   mfOffset(std::max(0.0, std::min(fOffset, 1.0)))
            // NOTE: I originally *corrected* mfStopOffset here by using
            //   mfStopOffset(std::max(0.0, std::min(fOffset, 1.0)))
            // While that is formally correct, it moves an invalid
            // entry to 0.0 or 1.0, thus creating additional wrong
            // Start/EndColor entries. That may then 'overlay' the
            // correct entry when corrections are applied to the
            // vector of entries (see sortAndCorrectColorSteps)
            // vector of entries (see sortAndCorrectColorStops)
            // which leads to getting the wanted Start/EndColor
            // to be factically deleted, what is an error.
        }

        double getOffset() const { return mfOffset; }
        const BColor& getColor() const { return maColor; }
        double getStopOffset() const { return mfStopOffset; }
        const BColor& getStopColor() const { return maStopColor; }

        bool operator<(const ColorStep& rCandidate) const
        // needed for std::sort
        bool operator<(const ColorStop& rCandidate) const
        {
            return getOffset() < rCandidate.getOffset();
            return getStopOffset() < rCandidate.getStopOffset();
        }

        bool operator==(const ColorStep& rCandidate) const
        bool operator==(const ColorStop& rCandidate) const
        {
            return getOffset() == rCandidate.getOffset() && getColor() == rCandidate.getColor();
            return getStopOffset() == rCandidate.getStopOffset() && getStopColor() == rCandidate.getStopColor();
        }
    };

    /* MCGR: Provide ColorSteps definition to the FillGradientAttribute
    /* MCGR: Provide ColorStops definition to the FillGradientAttribute

        This array should be sorted ascending by offsets, from lowest to
        highest. Since all the primitive data definition where it is used
        is read-only, this can/will be guaranteed by forcing/checking this
        in the constructor, see ::FillGradientAttribute
    */
    typedef std::vector<ColorStep> ColorSteps;
    typedef std::vector<ColorStop> ColorStops;

    /** Gradient definition as used in ODF 1.2

@@ -193,33 +196,78 @@ namespace basegfx

    namespace utils
    {
        /* Helper to sort and correct ColorSteps. This will
           sort and then correct the given ColorSteps. The
           corrected version will
           - be sorted
           - have no double values
           - have no values with offset < 0.0
           - have no values with offset > 1.0
           thus be ready to be used in multi-color gradients.

           NOTE: The returned version may be empty (!) if no
                 valid entries were contained
           NOTE: It does not necessarily contain values for
                 offset == 0.0 and 1.0 if there were none
                 given (so no Start/EndColor)
           NOTE: If it contains only one entry that entry is
                 set to StartColor and the Color is preserved.
                 This is also done when all Colors are the same
        /* Tooling method to convert UNO API data to ColorStops.
           This will try to extract ColorStop data from the given
           Any, so if it's of type awt::Gradient2 that data will be
           extracted, converted and copied into the given ColorStops.
        */
        BASEGFX_DLLPUBLIC void sortAndCorrectColorSteps(ColorSteps& rColorSteps);
        BASEGFX_DLLPUBLIC void fillColorStopsFromAny(ColorStops& rColorStops, const css::uno::Any& rVal);

        /* Helper to grep the correct ColorStep out of
           ColorSteps and interpolate as needed for given
        /* Tooling method to fill a awt::ColorStopSequence with
           the data from the given ColorStops. This is used in
           UNO API implementations.
        */
        BASEGFX_DLLPUBLIC void fillColorStopSequenceFromColorStops(css::awt::ColorStopSequence& rColorStopSequence, const ColorStops& rColorStops);

        /* Tooling method that allows to replace the StartColor in a
           vector of ColorStops. A vector in 'ordered state' is expected,
           so you may use/have used sortAndCorrectColorStops, see below.
           This method is for convenience & backwards compatibility, please
           think about handling multi-colored gradients directly.
        */
        BASEGFX_DLLPUBLIC void replaceStartColor(ColorStops& rColorStops, const BColor& rStart);

        /* Tooling method that allows to replace the EndColor in a
           vector of ColorStops. A vector in 'ordered state' is expected,
           so you may use/have used sortAndCorrectColorStops, see below.
           This method is for convenience & backwards compatibility, please
           think about handling multi-colored gradients directly.
        */
        BASEGFX_DLLPUBLIC void replaceEndColor(ColorStops& rColorStops, const BColor& rEnd);

        // Tooling method to quickly create a ColorStop vector for a given set of Start/EndColor
        BASEGFX_DLLPUBLIC ColorStops createColorStopsFromStartEndColor(const BColor& rStart, const BColor& rEnd);

        /* Tooling method to guarantee sort and correctness for
           the given ColorStops vector.
           A vector fulfilling these conditions is called to be
           in 'ordered state'.

           At return, the following conditions are guaranteed:
           - contains no ColorStops with offset < 0.0 (will
             be removed)
           - contains no ColorStops with offset > 1.0 (will
             be removed)
           - contains no two ColorStops with identical offsets
             (will be removed, 1st one/smallest offset wins
             which is also given by sort tooling)
           - will be sorted from lowest offset to highest
           - if all colors are the same, the content will
             be reduced to a single entry with offset 0.0
             (force to StartColor)

           Some more notes:
           - It can happen that the result is empty
           - It is allowed to have consecutive entries with
             the same color, this represents single-color
             regions inside the gradient
           - A entry with 0.0 is not required or forced, so
             no 'StartColor' is technically required
           - A entry with 1.0 is not required or forced, so
             no 'EndColor' is technically required

           All this is done in one run (sort + O(N)) without
           creating a copy of the data in any form
        */
        BASEGFX_DLLPUBLIC void sortAndCorrectColorStops(ColorStops& rColorStops);

        /* Helper to grep the correct ColorStop out of
           ColorStops and interpolate as needed for given
           relative value in fScaler in the range of [0.0 .. 1.0].
           It also takes care of evtl. given RequestedSteps.
        */
        BASEGFX_DLLPUBLIC BColor modifyBColor(
            const ColorSteps& rColorSteps,
            const ColorStops& rColorStops,
            double fScaler,
            sal_uInt32 nRequestedSteps);

diff --git a/include/drawinglayer/attribute/fillgradientattribute.hxx b/include/drawinglayer/attribute/fillgradientattribute.hxx
index 3a62ee4..8a2df4d 100644
--- a/include/drawinglayer/attribute/fillgradientattribute.hxx
+++ b/include/drawinglayer/attribute/fillgradientattribute.hxx
@@ -25,9 +25,9 @@

namespace basegfx
{
class ColorStep;
class ColorStop;
class BColor;
typedef std::vector<ColorStep> ColorSteps;
typedef std::vector<ColorStop> ColorStops;
}

namespace drawinglayer::attribute
@@ -56,17 +56,17 @@ public:
    /* MCGR: Adaptions for MultiColorGradients

       Direct Start/EndCOlor is no longer required, instead the
       full color gradient is handed over as ColorSteps vector.
       full color gradient is handed over as ColorStops vector.
       To add the former Start/EndColor in a compatible way, just
       prepare an instance of basegfx::ColorSteps with the
       prepare an instance of basegfx::ColorStops with the
       StartColor at 0.0 and the EndColor at 1.0.

       A rigid correction/input data will be done by the constructor,
       including to sort the ColorSteps by offset and removing invalid
       entries (see sortAndCorrectColorSteps)
       including to sort the ColorStops by offset and removing invalid
       entries (see sortAndCorrectColorStops)

       To access e.g. the StartColor, use getColorSteps().front(), and
       getColorSteps().back(), accordingly, for EndColor. The existence
       To access e.g. the StartColor, use getColorStops().front(), and
       getColorStops().back(), accordingly, for EndColor. The existence
       of at least one entry is guaranteed, so no need to check before
       accessing using of front()/back() calls. If only one color entry
       exists, start == end color is assumed, so not really a gradient
@@ -74,7 +74,7 @@ public:
    */
    /// constructors/assignmentoperator/destructor
    FillGradientAttribute(GradientStyle eStyle, double fBorder, double fOffsetX, double fOffsetY,
                          double fAngle, const basegfx::ColorSteps& rColorSteps,
                          double fAngle, const basegfx::ColorStops& rColorStops,
                          sal_uInt16 nSteps = 0);
    FillGradientAttribute();
    FillGradientAttribute(const FillGradientAttribute&);
@@ -98,7 +98,7 @@ public:
    double getOffsetX() const;
    double getOffsetY() const;
    double getAngle() const;
    const basegfx::ColorSteps& getColorSteps() const;
    const basegfx::ColorStops& getColorStops() const;
    sal_uInt16 getSteps() const;
};

diff --git a/include/svx/unomid.hxx b/include/svx/unomid.hxx
index fe07fee..766996a 100644
--- a/include/svx/unomid.hxx
+++ b/include/svx/unomid.hxx
@@ -71,6 +71,7 @@
#define MID_GRADIENT_STARTINTENSITY 9
#define MID_GRADIENT_ENDINTENSITY   10
#define MID_GRADIENT_STEPCOUNT      11
#define MID_GRADIENT_COLORSTOPSEQUENCE 12

// XFillHatchItem
// Don't use 0 as it used for the whole struct
diff --git a/include/svx/xgrad.hxx b/include/svx/xgrad.hxx
index 553dfe23..9dda79d 100644
--- a/include/svx/xgrad.hxx
+++ b/include/svx/xgrad.hxx
@@ -25,15 +25,16 @@
#include <svx/svxdllapi.h>
#include <com/sun/star/awt/GradientStyle.hpp>
#include <boost/property_tree/ptree_fwd.hpp>
#include <com/sun/star/awt/Gradient.hpp>

class Gradient;
#include <com/sun/star/awt/Gradient2.hpp>
#include <basegfx/utils/gradienttools.hxx>

class SAL_WARN_UNUSED SVXCORE_DLLPUBLIC XGradient final
{
    css::awt::GradientStyle  eStyle;
    Color               aStartColor;
    Color               aEndColor;

    // MCGS: ColorStops in the range [0.0 .. 1.0], including StartColor/EndColor
    basegfx::ColorStops aColorStops;

    Degree10            nAngle;
    sal_uInt16          nBorder;
    sal_uInt16          nOfsX;
@@ -46,7 +47,7 @@ class SAL_WARN_UNUSED SVXCORE_DLLPUBLIC XGradient final

public:
    XGradient();
    XGradient( const Color& rStart, const Color& rEnd,
    XGradient( const basegfx::ColorStops& rColorStops,
               css::awt::GradientStyle eStyle = css::awt::GradientStyle_LINEAR, Degree10 nAngle = 0_deg10,
               sal_uInt16 nXOfs = 50, sal_uInt16 nYOfs = 50, sal_uInt16 nBorder = 0,
               sal_uInt16 nStartIntens = 100, sal_uInt16 nEndIntens = 100,
@@ -55,8 +56,7 @@ public:
    bool operator==(const XGradient& rGradient) const;

    void SetGradientStyle(css::awt::GradientStyle eNewStyle) { eStyle = eNewStyle; }
    void SetStartColor(const Color& rColor)         { aStartColor = rColor; }
    void SetEndColor(const Color& rColor)           { aEndColor = rColor; }
    void SetColorStops(const basegfx::ColorStops& rSteps);
    void SetAngle(Degree10 nNewAngle)                { nAngle = nNewAngle; }
    void SetBorder(sal_uInt16 nNewBorder)               { nBorder = nNewBorder; }
    void SetXOffset(sal_uInt16 nNewOffset)              { nOfsX = nNewOffset; }
@@ -66,8 +66,7 @@ public:
    void SetSteps(sal_uInt16 nSteps)                    { nStepCount = nSteps; }

    css::awt::GradientStyle GetGradientStyle() const         { return eStyle; }
    const Color&       GetStartColor() const            { return aStartColor; }
    const Color&       GetEndColor() const              { return aEndColor; }
    const basegfx::ColorStops& GetColorStops() const { return aColorStops; }
    Degree10           GetAngle() const                 { return nAngle; }
    sal_uInt16         GetBorder() const                { return nBorder; }
    sal_uInt16         GetXOffset() const               { return nOfsX; }
@@ -78,7 +77,7 @@ public:

    boost::property_tree::ptree dumpAsJSON() const;
    static XGradient fromJSON(std::u16string_view rJSON);
    css::awt::Gradient toGradientUNO() const;
    css::awt::Gradient2 toGradientUNO() const;
};

#endif
diff --git a/offapi/UnoApi_offapi.mk b/offapi/UnoApi_offapi.mk
index 5a59260..bdae567 100644
--- a/offapi/UnoApi_offapi.mk
+++ b/offapi/UnoApi_offapi.mk
@@ -1714,6 +1714,8 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/awt,\
	AdjustmentEvent \
	AdjustmentType \
	CharSet \
	ColorStop \
	ColorStopSequence \
	Command \
	DeviceCapability \
	DeviceInfo \
@@ -1737,6 +1739,7 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/awt,\
	FontWeight \
	FontWidth \
	Gradient \
	Gradient2 \
	GradientStyle \
	ImageDrawMode \
	ImageAlign \
diff --git a/offapi/com/sun/star/awt/ColorStop.idl b/offapi/com/sun/star/awt/ColorStop.idl
new file mode 100644
index 0000000..7b67aa2
--- /dev/null
+++ b/offapi/com/sun/star/awt/ColorStop.idl
@@ -0,0 +1,32 @@
/* -*- 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/.
 */



 module com {  module sun {  module star {  module awt {


/** defines a Color-Stop entry for a gradient definition
 */
struct ColorStop
{
    /** specifies the offset.
     */
    double StopOffset;

    /** contains the color value.
     */
    // com::sun::star::util::Color StopColor;
    com::sun::star::rendering::RGBColor StopColor;
};


}; }; }; };

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/awt/ColorStopSequence.idl b/offapi/com/sun/star/awt/ColorStopSequence.idl
new file mode 100644
index 0000000..05d3e61
--- /dev/null
+++ b/offapi/com/sun/star/awt/ColorStopSequence.idl
@@ -0,0 +1,17 @@
/* -*- 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/.
 */


module com { module sun { module star { module awt {

typedef sequence<com::sun::star::awt::ColorStop> ColorStopSequence;

}; }; }; };

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/offapi/com/sun/star/awt/Gradient2.idl b/offapi/com/sun/star/awt/Gradient2.idl
new file mode 100644
index 0000000..c9d3865
--- /dev/null
+++ b/offapi/com/sun/star/awt/Gradient2.idl
@@ -0,0 +1,26 @@
/* -*- 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/.
 */


module com { module sun { module star { module awt {

/** This struct extends the Gradient definition by adding a sequence
    of ColorStops to allow definition of multi-color gradients.
  */
struct Gradient2 : Gradient
{
    /** contains the full multi-color gradient definition.
      */
    com::sun::star::awt::ColorStopSequence ColorStops;
};


}; }; }; };

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/reportdesign/source/ui/misc/UITools.cxx b/reportdesign/source/ui/misc/UITools.cxx
index ae54ed3..e928bbd 100644
--- a/reportdesign/source/ui/misc/UITools.cxx
+++ b/reportdesign/source/ui/misc/UITools.cxx
@@ -625,7 +625,9 @@ bool openCharDialog( const uno::Reference<report::XReportControlFormat >& _rxRep
    XColorListRef pColorList( XColorList::CreateStdColorList() );
    const ::Color aNullLineCol(COL_DEFAULT_SHAPE_STROKE); // #i121448# Use defined default color
    const ::Color aNullFillCol(COL_DEFAULT_SHAPE_FILLING); // #i121448# Use defined default color
    const XGradient aNullGrad(COL_BLACK, COL_WHITE);
    // XGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
    const XGradient aNullGrad;

    const XHatch aNullHatch(aNullLineCol);
    std::vector<SfxPoolItem*> pDefaults
    {
diff --git a/reportdesign/source/ui/report/ReportController.cxx b/reportdesign/source/ui/report/ReportController.cxx
index 0266e14..d2dcb50 100644
--- a/reportdesign/source/ui/report/ReportController.cxx
+++ b/reportdesign/source/ui/report/ReportController.cxx
@@ -2373,7 +2373,8 @@ void OReportController::openPageDialog(const uno::Reference<report::XSection>& _

    const ::Color aNullLineCol(COL_DEFAULT_SHAPE_STROKE); // #i121448# Use defined default color
    const ::Color aNullFillCol(COL_DEFAULT_SHAPE_FILLING); // #i121448# Use defined default color
    const XGradient aNullGrad(COL_BLACK, COL_WHITE);
    // XGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
    const XGradient aNullGrad;
    const XHatch aNullHatch(aNullLineCol);

    std::vector<SfxPoolItem*> pDefaults
diff --git a/sc/qa/unit/subsequent_filters_test3.cxx b/sc/qa/unit/subsequent_filters_test3.cxx
index c2e76d2..7b2407c 100644
--- a/sc/qa/unit/subsequent_filters_test3.cxx
+++ b/sc/qa/unit/subsequent_filters_test3.cxx
@@ -1626,8 +1626,12 @@ CPPUNIT_TEST_FIXTURE(ScFiltersTest3, testTdf129789)

        CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, rStyleItemH2.GetValue());
        const XFillGradientItem& rGradientItem = pCaptionH2->GetMergedItem(XATTR_FILLGRADIENT);
        CPPUNIT_ASSERT_EQUAL(Color(0xdde8cb), rGradientItem.GetGradientValue().GetStartColor());
        CPPUNIT_ASSERT_EQUAL(Color(0xffd7d7), rGradientItem.GetGradientValue().GetEndColor());
        CPPUNIT_ASSERT_EQUAL(
            Color(0xdde8cb),
            Color(rGradientItem.GetGradientValue().GetColorStops().front().getStopColor()));
        CPPUNIT_ASSERT_EQUAL(
            Color(0xffd7d7),
            Color(rGradientItem.GetGradientValue().GetColorStops().back().getStopColor()));

        SdrCaptionObj* const pCaptionH9 = checkCaption(*pDoc, ScAddress(7, 8, 0), false);

@@ -1635,8 +1639,12 @@ CPPUNIT_TEST_FIXTURE(ScFiltersTest3, testTdf129789)

        CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, rStyleItemH9.GetValue());
        const XFillGradientItem& rGradientItem2 = pCaptionH2->GetMergedItem(XATTR_FILLGRADIENT);
        CPPUNIT_ASSERT_EQUAL(Color(0xdde8cb), rGradientItem2.GetGradientValue().GetStartColor());
        CPPUNIT_ASSERT_EQUAL(Color(0xffd7d7), rGradientItem2.GetGradientValue().GetEndColor());
        CPPUNIT_ASSERT_EQUAL(
            Color(0xdde8cb),
            Color(rGradientItem2.GetGradientValue().GetColorStops().front().getStopColor()));
        CPPUNIT_ASSERT_EQUAL(
            Color(0xffd7d7),
            Color(rGradientItem2.GetGradientValue().GetColorStops().back().getStopColor()));
    }

    {
diff --git a/sd/qa/unit/uiimpress.cxx b/sd/qa/unit/uiimpress.cxx
index 5cf0de0..d9f71fc 100644
--- a/sd/qa/unit/uiimpress.cxx
+++ b/sd/qa/unit/uiimpress.cxx
@@ -764,8 +764,8 @@ CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testPageFillGradient)
    CPPUNIT_ASSERT_EQUAL(drawing::FillStyle_GRADIENT, eXFS);

    XGradient aGradient = rPageAttr.GetItem(XATTR_FILLGRADIENT)->GetGradientValue();
    CPPUNIT_ASSERT_EQUAL(Color(0xff0000), aGradient.GetStartColor());
    CPPUNIT_ASSERT_EQUAL(Color(0x0000ff), aGradient.GetEndColor());
    CPPUNIT_ASSERT_EQUAL(Color(0xff0000), Color(aGradient.GetColorStops().front().getStopColor()));
    CPPUNIT_ASSERT_EQUAL(Color(0x0000ff), Color(aGradient.GetColorStops().back().getStopColor()));
}

CPPUNIT_TEST_FIXTURE(SdUiImpressTest, testTdf134053)
diff --git a/sd/source/core/drawdoc4.cxx b/sd/source/core/drawdoc4.cxx
index c487c04..b697be2 100644
--- a/sd/source/core/drawdoc4.cxx
+++ b/sd/source/core/drawdoc4.cxx
@@ -154,7 +154,10 @@ void SdDrawDocument::CreateLayoutTemplates()
    Color    aNullCol(COL_DEFAULT_SHAPE_STROKE);

    XDash     aNullDash;
    XGradient aNullGrad(aNullCol,COL_WHITE);
    XGradient aNullGrad(
        basegfx::utils::createColorStopsFromStartEndColor(
            aNullCol.getBColor(),
            COL_WHITE.getBColor()));
    aNullGrad.SetStartIntens( 100 );
    aNullGrad.SetEndIntens( 100 );
    XHatch    aNullHatch(aNullCol);
@@ -414,8 +417,12 @@ void SdDrawDocument::CreateLayoutTemplates()
        pISet->Put(XFillStyleItem(drawing::FillStyle_GRADIENT));           // fill with gradient
        aGradient.SetGradientStyle( ::awt::GradientStyle_RECT);            // square type
        aGradient.SetAngle( 0_deg10 );                                 // 0° angle
        aGradient.SetStartColor( Color(0xcccccc) );                        // white
        aGradient.SetEndColor( COL_WHITE );                                // light gray 3

        aGradient.SetColorStops(
            basegfx::utils::createColorStopsFromStartEndColor(
                Color(0xcccccc).getBColor(),    // light gray 3
                COL_WHITE.getBColor())); // white

        aFillGradient.SetName( aShapesName );
        aFillGradient.SetGradientValue(aGradient);
        pISet->Put( aFillGradient );
@@ -434,8 +441,12 @@ void SdDrawDocument::CreateLayoutTemplates()

        aGradient.SetGradientStyle( ::awt::GradientStyle_LINEAR );
        aGradient.SetAngle( 300_deg10 );
        aGradient.SetStartColor( COL_WHITE );                              // white
        aGradient.SetEndColor( Color(0xcccccc) );                          // light gray 3

        aGradient.SetColorStops(
            basegfx::utils::createColorStopsFromStartEndColor(
                COL_WHITE.getBColor(),  // white
                Color(0xcccccc).getBColor())); // light gray 3

        aFillGradient.SetName( aName );
        aFillGradient.SetGradientValue(aGradient);
        pISet->Put( XFillStyleItem(drawing::FillStyle_GRADIENT) );
@@ -449,8 +460,11 @@ void SdDrawDocument::CreateLayoutTemplates()
        pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED_BLUE );
        pISet = &pSheet->GetItemSet();

        aGradient.SetStartColor( Color(0x00729fcf) );                   // light blue 2
        aGradient.SetEndColor( Color(0x00355269) );                     // dark blue 2
        aGradient.SetColorStops(
            basegfx::utils::createColorStopsFromStartEndColor(
                Color(0x00729fcf).getBColor(),   // light blue 2
                Color(0x00355269).getBColor())); // dark blue 2

        aFillGradient.SetName( aName );
        aFillGradient.SetGradientValue(aGradient);
        pISet->Put( aFillGradient );
@@ -464,8 +478,11 @@ void SdDrawDocument::CreateLayoutTemplates()
        pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED_GREEN );
        pISet = &pSheet->GetItemSet();

        aGradient.SetStartColor( Color(0x0077bc65) );                   // light green 2
        aGradient.SetEndColor( Color(0x00127622) );                     // dark green 2
        aGradient.SetColorStops(
            basegfx::utils::createColorStopsFromStartEndColor(
                Color(0x0077bc65).getBColor(),   // light green 2
                Color(0x00127622).getBColor())); // dark green 2

        aFillGradient.SetName( aName );
        aFillGradient.SetGradientValue(aGradient);
        pISet->Put( aFillGradient );
@@ -480,8 +497,11 @@ void SdDrawDocument::CreateLayoutTemplates()
        pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED_RED );
        pISet = &pSheet->GetItemSet();

        aGradient.SetStartColor( Color(0x00ff6d6d) );                   // light red 2
        aGradient.SetEndColor( Color(0x00c9211e) );                     // dark red 2
        aGradient.SetColorStops(
            basegfx::utils::createColorStopsFromStartEndColor(
                Color(0x00ff6d6d).getBColor(),   // light red 2
                Color(0x00c9211e).getBColor())); // dark red 2

        aFillGradient.SetName( aName );
        aFillGradient.SetGradientValue(aGradient);
        pISet->Put( aFillGradient );
@@ -495,8 +515,11 @@ void SdDrawDocument::CreateLayoutTemplates()
        pSheet->SetHelpId( aHelpFile, HID_POOLSHEET_FILLED_YELLOW );
        pISet = &pSheet->GetItemSet();

        aGradient.SetStartColor( Color(0x00ffde59) );                   // light gold 2
        aGradient.SetEndColor( Color(0x00b47804) );                     // dark gold 2
        aGradient.SetColorStops(
            basegfx::utils::createColorStopsFromStartEndColor(
                Color(0x00ffde59).getBColor(),   // light gold 2
                Color(0x00b47804).getBColor())); // dark gold 2

        aFillGradient.SetName( aName );
        aFillGradient.SetGradientValue(aGradient);
        pISet->Put( aFillGradient );
diff --git a/sd/source/ui/sidebar/SlideBackground.cxx b/sd/source/ui/sidebar/SlideBackground.cxx
index 5f8bcff..101b8c6 100644
--- a/sd/source/ui/sidebar/SlideBackground.cxx
+++ b/sd/source/ui/sidebar/SlideBackground.cxx
@@ -399,9 +399,9 @@ void SlideBackground::Update()
            mxFillGrad2->show();

            const XGradient xGradient = GetGradientSetOrDefault();
            const Color aStartColor = xGradient.GetStartColor();
            const Color aStartColor(xGradient.GetColorStops().front().getStopColor());
            mxFillGrad1->SelectEntry(aStartColor);
            const Color aEndColor = xGradient.GetEndColor();
            const Color aEndColor(xGradient.GetColorStops().back().getStopColor());
            mxFillGrad2->SelectEntry(aEndColor);
        }
        break;
@@ -1127,9 +1127,10 @@ IMPL_LINK_NOARG(SlideBackground, FillColorHdl, ColorListBox&, void)
        break;
        case drawing::FillStyle_GRADIENT:
        {
            XGradient aGradient;
            aGradient.SetStartColor(mxFillGrad1->GetSelectEntryColor());
            aGradient.SetEndColor(mxFillGrad2->GetSelectEntryColor());
            XGradient aGradient(
                basegfx::utils::createColorStopsFromStartEndColor(
                    mxFillGrad1->GetSelectEntryColor().getBColor(),
                    mxFillGrad2->GetSelectEntryColor().getBColor()));

            // the name doesn't really matter, it'll be converted to unique one eventually,
            // but it has to be non-empty
diff --git a/sd/source/ui/view/drviews9.cxx b/sd/source/ui/view/drviews9.cxx
index 274fdaf..f0a6cae4 100644
--- a/sd/source/ui/view/drviews9.cxx
+++ b/sd/source/ui/view/drviews9.cxx
@@ -347,9 +347,18 @@ void DrawViewShell::AttrExec (SfxRequest &rReq)
                    if (pEntry->GetName () == pName->GetValue ())
                    {
                        XGradient aGradient(pEntry->GetGradient());
                        basegfx::ColorStops aNewColorStops(aGradient.GetColorStops());

                        if (rReq.GetSlot () == SID_SETGRADSTARTCOLOR) aGradient.SetStartColor (aColor);
                        else aGradient.SetEndColor (aColor);
                        if (SID_SETGRADSTARTCOLOR == rReq.GetSlot ())
                        {
                            basegfx::utils::replaceStartColor(aNewColorStops, aColor.getBColor());
                        }
                        else
                        {
                            basegfx::utils::replaceEndColor(aNewColorStops, aColor.getBColor());
                        }

                        aGradient.SetColorStops(aNewColorStops);

                        XFillStyleItem aStyleItem(drawing::FillStyle_GRADIENT);
                        aStyleItem.SetWhich(XATTR_FILLSTYLE);
@@ -364,12 +373,14 @@ void DrawViewShell::AttrExec (SfxRequest &rReq)
                if (i >= nCounts)
                {
                    Color aBlack (0, 0, 0);
                    XGradient aGradient ((rReq.GetSlot () == SID_SETGRADSTARTCOLOR)
                                             ? aColor
                                             : aBlack,
                                         (rReq.GetSlot () == SID_SETGRADENDCOLOR)
                                             ? aColor
                                             : aBlack);
                    XGradient aGradient (
                        basegfx::utils::createColorStopsFromStartEndColor(
                            (rReq.GetSlot () == SID_SETGRADSTARTCOLOR)
                                             ? aColor.getBColor()
                                             : aBlack.getBColor(),
                            (rReq.GetSlot () == SID_SETGRADENDCOLOR)
                                             ? aColor.getBColor()
                                             : aBlack.getBColor()));

                    GetDoc()->GetGradientList()->Insert(std::make_unique<XGradientEntry>(aGradient, pName->GetValue()));

@@ -568,10 +579,12 @@ void DrawViewShell::AttrExec (SfxRequest &rReq)
                    if (i >= nCounts)
                    {
                        Color aBlack (0, 0, 0);
                        XGradient aGradient (aBlack, aBlack, static_cast<css::awt::GradientStyle>(pStyle->GetValue ()),
                                             Degree10(pAngle->GetValue () * 10), static_cast<short>(pCenterX->GetValue ()),
                                             static_cast<short>(pCenterY->GetValue ()), static_cast<short>(pBorder->GetValue ()),
                                             static_cast<short>(pStart->GetValue ()), static_cast<short>(pEnd->GetValue ()));
                        XGradient aGradient (
                            basegfx::utils::createColorStopsFromStartEndColor(aBlack.getBColor(), aBlack.getBColor()),
                            static_cast<css::awt::GradientStyle>(pStyle->GetValue ()),
                            Degree10(pAngle->GetValue () * 10), static_cast<short>(pCenterX->GetValue ()),
                            static_cast<short>(pCenterY->GetValue ()), static_cast<short>(pBorder->GetValue ()),
                            static_cast<short>(pStart->GetValue ()), static_cast<short>(pEnd->GetValue ()));

                        pGradientList->Insert(std::make_unique<XGradientEntry>(aGradient, pName->GetValue()));
                        XFillStyleItem aStyleItem(drawing::FillStyle_GRADIENT);
@@ -854,8 +867,8 @@ void DrawViewShell::AttrState (SfxItemSet& rSet)
                        const XGradient         &rGradient         = rFillGradientItem.GetGradientValue ();

                        aColor = (rWhatKind.GetValue () == 3)
                                    ? rGradient.GetStartColor ()
                                    : rGradient.GetEndColor ();
                                    ? Color(rGradient.GetColorStops().front().getStopColor())
                                    : Color(rGradient.GetColorStops().back().getStopColor());
                        break;
                    }

diff --git a/svx/source/customshapes/EnhancedCustomShape2d.cxx b/svx/source/customshapes/EnhancedCustomShape2d.cxx
index d93dbee..e6b0173 100644
--- a/svx/source/customshapes/EnhancedCustomShape2d.cxx
+++ b/svx/source/customshapes/EnhancedCustomShape2d.cxx
@@ -2804,16 +2804,17 @@ void EnhancedCustomShape2d::AdaptObjColor(

            if ( nColorCount || 0.0 != dBrightness )
            {
                aXGradient.SetStartColor(
                    GetColorData(
                        aXGradient.GetStartColor(),
                        std::min(nColorIndex, nColorCount-1),
                        dBrightness ));
                aXGradient.SetEndColor(
                    GetColorData(
                        aXGradient.GetEndColor(),
                        std::min(nColorIndex, nColorCount-1),
                        dBrightness ));
                basegfx::ColorStops aColorStops(aXGradient.GetColorStops());
                for (auto& candidate : aColorStops)
                {
                    candidate = basegfx::ColorStop(
                        candidate.getStopOffset(),
                        GetColorData(
                            Color(candidate.getStopColor()),
                            std::min(nColorIndex, nColorCount-1),
                            dBrightness ).getBColor());
                }
                aXGradient.SetColorStops(aColorStops);
            }

            rObj.SetMergedItem( XFillGradientItem( "", aXGradient ) );
diff --git a/svx/source/sdr/attribute/sdrallfillattributeshelper.cxx b/svx/source/sdr/attribute/sdrallfillattributeshelper.cxx
index 720adcf..6a96870 100644
--- a/svx/source/sdr/attribute/sdrallfillattributeshelper.cxx
+++ b/svx/source/sdr/attribute/sdrallfillattributeshelper.cxx
@@ -152,8 +152,8 @@ namespace drawinglayer::attribute

                if(!rFillTransparenceGradientAttribute.isDefault())
                {
                    const double fTransA(rFillTransparenceGradientAttribute.getColorSteps().front().getColor().luminance());
                    const double fTransB(rFillTransparenceGradientAttribute.getColorSteps().back().getColor().luminance());
                    const double fTransA(rFillTransparenceGradientAttribute.getColorStops().front().getStopColor().luminance());
                    const double fTransB(rFillTransparenceGradientAttribute.getColorStops().back().getStopColor().luminance());

                    fTransparence = (fTransA + fTransB) * 0.5;
                }
@@ -161,8 +161,8 @@ namespace drawinglayer::attribute
                if(!rFillGradientAttribute.isDefault())
                {
                    // gradient fill
                    const basegfx::BColor aStart(rFillGradientAttribute.getColorSteps().front().getColor());
                    const basegfx::BColor aEnd(rFillGradientAttribute.getColorSteps().back().getColor());
                    const basegfx::BColor aStart(rFillGradientAttribute.getColorStops().front().getStopColor());
                    const basegfx::BColor aEnd(rFillGradientAttribute.getColorStops().back().getStopColor());

                    aRetval = basegfx::interpolate(aStart, aEnd, 0.5);
                }
diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
index 0e0369b..7409c40 100644
--- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx
+++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
@@ -444,8 +444,8 @@ namespace drawinglayer::primitive2d
                        && pGradientItem->IsEnabled())
                    {
                        const XGradient& rGradient = pGradientItem->GetGradientValue();
                        const sal_uInt8 nStartLuminance(rGradient.GetStartColor().GetLuminance());
                        const sal_uInt8 nEndLuminance(rGradient.GetEndColor().GetLuminance());
                        const sal_uInt8 nStartLuminance(Color(rGradient.GetColorStops().front().getStopColor()).GetLuminance());
                        const sal_uInt8 nEndLuminance(Color(rGradient.GetColorStops().back().getStopColor()).GetLuminance());
                        const bool bCompletelyTransparent(0xff == nStartLuminance && 0xff == nEndLuminance);

                        if(bCompletelyTransparent)
@@ -472,62 +472,36 @@ namespace drawinglayer::primitive2d
                        case drawing::FillStyle_GRADIENT :
                        {
                            XGradient aXGradient(rSet.Get(XATTR_FILLGRADIENT).GetGradientValue());

                            const Color aStartColor(aXGradient.GetStartColor());
                            const sal_uInt16 nStartIntens(aXGradient.GetStartIntens());
                            basegfx::BColor aStart(aStartColor.getBColor());

                            if(nStartIntens != 100)
                            {
                                const basegfx::BColor aBlack;
                                aStart = interpolate(aBlack, aStart, static_cast<double>(nStartIntens) * 0.01);
                            }

                            const Color aEndColor(aXGradient.GetEndColor());
                            const sal_uInt16 nEndIntens(aXGradient.GetEndIntens());
                            basegfx::BColor aEnd(aEndColor.getBColor());

                            if(nEndIntens != 100)
                            {
                                const basegfx::BColor aBlack;
                                aEnd = interpolate(aBlack, aEnd, static_cast<double>(nEndIntens) * 0.01);
                            }

                            // prepare ColorSteps
                            // currently always two (Start/EndColor) to stay compatible
                            // for now, but that will change. It already gets manipulated
                            // by the test cases below
                            basegfx::ColorSteps aColorSteps {
                                basegfx::ColorStep(0.0, aStart),
                                basegfx::ColorStep(1.0, aEnd) };
                            basegfx::ColorStops aColorStops(aXGradient.GetColorStops());

                            // test code here, can/will be removed later
                            static sal_uInt32 nUseGradientSteps(0);

                            switch(nUseGradientSteps)
                            {
                                case 1:
                                {
                                    // just test a nice valid gradient
                                    aColorSteps.clear();
                                    aColorSteps.emplace_back(0.0, basegfx::BColor(1.0, 0.0, 0.0)); // red
                                    aColorSteps.emplace_back(0.25, basegfx::BColor(0.0, 1.0, 0.0)); // green@25%
                                    aColorSteps.emplace_back(0.50, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorSteps.emplace_back(0.75, basegfx::BColor(1.0, 0.0, 1.0)); // pink@75%
                                    aColorSteps.emplace_back(1.0, basegfx::BColor(0.0, 0.0, 1.0)); // blue
                                    aColorStops.clear();
                                    aColorStops.emplace_back(0.0, basegfx::BColor(1.0, 0.0, 0.0)); // red
                                    aColorStops.emplace_back(0.25, basegfx::BColor(0.0, 1.0, 0.0)); // green@25%
                                    aColorStops.emplace_back(0.50, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.75, basegfx::BColor(1.0, 0.0, 1.0)); // pink@75%
                                    aColorStops.emplace_back(1.0, basegfx::BColor(0.0, 0.0, 1.0)); // blue
                                    break;
                                }

                                case 2:
                                {
                                    // single added in-between, no change of start/end
                                    aColorSteps.emplace_back(0.5, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.5, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    break;
                                }

                                case 3:
                                {
                                    // check additional StartColor, the one given directly has to win
                                    aColorSteps.emplace_back(0.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    break;
                                }

@@ -535,63 +509,63 @@ namespace drawinglayer::primitive2d
                                {
                                    // check additional EndColor, the one given directly has to win
                                    // due this one being added *after* the original one
                                    aColorSteps.emplace_back(1.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(1.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    break;
                                }

                                case 5:
                                {
                                    // check invalid color (too low index), has to be ignored
                                    aColorSteps.emplace_back(-1.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(-1.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    break;
                                }

                                case 6:
                                {
                                    // check invalid color (too high index), has to be ignored
                                    aColorSteps.emplace_back(2.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(2.0, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    break;
                                }

                                case 7:
                                {
                                    // check in-between single-color section
                                    aColorSteps.emplace_back(0.3, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorSteps.emplace_back(0.7, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.3, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.7, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    break;
                                }

                                case 8:
                                {
                                    // check in-between single-color sections
                                    aColorSteps.emplace_back(0.2, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorSteps.emplace_back(0.4, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorSteps.emplace_back(0.5, aStart);
                                    aColorSteps.emplace_back(0.6, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorSteps.emplace_back(0.8, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.2, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.4, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.5, aXGradient.GetColorStops().front().getStopColor());
                                    aColorStops.emplace_back(0.6, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    aColorStops.emplace_back(0.8, basegfx::BColor(1.0, 1.0, 0.0)); // yellow@50%
                                    break;
                                }

                                case 9:
                                {
                                    // check single-color start area
                                    aColorSteps.emplace_back(0.6, aStart);
                                    aColorStops.emplace_back(0.6, aXGradient.GetColorStops().front().getStopColor());
                                    break;
                                }

                                case 10:
                                {
                                    // check single-color end area
                                    aColorSteps.emplace_back(0.4, aEnd);
                                    aColorStops.emplace_back(0.4, aXGradient.GetColorStops().back().getStopColor());
                                    break;
                                }

                                case 11:
                                {
                                    // check case without direct Start/EndColor
                                    aColorSteps.clear();
                                    aColorSteps.emplace_back(0.4, aEnd);
                                    aColorSteps.emplace_back(0.6, aStart);
                                    aColorStops.clear();
                                    aColorStops.emplace_back(0.4, aXGradient.GetColorStops().back().getStopColor());
                                    aColorStops.emplace_back(0.6, aXGradient.GetColorStops().front().getStopColor());
                                    break;
                                }

@@ -601,13 +575,32 @@ namespace drawinglayer::primitive2d
                                }
                            }

                            if(aXGradient.GetStartIntens() != 100 || aXGradient.GetEndIntens() != 100)
                            {
                                // Need to do the (old, crazy) blend against black for a
                                // used intensity, but now for all ColorStops relative to their
                                // offsets, where 0 means black and 100 means original color
                                const double fStartIntensity(aXGradient.GetStartIntens() * 0.01);
                                const double fEndIntensity(aXGradient.GetEndIntens() * 0.01);
                                const basegfx::BColor aBlack;

                                for (auto& candidate : aColorStops)
                                {
                                    const double fOffset(candidate.getStopOffset());
                                    const double fIntensity((fStartIntensity * (1.0 - fOffset)) + (fEndIntensity * fOffset));
                                    candidate = basegfx::ColorStop(
                                        fOffset,
                                        basegfx::interpolate(aBlack, candidate.getStopColor(), fIntensity));
                                }
                            }

                            aGradient = attribute::FillGradientAttribute(
                                XGradientStyleToGradientStyle(aXGradient.GetGradientStyle()),
                                static_cast<double>(aXGradient.GetBorder()) * 0.01,
                                static_cast<double>(aXGradient.GetXOffset()) * 0.01,
                                static_cast<double>(aXGradient.GetYOffset()) * 0.01,
                                toRadians(aXGradient.GetAngle()),
                                aColorSteps,
                                aColorStops,
                                rSet.Get(XATTR_GRADIENTSTEPCOUNT).GetValue());

                            break;
@@ -747,8 +740,8 @@ namespace drawinglayer::primitive2d
            {
                // test if float transparence is completely transparent
                const XGradient& rGradient = pGradientItem->GetGradientValue();
                const sal_uInt8 nStartLuminance(rGradient.GetStartColor().GetLuminance());
                const sal_uInt8 nEndLuminance(rGradient.GetEndColor().GetLuminance());
                const sal_uInt8 nStartLuminance(Color(rGradient.GetColorStops().front().getStopColor()).GetLuminance());
                const sal_uInt8 nEndLuminance(Color(rGradient.GetColorStops().back().getStopColor()).GetLuminance());
                const bool bCompletelyTransparent(0xff == nStartLuminance && 0xff == nEndLuminance);
                const bool bNotTransparent(0x00 == nStartLuminance && 0x00 == nEndLuminance);

@@ -761,17 +754,15 @@ namespace drawinglayer::primitive2d
                    const double fStartLum(nStartLuminance / 255.0);
                    const double fEndLum(nEndLuminance / 255.0);

                    const basegfx::ColorSteps aColorSteps {
                        basegfx::ColorStep(0.0, basegfx::BColor(fStartLum, fStartLum, fStartLum)),
                        basegfx::ColorStep(1.0, basegfx::BColor(fEndLum, fEndLum, fEndLum)) };

                    return attribute::FillGradientAttribute(
                        XGradientStyleToGradientStyle(rGradient.GetGradientStyle()),
                        static_cast<double>(rGradient.GetBorder()) * 0.01,
                        static_cast<double>(rGradient.GetXOffset()) * 0.01,
                        static_cast<double>(rGradient.GetYOffset()) * 0.01,
                        toRadians(rGradient.GetAngle()),
                        aColorSteps);
                        basegfx::utils::createColorStopsFromStartEndColor(
                            basegfx::BColor(fStartLum, fStartLum, fStartLum),
                            basegfx::BColor(fEndLum, fEndLum, fEndLum)));
                }
            }

diff --git a/svx/source/sidebar/area/AreaPropertyPanelBase.cxx b/svx/source/sidebar/area/AreaPropertyPanelBase.cxx
index e54002e..33c5382 100644
--- a/svx/source/sidebar/area/AreaPropertyPanelBase.cxx
+++ b/svx/source/sidebar/area/AreaPropertyPanelBase.cxx
@@ -127,8 +127,10 @@ void AreaPropertyPanelBase::Initialize()
    maGradientLinear.SetXOffset(DEFAULT_CENTERX);
    maGradientLinear.SetYOffset(DEFAULT_CENTERY);
    maGradientLinear.SetAngle(Degree10(DEFAULT_ANGLE));
    maGradientLinear.SetStartColor(Color(DEFAULT_STARTVALUE));
    maGradientLinear.SetEndColor(Color(DEFAULT_ENDVALUE));
    maGradientLinear.SetColorStops(
        basegfx::utils::createColorStopsFromStartEndColor(
            Color(DEFAULT_STARTVALUE).getBColor(),
            Color(DEFAULT_ENDVALUE).getBColor()));
    maGradientLinear.SetBorder(DEFAULT_BORDER);
    maGradientLinear.SetGradientStyle(css::awt::GradientStyle_LINEAR);

@@ -295,11 +297,12 @@ void AreaPropertyPanelBase::SelectFillAttrHdl_Impl()

            if (pSh && pSh->GetItem(SID_COLOR_TABLE))
            {
                XGradient aGradient;
                XGradient aGradient(
                    basegfx::utils::createColorStopsFromStartEndColor(
                        mxLbFillGradFrom->GetSelectEntryColor().getBColor(),
                        mxLbFillGradTo->GetSelectEntryColor().getBColor()));
                aGradient.SetAngle(Degree10(mxMTRAngle->get_value(FieldUnit::DEGREE) * 10));
                aGradient.SetGradientStyle(static_cast<css::awt::GradientStyle>(mxGradientStyle->get_active()));
                aGradient.SetStartColor(mxLbFillGradFrom->GetSelectEntryColor());
                aGradient.SetEndColor(mxLbFillGradTo->GetSelectEntryColor());

                const XFillGradientItem aXFillGradientItem(mxLbFillAttr->get_active_text(), aGradient);

@@ -485,8 +488,8 @@ void AreaPropertyPanelBase::FillStyleChanged(bool bUpdateModel)
                    // #i122676# change FillStyle and Gradient in one call
                    XFillStyleItem aXFillStyleItem(drawing::FillStyle_GRADIENT);
                    setFillStyleAndGradient(&aXFillStyleItem, aXFillGradientItem);
                    mxLbFillGradFrom->SelectEntry(aGradient.GetStartColor());
                    mxLbFillGradTo->SelectEntry(aGradient.GetEndColor());
                    mxLbFillGradFrom->SelectEntry(Color(aGradient.GetColorStops().front().getStopColor()));
                    mxLbFillGradTo->SelectEntry(Color(aGradient.GetColorStops().back().getStopColor()));

                    mxMTRAngle->set_value(toDegrees(aGradient.GetAngle()), FieldUnit::DEGREE);
                    css::awt::GradientStyle eXGS = aGradient.GetGradientStyle();
@@ -506,8 +509,8 @@ void AreaPropertyPanelBase::FillStyleChanged(bool bUpdateModel)
                        const OUString aString(mpFillGradientItem->GetName());
                        mxLbFillAttr->set_active_text(aString);
                        const XGradient aGradient = mpFillGradientItem->GetGradientValue();
                        mxLbFillGradFrom->SelectEntry(aGradient.GetStartColor());
                        mxLbFillGradTo->SelectEntry(aGradient.GetEndColor());
                        mxLbFillGradFrom->SelectEntry(Color(aGradient.GetColorStops().front().getStopColor()));
                        mxLbFillGradTo->SelectEntry(Color(aGradient.GetColorStops().back().getStopColor()));
                        mxGradientStyle->set_active(
                            sal::static_int_cast<sal_Int32>(aGradient.GetGradientStyle()));
                        if (mxGradientStyle->get_active() == sal_Int32(GradientStyle::Radial))
diff --git a/svx/source/sidebar/area/AreaTransparencyGradientPopup.cxx b/svx/source/sidebar/area/AreaTransparencyGradientPopup.cxx
index 2d92b6b..4cbfa7b 100644
--- a/svx/source/sidebar/area/AreaTransparencyGradientPopup.cxx
+++ b/svx/source/sidebar/area/AreaTransparencyGradientPopup.cxx
@@ -59,13 +59,15 @@ void AreaTransparencyGradientPopup::InitStatus(XFillFloatTransparenceItem const 
    const XGradient& rGradient = pGradientItem->GetGradientValue();

    XGradient aGradient;
    Color aStart(rGradient.GetColorStops().front().getStopColor());
    Color aEnd(rGradient.GetColorStops().back().getStopColor());

    if (rGradient.GetXOffset() == AreaPropertyPanelBase::DEFAULT_CENTERX
        && rGradient.GetYOffset() == AreaPropertyPanelBase::DEFAULT_CENTERY
        && static_cast<sal_Int32>(toDegrees(rGradient.GetAngle())) == AreaPropertyPanelBase::DEFAULT_ANGLE
        && static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetStartColor().GetRed()) + 1) * 100) / 255)
        && static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aStart.GetRed()) + 1) * 100) / 255)
            == AreaPropertyPanelBase::DEFAULT_STARTVALUE
        && static_cast<sal_uInt16>(((static_cast<sal_uInt16>(rGradient.GetEndColor().GetRed()) + 1) * 100) / 255)
        && static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aEnd.GetRed()) + 1) * 100) / 255)
            == AreaPropertyPanelBase::DEFAULT_ENDVALUE
        && rGradient.GetBorder() == AreaPropertyPanelBase::DEFAULT_BORDER)
    {
@@ -78,8 +80,10 @@ void AreaTransparencyGradientPopup::InitStatus(XFillFloatTransparenceItem const 
    mxMtrTrgrCenterX->set_value(aGradient.GetXOffset(), FieldUnit::PERCENT);
    mxMtrTrgrCenterY->set_value(aGradient.GetYOffset(), FieldUnit::PERCENT);
    mxMtrTrgrAngle->set_value(toDegrees(aGradient.GetAngle()), FieldUnit::DEGREE);
    mxMtrTrgrStartValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aGradient.GetStartColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
    mxMtrTrgrEndValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aGradient.GetEndColor().GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
    aStart = Color(aGradient.GetColorStops().front().getStopColor());
    aEnd = Color(aGradient.GetColorStops().back().getStopColor());
    mxMtrTrgrStartValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aStart.GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
    mxMtrTrgrEndValue->set_value(static_cast<sal_uInt16>(((static_cast<sal_uInt16>(aEnd.GetRed()) + 1) * 100) / 255), FieldUnit::PERCENT);
    mxMtrTrgrBorder->set_value(aGradient.GetBorder(), FieldUnit::PERCENT);
}

@@ -122,8 +126,9 @@ void AreaTransparencyGradientPopup::ExecuteValueModify(sal_uInt8 nStartCol, sal_
    mxMtrTrgrAngle->set_value(nVal, FieldUnit::DEGREE);
    //End of new code
    XGradient aTmpGradient(
        Color(nStartCol, nStartCol, nStartCol),
        Color(nEndCol, nEndCol, nEndCol),
        basegfx::utils::createColorStopsFromStartEndColor(
            Color(nStartCol, nStartCol, nStartCol).getBColor(),
            Color(nEndCol, nEndCol, nEndCol).getBColor()),
        static_cast<css::awt::GradientStyle>(mrAreaPropertyPanel.GetSelectedTransparencyTypeIndex()-2),
        Degree10(static_cast<sal_Int16>(mxMtrTrgrAngle->get_value(FieldUnit::DEGREE)) * 10),
        static_cast<sal_uInt16>(mxMtrTrgrCenterX->get_value(FieldUnit::PERCENT)),
diff --git a/svx/source/svdraw/gradtrns.cxx b/svx/source/svdraw/gradtrns.cxx
index d665cd4..c559e58 100644
--- a/svx/source/svdraw/gradtrns.cxx
+++ b/svx/source/svdraw/gradtrns.cxx
@@ -30,7 +30,7 @@
void GradTransformer::GradToVec(GradTransGradient const & rG, GradTransVector& rV, const SdrObject* pObj)
{
    // handle start color
    rV.aCol1 = rG.aGradient.GetStartColor();
    rV.aCol1 = Color(rG.aGradient.GetColorStops().front().getStopColor());
    if(100 != rG.aGradient.GetStartIntens())
    {
        const double fFact(static_cast<double>(rG.aGradient.GetStartIntens()) / 100.0);
@@ -38,7 +38,7 @@ void GradTransformer::GradToVec(GradTransGradient const & rG, GradTransVector& r
    }

    // handle end color
    rV.aCol2 = rG.aGradient.GetEndColor();
    rV.aCol2 = Color(rG.aGradient.GetColorStops().back().getStopColor());
    if(100 != rG.aGradient.GetEndIntens())
    {
        const double fFact(static_cast<double>(rG.aGradient.GetEndIntens()) / 100.0);
@@ -186,14 +186,18 @@ void GradTransformer::VecToGrad(GradTransVector const & rV, GradTransGradient& r
    rG = rGOld;

    // handle color changes
    if(rV.aCol1 != rGOld.aGradient.GetStartColor())
    if(rV.aCol1 != Color(rGOld.aGradient.GetColorStops().front().getStopColor()))
    {
        rG.aGradient.SetStartColor(rV.aCol1);
        basegfx::ColorStops aNewColorStops(rG.aGradient.GetColorStops());
        basegfx::utils::replaceStartColor(aNewColorStops, rV.aCol1.getBColor());
        rG.aGradient.SetColorStops(aNewColorStops);
        rG.aGradient.SetStartIntens(100);
    }
    if(rV.aCol2 != rGOld.aGradient.GetEndColor())
    if(rV.aCol2 != Color(rGOld.aGradient.GetColorStops().back().getStopColor()))
    {
        rG.aGradient.SetEndColor(rV.aCol2);
        basegfx::ColorStops aNewColorStops(rG.aGradient.GetColorStops());
        basegfx::utils::replaceEndColor(aNewColorStops, rV.aCol2.getBColor());
        rG.aGradient.SetColorStops(aNewColorStops);
        rG.aGradient.SetEndIntens(100);
    }

diff --git a/svx/source/svdraw/svdetc.cxx b/svx/source/svdraw/svdetc.cxx
index 4163900..97da369 100644
--- a/svx/source/svdraw/svdetc.cxx
+++ b/svx/source/svdraw/svdetc.cxx
@@ -272,8 +272,8 @@ bool GetDraftFillColor(const SfxItemSet& rSet, Color& rCol)
        }
        case drawing::FillStyle_GRADIENT: {
            const XGradient& rGrad=rSet.Get(XATTR_FILLGRADIENT).GetGradientValue();
            Color aCol1(rGrad.GetStartColor());
            Color aCol2(rGrad.GetEndColor());
            Color aCol1(Color(rGrad.GetColorStops().front().getStopColor()));
            Color aCol2(Color(rGrad.GetColorStops().back().getStopColor()));
            const basegfx::BColor aAverageColor(basegfx::average(aCol1.getBColor(), aCol2.getBColor()));
            rCol = Color(aAverageColor);
            bRetval = true;
diff --git a/svx/source/svdraw/svdfmtf.cxx b/svx/source/svdraw/svdfmtf.cxx
index eb1c964..86cb829 100644
--- a/svx/source/svdraw/svdfmtf.cxx
+++ b/svx/source/svdraw/svdfmtf.cxx
@@ -1245,11 +1245,12 @@ void ImpSdrGDIMetaFileImport::DoAction( MetaCommentAction const & rAct, GDIMetaF
                        std::move(aSource));
                    // #i125211# Use the ranges from the SdrObject to create a new empty SfxItemSet
                    SfxItemSet aGradAttr(mpModel->GetItemPool(), pPath->GetMergedItemSet().GetRanges());
                    XGradient aXGradient;
                    XGradient aXGradient(
                        basegfx::utils::createColorStopsFromStartEndColor(
                            rGrad.GetStartColor().getBColor(),
                            rGrad.GetEndColor().getBColor()));

                    aXGradient.SetGradientStyle(static_cast<css::awt::GradientStyle>(rGrad.GetStyle()));
                    aXGradient.SetStartColor(rGrad.GetStartColor());
                    aXGradient.SetEndColor(rGrad.GetEndColor());
                    aXGradient.SetAngle(rGrad.GetAngle());
                    aXGradient.SetBorder(rGrad.GetBorder());
                    aXGradient.SetXOffset(rGrad.GetOfsX());
@@ -1442,8 +1443,9 @@ void ImpSdrGDIMetaFileImport::DoAction(MetaGradientAction const & rAct)
    const css::awt::GradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
    const XFillGradientItem aXFillGradientItem(
        XGradient(
            rGradient.GetStartColor(),
            rGradient.GetEndColor(),
            basegfx::utils::createColorStopsFromStartEndColor(
                rGradient.GetStartColor().getBColor(),
                rGradient.GetEndColor().getBColor()),
            aXGradientStyle,
            rGradient.GetAngle(),
            rGradient.GetOfsX(),
@@ -1504,8 +1506,9 @@ void ImpSdrGDIMetaFileImport::DoAction(MetaGradientExAction const & rAct)
    const css::awt::GradientStyle aXGradientStyle(getXGradientStyleFromGradientStyle(rGradient.GetStyle()));
    const XFillGradientItem aXFillGradientItem(
        XGradient(
            rGradient.GetStartColor(),
            rGradient.GetEndColor(),
            basegfx::utils::createColorStopsFromStartEndColor(
                rGradient.GetStartColor().getBColor(),
                rGradient.GetEndColor().getBColor()),
            aXGradientStyle,
            rGradient.GetAngle(),
            rGradient.GetOfsX(),
diff --git a/svx/source/svdraw/svdoashp.cxx b/svx/source/svdraw/svdoashp.cxx
index 63a987e..a2db44a 100644
--- a/svx/source/svdraw/svdoashp.cxx
+++ b/svx/source/svdraw/svdoashp.cxx
@@ -303,8 +303,8 @@ static rtl::Reference<SdrObject> ImpCreateShadowObjectClone(const SdrObject& rOr
        if(bGradientFillUsed)
        {
            XGradient aGradient(rOriginalSet.Get(XATTR_FILLGRADIENT).GetGradientValue());
            sal_uInt8 nStartLuminance(aGradient.GetStartColor().GetLuminance());
            sal_uInt8 nEndLuminance(aGradient.GetEndColor().GetLuminance());
            sal_uInt8 nStartLuminance(Color(aGradient.GetColorStops().front().getStopColor()).GetLuminance());
            sal_uInt8 nEndLuminance(Color(aGradient.GetColorStops().back().getStopColor()).GetLuminance());

            if(aGradient.GetStartIntens() != 100)
            {
@@ -326,8 +326,10 @@ static rtl::Reference<SdrObject> ImpCreateShadowObjectClone(const SdrObject& rOr
                static_cast<sal_uInt8>((nEndLuminance * aShadowColor.GetGreen()) / 256),
                static_cast<sal_uInt8>((nEndLuminance * aShadowColor.GetBlue()) / 256));

            aGradient.SetStartColor(aStartColor);
            aGradient.SetEndColor(aEndColor);
            aGradient.SetColorStops(
                basegfx::utils::createColorStopsFromStartEndColor(
                    aStartColor.getBColor(),
                    aEndColor.getBColor()));
            aTempSet.Put(XFillGradientItem(aGradient));
            aTempSet.Put(XFillTransparenceItem(nShadowTransparence));
        }
diff --git a/svx/source/unodraw/XPropertyTable.cxx b/svx/source/unodraw/XPropertyTable.cxx
index c110533..586bba3 100644
--- a/svx/source/unodraw/XPropertyTable.cxx
+++ b/svx/source/unodraw/XPropertyTable.cxx
@@ -536,8 +536,8 @@ uno::Any SvxUnoXGradientTable::getAny( const XPropertyEntry* pEntry ) const noex
    awt::Gradient aGradient;

    aGradient.Style = aXGradient.GetGradientStyle();
    aGradient.StartColor = static_cast<sal_Int32>(aXGradient.GetStartColor());
    aGradient.EndColor = static_cast<sal_Int32>(aXGradient.GetEndColor());
    aGradient.StartColor = static_cast<sal_Int32>(Color(aXGradient.GetColorStops().front().getStopColor()));
    aGradient.EndColor = static_cast<sal_Int32>(Color(aXGradient.GetColorStops().back().getStopColor()));
    aGradient.Angle = static_cast<short>(aXGradient.GetAngle());
    aGradient.Border = aXGradient.GetBorder();
    aGradient.XOffset = aXGradient.GetXOffset();
@@ -555,11 +555,12 @@ std::unique_ptr<XPropertyEntry> SvxUnoXGradientTable::createEntry(const OUString
    if(!(rAny >>= aGradient))
        return std::unique_ptr<XPropertyEntry>();

    XGradient aXGradient;
    XGradient aXGradient(
        basegfx::utils::createColorStopsFromStartEndColor(
            Color(ColorTransparency, aGradient.StartColor).getBColor(),
            Color(ColorTransparency, aGradient.EndColor).getBColor()));

    aXGradient.SetGradientStyle( aGradient.Style );
    aXGradient.SetStartColor( Color(ColorTransparency, aGradient.StartColor) );
    aXGradient.SetEndColor( Color(ColorTransparency, aGradient.EndColor) );
    aXGradient.SetAngle( Degree10(aGradient.Angle) );
    aXGradient.SetBorder( aGradient.Border );
    aXGradient.SetXOffset( aGradient.XOffset );
diff --git a/svx/source/unodraw/unobrushitemhelper.cxx b/svx/source/unodraw/unobrushitemhelper.cxx
index bc9d047..ba0924b 100644
--- a/svx/source/unodraw/unobrushitemhelper.cxx
+++ b/svx/source/unodraw/unobrushitemhelper.cxx
@@ -157,8 +157,8 @@ static sal_uInt16 getTransparenceForSvxBrushItem(const SfxItemSet& rSourceSet, b
        && pGradientItem->IsEnabled())
    {
        const XGradient& rGradient = pGradientItem->GetGradientValue();
        const sal_uInt16 nStartLuminance(rGradient.GetStartColor().GetLuminance());
        const sal_uInt16 nEndLuminance(rGradient.GetEndColor().GetLuminance());
        const sal_uInt16 nStartLuminance(Color(rGradient.GetColorStops().front().getStopColor()).GetLuminance());
        const sal_uInt16 nEndLuminance(Color(rGradient.GetColorStops().back().getStopColor()).GetLuminance());

        // luminance is [0..255], transparence needs to be in [0..100].Maximum is 51200, thus sal_uInt16 is okay to use
        nFillTransparence = static_cast< sal_uInt16 >(((nStartLuminance + nEndLuminance) * 100) / 512);
@@ -224,8 +224,8 @@ std::unique_ptr<SvxBrushItem> getSvxBrushItemFromSourceSet(const SfxItemSet& rSo
        {
            // cannot be directly supported, but do the best possible
            const XGradient aXGradient(rSourceSet.Get(XATTR_FILLGRADIENT).GetGradientValue());
            const basegfx::BColor aStartColor(aXGradient.GetStartColor().getBColor() * (aXGradient.GetStartIntens() * 0.01));
            const basegfx::BColor aEndColor(aXGradient.GetEndColor().getBColor() * (aXGradient.GetEndIntens() * 0.01));
            const basegfx::BColor aStartColor(aXGradient.GetColorStops().front().getStopColor() * (aXGradient.GetStartIntens() * 0.01));
            const basegfx::BColor aEndColor(aXGradient.GetColorStops().back().getStopColor() * (aXGradient.GetEndIntens() * 0.01));

            // use half/half mixed color from gradient start and end
            Color aMixedColor((aStartColor + aEndColor) * 0.5);
diff --git a/svx/source/xoutdev/xattr.cxx b/svx/source/xoutdev/xattr.cxx
index f0d17db..64df042 100644
--- a/svx/source/xoutdev/xattr.cxx
+++ b/svx/source/xoutdev/xattr.cxx
@@ -27,7 +27,7 @@
#include <com/sun/star/drawing/LineDash.hpp>
#include <com/sun/star/drawing/DashStyle.hpp>
#include <com/sun/star/drawing/FillStyle.hpp>
#include <com/sun/star/awt/Gradient.hpp>
#include <com/sun/star/awt/Gradient2.hpp>
#include <com/sun/star/uno/Sequence.hxx>
#include <com/sun/star/beans/PropertyValue.hpp>

@@ -2159,10 +2159,11 @@ namespace

    XGradient lcl_buildGradientFromStringMap(StringMap& rMap)
    {
        XGradient aGradient;
        XGradient aGradient(
            basegfx::utils::createColorStopsFromStartEndColor(
                Color(ColorTransparency, rMap["startcolor"].toInt32(16)).getBColor(),
                Color(ColorTransparency, rMap["endcolor"].toInt32(16)).getBColor()));

        aGradient.SetStartColor(Color(ColorTransparency, rMap["startcolor"].toInt32(16)));
        aGradient.SetEndColor(Color(ColorTransparency, rMap["endcolor"].toInt32(16)));
        aGradient.SetGradientStyle(lcl_getStyleFromString(rMap["style"]));
        aGradient.SetAngle(Degree10(rMap["angle"].toInt32()));

@@ -2176,28 +2177,43 @@ XGradient XGradient::fromJSON(std::u16string_view rJSON)
    return lcl_buildGradientFromStringMap(aMap);
}

css::awt::Gradient XGradient::toGradientUNO() const
namespace
{
    css::awt::Gradient aGradient;
    void fillGradient2FromXGradient(css::awt::Gradient2& rGradient2, const XGradient& rXGradient)
    {
        // standard values
        rGradient2.Style = rXGradient.GetGradientStyle();
        rGradient2.Angle = static_cast<short>(rXGradient.GetAngle());
        rGradient2.Border = rXGradient.GetBorder();
        rGradient2.XOffset = rXGradient.GetXOffset();
        rGradient2.YOffset = rXGradient.GetYOffset();
        rGradient2.StartIntensity = rXGradient.GetStartIntens();
        rGradient2.EndIntensity = rXGradient.GetEndIntens();
        rGradient2.StepCount = rXGradient.GetSteps();

    aGradient.Style = this->GetGradientStyle();
    aGradient.StartColor = static_cast<sal_Int32>(this->GetStartColor());
    aGradient.EndColor = static_cast<sal_Int32>(this->GetEndColor());
    aGradient.Angle = static_cast<short>(this->GetAngle());
    aGradient.Border = this->GetBorder();
    aGradient.XOffset = this->GetXOffset();
    aGradient.YOffset = this->GetYOffset();
    aGradient.StartIntensity = this->GetStartIntens();
    aGradient.EndIntensity = this->GetEndIntens();
    aGradient.StepCount = this->GetSteps();
        // for compatibility, still set StartColor/EndColor
        const basegfx::ColorStops& rColorStops(rXGradient.GetColorStops());
        rGradient2.StartColor = static_cast<sal_Int32>(Color(rColorStops.front().getStopColor()));
        rGradient2.EndColor = static_cast<sal_Int32>(Color(rColorStops.back().getStopColor()));

    return aGradient;
        // fill ColorStops to extended Gradient2
        basegfx::utils::fillColorStopSequenceFromColorStops(rGradient2.ColorStops, rColorStops);
    }
}

css::awt::Gradient2 XGradient::toGradientUNO() const
{
    css::awt::Gradient2 aGradient2;

    // fill values
    fillGradient2FromXGradient(aGradient2, *this);

    return aGradient2;
}

XGradient::XGradient() :
    eStyle( css::awt::GradientStyle_LINEAR ),
    aStartColor( COL_BLACK ),
    aEndColor( COL_WHITE ),
    aColorStops(),
    nAngle( 0 ),
    nBorder( 0 ),
    nOfsX( 50 ),
@@ -2206,16 +2222,17 @@ XGradient::XGradient() :
    nIntensEnd( 100 ),
    nStepCount( 0 )
{
    aColorStops.emplace_back(0.0, COL_BLACK.getBColor());
    aColorStops.emplace_back(1.0, COL_WHITE.getBColor());
}

XGradient::XGradient(const Color& rStart, const Color& rEnd,
XGradient::XGradient(const basegfx::ColorStops& rColorStops,
                     css::awt::GradientStyle eTheStyle, Degree10 nTheAngle, sal_uInt16 nXOfs,
                     sal_uInt16 nYOfs, sal_uInt16 nTheBorder,
                     sal_uInt16 nStartIntens, sal_uInt16 nEndIntens,
                     sal_uInt16 nSteps) :
    eStyle(eTheStyle),
    aStartColor(rStart),
    aEndColor(rEnd),
    aColorStops(rColorStops),
    nAngle(nTheAngle),
    nBorder(nTheBorder),
    nOfsX(nXOfs),
@@ -2224,13 +2241,13 @@ XGradient::XGradient(const Color& rStart, const Color& rEnd,
    nIntensEnd(nEndIntens),
    nStepCount(nSteps)
{
    SetColorStops(aColorStops);
}

bool XGradient::operator==(const XGradient& rGradient) const
{
    return ( eStyle         == rGradient.eStyle         &&
             aStartColor    == rGradient.aStartColor    &&
             aEndColor      == rGradient.aEndColor      &&
             aColorStops    == rGradient.aColorStops    &&
             nAngle         == rGradient.nAngle         &&
             nBorder        == rGradient.nBorder        &&
             nOfsX          == rGradient.nOfsX          &&
@@ -2240,13 +2257,21 @@ bool XGradient::operator==(const XGradient& rGradient) const
             nStepCount     == rGradient.nStepCount );
}

void XGradient::SetColorStops(const basegfx::ColorStops& rSteps)
{
    aColorStops = rSteps;
    basegfx::utils::sortAndCorrectColorStops(aColorStops);
    if (aColorStops.empty())
        aColorStops.emplace_back(0.0, basegfx::BColor());
}

boost::property_tree::ptree XGradient::dumpAsJSON() const
{
    boost::property_tree::ptree aTree;

    aTree.put("style", XGradient::GradientStyleToString(eStyle));
    aTree.put("startcolor",aStartColor.AsRGBHexString());
    aTree.put("endcolor", aEndColor.AsRGBHexString());
    aTree.put("startcolor", Color(GetColorStops().front().getStopColor()).AsRGBHexString());
    aTree.put("endcolor", Color(GetColorStops().back().getStopColor()).AsRGBHexString());
    aTree.put("angle", std::to_string(nAngle.get()));
    aTree.put("border", std::to_string(nBorder));
    aTree.put("x", std::to_string(nOfsX));
@@ -2318,6 +2343,37 @@ bool XFillGradientItem::GetPresentation
    return true;
}

namespace
{
    void fillXGradientFromAny(XGradient& rXGradient, const css::uno::Any& rVal)
    {
        css::awt::Gradient aGradient;
        if (!(rVal >>= aGradient))
            return;

        // for compatibility, read and set StartColor/EndColor
        rXGradient.SetColorStops(basegfx::utils::createColorStopsFromStartEndColor(
            Color(ColorTransparency, aGradient.StartColor).getBColor(),
            Color(ColorTransparency, aGradient.EndColor).getBColor()));

        // set values
        rXGradient.SetGradientStyle( aGradient.Style );
        rXGradient.SetAngle( Degree10(aGradient.Angle) );
        rXGradient.SetBorder( aGradient.Border );
        rXGradient.SetXOffset( aGradient.XOffset );
        rXGradient.SetYOffset( aGradient.YOffset );
        rXGradient.SetStartIntens( aGradient.StartIntensity );
        rXGradient.SetEndIntens( aGradient.EndIntensity );
        rXGradient.SetSteps( aGradient.StepCount );

        // check if we have a awt::Gradient2 with a ColorStopSequence
        basegfx::ColorStops aColorStops;
        basegfx::utils::fillColorStopsFromAny(aColorStops, rVal);
        if (!aColorStops.empty())
            rXGradient.SetColorStops(aColorStops);
    }
}

bool XFillGradientItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) const
{
    nMemberId &= ~CONVERT_TWIPS;
@@ -2325,20 +2381,12 @@ bool XFillGradientItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) c
    {
        case 0:
        {
            css::awt::Gradient aGradient2;
            css::awt::Gradient2 aGradient2;

            const XGradient& aXGradient = GetGradientValue();
            aGradient2.Style = aXGradient.GetGradientStyle();
            aGradient2.StartColor = static_cast<sal_Int32>(aXGradient.GetStartColor());
            aGradient2.EndColor = static_cast<sal_Int32>(aXGradient.GetEndColor());
            aGradient2.Angle = static_cast<short>(aXGradient.GetAngle());
            aGradient2.Border = aXGradient.GetBorder();
            aGradient2.XOffset = aXGradient.GetXOffset();
            aGradient2.YOffset = aXGradient.GetYOffset();
            aGradient2.StartIntensity = aXGradient.GetStartIntens();
            aGradient2.EndIntensity = aXGradient.GetEndIntens();
            aGradient2.StepCount = aXGradient.GetSteps();
            // fill values
            fillGradient2FromXGradient(aGradient2, GetGradientValue());

            // create sequence
            uno::Sequence< beans::PropertyValue > aPropSeq{
                comphelper::makePropertyValue("Name", SvxUnogetApiNameForItem(Which(), GetName())),
                comphelper::makePropertyValue("FillGradient", aGradient2)
@@ -2349,20 +2397,12 @@ bool XFillGradientItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) c

        case MID_FILLGRADIENT:
        {
            const XGradient& aXGradient = GetGradientValue();
            css::awt::Gradient aGradient2;
            css::awt::Gradient2 aGradient2;

            aGradient2.Style = aXGradient.GetGradientStyle();
            aGradient2.StartColor = static_cast<sal_Int32>(aXGradient.GetStartColor());
            aGradient2.EndColor = static_cast<sal_Int32>(aXGradient.GetEndColor());
            aGradient2.Angle = static_cast<short>(aXGradient.GetAngle());
            aGradient2.Border = aXGradient.GetBorder();
            aGradient2.XOffset = aXGradient.GetXOffset();
            aGradient2.YOffset = aXGradient.GetYOffset();
            aGradient2.StartIntensity = aXGradient.GetStartIntens();
            aGradient2.EndIntensity = aXGradient.GetEndIntens();
            aGradient2.StepCount = aXGradient.GetSteps();
            // fill values
            fillGradient2FromXGradient(aGradient2, GetGradientValue());

            // create sequence
            rVal <<= aGradient2;
            break;
        }
@@ -2373,9 +2413,21 @@ bool XFillGradientItem::QueryValue( css::uno::Any& rVal, sal_uInt8 nMemberId ) c
            break;
        }

        case MID_GRADIENT_COLORSTOPSEQUENCE:
        {
            css::awt::ColorStopSequence aColorStopSequence;

            // fill values
            basegfx::utils::fillColorStopSequenceFromColorStops(aColorStopSequence, GetGradientValue().GetColorStops());

            // create sequence
            rVal <<= aColorStopSequence;
            break;
        }

        case MID_GRADIENT_STYLE: rVal <<= static_cast<sal_Int16>(GetGradientValue().GetGradientStyle()); break;
        case MID_GRADIENT_STARTCOLOR: rVal <<= GetGradientValue().GetStartColor(); break;
        case MID_GRADIENT_ENDCOLOR: rVal <<= GetGradientValue().GetEndColor(); break;
        case MID_GRADIENT_STARTCOLOR: rVal <<= Color(GetGradientValue().GetColorStops().front().getStopColor()); break;
        case MID_GRADIENT_ENDCOLOR: rVal <<= Color(GetGradientValue().GetColorStops().back().getStopColor()); break;
        case MID_GRADIENT_ANGLE: rVal <<= static_cast<sal_Int16>(GetGradientValue().GetAngle()); break;
        case MID_GRADIENT_BORDER: rVal <<= GetGradientValue().GetBorder(); break;
        case MID_GRADIENT_XOFFSET: rVal <<= GetGradientValue().GetXOffset(); break;
@@ -2399,40 +2451,27 @@ bool XFillGradientItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId
        case 0:
        {
            uno::Sequence< beans::PropertyValue >   aPropSeq;
            css::uno::Any aGradientAny;

            if ( rVal >>= aPropSeq )
            {
                css::awt::Gradient aGradient2;
                OUString aName;
                bool bGradient( false );

                for ( const auto& rProp : std::as_const(aPropSeq) )
                {
                    if ( rProp.Name == "Name" )
                        rProp.Value >>= aName;
                    else if ( rProp.Name == "FillGradient" )
                    {
                        if ( rProp.Value >>= aGradient2 )
                            bGradient = true;
                    }
                        aGradientAny = rProp.Value;
                }

                SetName( aName );
                if ( bGradient )

                if ( aGradientAny.hasValue() )
                {
                    XGradient aXGradient;

                    aXGradient.SetGradientStyle( aGradient2.Style );
                    aXGradient.SetStartColor( Color(ColorTransparency, aGradient2.StartColor) );
                    aXGradient.SetEndColor( Color(ColorTransparency, aGradient2.EndColor) );
                    aXGradient.SetAngle( Degree10(aGradient2.Angle) );
                    aXGradient.SetBorder( aGradient2.Border );
                    aXGradient.SetXOffset( aGradient2.XOffset );
                    aXGradient.SetYOffset( aGradient2.YOffset );
                    aXGradient.SetStartIntens( aGradient2.StartIntensity );
                    aXGradient.SetEndIntens( aGradient2.EndIntensity );
                    aXGradient.SetSteps( aGradient2.StepCount );

                    SetGradientValue( aXGradient );
                    fillXGradientFromAny(aXGradient, aGradientAny);
                    SetGradientValue(aXGradient);
                }

                return true;
@@ -2452,24 +2491,23 @@ bool XFillGradientItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId

        case MID_FILLGRADIENT:
        {
            css::awt::Gradient aGradient2;
            if(!(rVal >>= aGradient2))
                return false;

            XGradient aXGradient;
            fillXGradientFromAny(aXGradient, rVal);
            SetGradientValue(aXGradient);
            break;
        }

            aXGradient.SetGradientStyle( aGradient2.Style );
            aXGradient.SetStartColor( Color(ColorTransparency, aGradient2.StartColor) );
            aXGradient.SetEndColor( Color(ColorTransparency, aGradient2.EndColor) );
            aXGradient.SetAngle( Degree10(aGradient2.Angle) );
            aXGradient.SetBorder( aGradient2.Border );
            aXGradient.SetXOffset( aGradient2.XOffset );
            aXGradient.SetYOffset( aGradient2.YOffset );
            aXGradient.SetStartIntens( aGradient2.StartIntensity );
            aXGradient.SetEndIntens( aGradient2.EndIntensity );
            aXGradient.SetSteps( aGradient2.StepCount );

            SetGradientValue( aXGradient );
        case MID_GRADIENT_COLORSTOPSEQUENCE:
        {
            // check if we have a awt::Gradient2 with a ColorStopSequence
            basegfx::ColorStops aColorStops;
            basegfx::utils::fillColorStopsFromAny(aColorStops, rVal);
            if (!aColorStops.empty())
            {
                XGradient aXGradient(GetGradientValue());
                aXGradient.SetColorStops(aColorStops);
                SetGradientValue(aXGradient);
            }
            break;
        }

@@ -2480,12 +2518,19 @@ bool XFillGradientItem::PutValue( const css::uno::Any& rVal, sal_uInt8 nMemberId
            if(!(rVal >>= nVal ))
                return false;

            XGradient aXGradient = GetGradientValue();
            XGradient aXGradient(GetGradientValue());
            basegfx::ColorStops aNewColorStops(aXGradient.GetColorStops());

            if ( nMemberId == MID_GRADIENT_STARTCOLOR )
                aXGradient.SetStartColor( nVal );
            {
                basegfx::utils::replaceStartColor(aNewColorStops, nVal.getBColor());
            }
            else
                aXGradient.SetEndColor( nVal );
            {
                basegfx::utils::replaceEndColor(aNewColorStops, nVal.getBColor());
            }

            aXGradient.SetColorStops(aNewColorStops);
            SetGradientValue( aXGradient );
            break;
        }
diff --git a/svx/source/xoutdev/xpool.cxx b/svx/source/xoutdev/xpool.cxx
index 65a096d..5294092 100644
--- a/svx/source/xoutdev/xpool.cxx
+++ b/svx/source/xoutdev/xpool.cxx
@@ -108,7 +108,10 @@ XOutdevItemPool::XOutdevItemPool(SfxItemPool* _pMaster)
    rPoolDefaults[XATTR_LINECAP            -XATTR_START] = new XLineCapItem;
    rPoolDefaults[XATTR_FILLSTYLE                -XATTR_START] = new XFillStyleItem;
    rPoolDefaults[XATTR_FILLCOLOR                -XATTR_START] = new XFillColorItem   (aNullStr,aNullFillCol);
    rPoolDefaults[XATTR_FILLGRADIENT         -XATTR_START] = new XFillGradientItem(XGradient(COL_BLACK, COL_WHITE));

    // XGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
    rPoolDefaults[XATTR_FILLGRADIENT         -XATTR_START] = new XFillGradientItem(XGradient());

    rPoolDefaults[XATTR_FILLHATCH                -XATTR_START] = new XFillHatchItem   (aNullHatch);
    rPoolDefaults[XATTR_FILLBITMAP               -XATTR_START] = new XFillBitmapItem  (Graphic());
    rPoolDefaults[XATTR_FILLTRANSPARENCE     -XATTR_START] = new XFillTransparenceItem;
@@ -123,7 +126,14 @@ XOutdevItemPool::XOutdevItemPool(SfxItemPool* _pMaster)
    rPoolDefaults[XATTR_FILLBMP_STRETCH      -XATTR_START] = new XFillBmpStretchItem;
    rPoolDefaults[XATTR_FILLBMP_POSOFFSETX       -XATTR_START] = new XFillBmpPosOffsetXItem;
    rPoolDefaults[XATTR_FILLBMP_POSOFFSETY       -XATTR_START] = new XFillBmpPosOffsetYItem;
    rPoolDefaults[XATTR_FILLFLOATTRANSPARENCE    -XATTR_START] = new XFillFloatTransparenceItem( XGradient(COL_BLACK, COL_BLACK), false );

    rPoolDefaults[XATTR_FILLFLOATTRANSPARENCE    -XATTR_START] = new XFillFloatTransparenceItem(
        XGradient(
            basegfx::utils::createColorStopsFromStartEndColor(
                COL_BLACK.getBColor(),
                COL_BLACK.getBColor())),
                false);

    rPoolDefaults[XATTR_SECONDARYFILLCOLOR       -XATTR_START] = new XSecondaryFillColorItem(aNullStr, aNullFillCol);
    rPoolDefaults[XATTR_FILLBACKGROUND           -XATTR_START] = new XFillBackgroundItem;
    rPoolDefaults[XATTR_FILLUSESLIDEBACKGROUND   -XATTR_START] = new XFillUseSlideBackgroundItem;
diff --git a/svx/source/xoutdev/xtabgrdt.cxx b/svx/source/xoutdev/xtabgrdt.cxx
index 219ee28..e44141d 100644
--- a/svx/source/xoutdev/xtabgrdt.cxx
+++ b/svx/source/xoutdev/xtabgrdt.cxx
@@ -69,17 +69,20 @@ bool XGradientList::Create()
    OUStringBuffer aStr(SvxResId(RID_SVXSTR_GRADIENT));
    aStr.append(" 1");
    sal_Int32 nLen = aStr.getLength() - 1;
    Insert(std::make_unique<XGradientEntry>(XGradient(COL_BLACK,   COL_WHITE, css::awt::GradientStyle_LINEAR    ,    0_deg10,10,10, 0,100,100),aStr.toString()));

    // XGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
    Insert(std::make_unique<XGradientEntry>(XGradient(),aStr.toString()));

    aStr[nLen] = '2';
    Insert(std::make_unique<XGradientEntry>(XGradient(COL_BLUE,    COL_RED,   css::awt::GradientStyle_AXIAL     ,  300_deg10,20,20,10,100,100),aStr.toString()));
    Insert(std::make_unique<XGradientEntry>(XGradient(basegfx::utils::createColorStopsFromStartEndColor(COL_BLUE.getBColor(),    COL_RED.getBColor()),     css::awt::GradientStyle_AXIAL     ,  300_deg10,20,20,10,100,100),aStr.toString()));
    aStr[nLen] = '3';
    Insert(std::make_unique<XGradientEntry>(XGradient(COL_RED,     COL_YELLOW,css::awt::GradientStyle_RADIAL    ,  600_deg10,30,30,20,100,100),aStr.toString()));
    Insert(std::make_unique<XGradientEntry>(XGradient(basegfx::utils::createColorStopsFromStartEndColor(COL_RED.getBColor(),     COL_YELLOW.getBColor()),  css::awt::GradientStyle_RADIAL    ,  600_deg10,30,30,20,100,100),aStr.toString()));
    aStr[nLen] = '4';
    Insert(std::make_unique<XGradientEntry>(XGradient(COL_YELLOW , COL_GREEN, css::awt::GradientStyle_ELLIPTICAL,  900_deg10,40,40,30,100,100),aStr.toString()));
    Insert(std::make_unique<XGradientEntry>(XGradient(basegfx::utils::createColorStopsFromStartEndColor(COL_YELLOW.getBColor(),  COL_GREEN.getBColor()),   css::awt::GradientStyle_ELLIPTICAL,  900_deg10,40,40,30,100,100),aStr.toString()));
    aStr[nLen] = '5';
    Insert(std::make_unique<XGradientEntry>(XGradient(COL_GREEN  , COL_MAGENTA,css::awt::GradientStyle_SQUARE    , 1200_deg10,50,50,40,100,100),aStr.toString()));
    Insert(std::make_unique<XGradientEntry>(XGradient(basegfx::utils::createColorStopsFromStartEndColor(COL_GREEN.getBColor(),   COL_MAGENTA.getBColor()), css::awt::GradientStyle_SQUARE    , 1200_deg10,50,50,40,100,100),aStr.toString()));
    aStr[nLen] = '6';
    Insert(std::make_unique<XGradientEntry>(XGradient(COL_MAGENTA, COL_YELLOW ,css::awt::GradientStyle_RECT      , 1900_deg10,60,60,50,100,100),aStr.toString()));
    Insert(std::make_unique<XGradientEntry>(XGradient(basegfx::utils::createColorStopsFromStartEndColor(COL_MAGENTA.getBColor(), COL_YELLOW.getBColor()),  css::awt::GradientStyle_RECT      , 1900_deg10,60,60,50,100,100),aStr.toString()));

    return true;
}
@@ -100,7 +103,7 @@ BitmapEx XGradientList::CreateBitmap( tools::Long nIndex, const Size& rSize ) co

        const XGradient& rGradient = GetGradient(nIndex)->GetGradient();
        const sal_uInt16 nStartIntens(rGradient.GetStartIntens());
        basegfx::BColor aStart(rGradient.GetStartColor().getBColor());
        basegfx::BColor aStart(rGradient.GetColorStops().front().getStopColor());

        if(nStartIntens != 100)
        {
@@ -109,7 +112,7 @@ BitmapEx XGradientList::CreateBitmap( tools::Long nIndex, const Size& rSize ) co
        }

        const sal_uInt16 nEndIntens(rGradient.GetEndIntens());
        basegfx::BColor aEnd(rGradient.GetEndColor().getBColor());
        basegfx::BColor aEnd(rGradient.GetColorStops().back().getStopColor());

        if(nEndIntens != 100)
        {
@@ -153,17 +156,13 @@ BitmapEx XGradientList::CreateBitmap( tools::Long nIndex, const Size& rSize ) co
            }
        }

        const basegfx::ColorSteps aColorSteps {
            basegfx::ColorStep(0.0, aStart),
            basegfx::ColorStep(1.0, aEnd) };

        drawinglayer::attribute::FillGradientAttribute aFillGradient(
            aGradientStyle,
            static_cast<double>(rGradient.GetBorder()) * 0.01,
            static_cast<double>(rGradient.GetXOffset()) * 0.01,
            static_cast<double>(rGradient.GetYOffset()) * 0.01,
            toRadians(rGradient.GetAngle()),
            aColorSteps);
            basegfx::utils::createColorStopsFromStartEndColor(aStart, aEnd));

        const drawinglayer::primitive2d::Primitive2DReference aGradientPrimitive(
            new drawinglayer::primitive2d::PolyPolygonGradientPrimitive2D(
diff --git a/sw/source/core/unocore/unoframe.cxx b/sw/source/core/unocore/unoframe.cxx
index 15701a5..a55e4d9 100644
--- a/sw/source/core/unocore/unoframe.cxx
+++ b/sw/source/core/unocore/unoframe.cxx
@@ -377,7 +377,8 @@ bool BaseFrameProperties_Impl::FillBaseProperties(SfxItemSet& rToSet, const SfxI
        {
            if(pXFillGradientItem)
            {
                const XGradient aNullGrad(COL_BLACK, COL_WHITE);
                // XGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
                const XGradient aNullGrad;
                XFillGradientItem aXFillGradientItem(aNullGrad);

                aXFillGradientItem.PutValue(*pXFillGradientItem, MID_FILLGRADIENT);
@@ -519,7 +520,8 @@ bool BaseFrameProperties_Impl::FillBaseProperties(SfxItemSet& rToSet, const SfxI
        {
            if(pXFillFloatTransparenceItem)
            {
                const XGradient aNullGrad(COL_BLACK, COL_WHITE);
                // XGradient() default already creates [COL_BLACK, COL_WHITE] as defaults
                const XGradient aNullGrad;
                XFillFloatTransparenceItem aXFillFloatTransparenceItem(aNullGrad, false);

                aXFillFloatTransparenceItem.PutValue(*pXFillFloatTransparenceItem, MID_FILLGRADIENT);
diff --git a/sw/source/filter/ww8/docxattributeoutput.cxx b/sw/source/filter/ww8/docxattributeoutput.cxx
index 1b1afa1..6577bf1 100644
--- a/sw/source/filter/ww8/docxattributeoutput.cxx
+++ b/sw/source/filter/ww8/docxattributeoutput.cxx
@@ -9360,8 +9360,8 @@ void DocxAttributeOutput::FormatFillGradient( const XFillGradientItem& rFillGrad
        AddToAttrList( m_rExport.SdrExporter().getFlyFillAttrList(), XML_type, "gradient" );

        const XGradient& rGradient = rFillGradient.GetGradientValue();
        OString sStartColor = msfilter::util::ConvertColor(rGradient.GetStartColor());
        OString sEndColor = msfilter::util::ConvertColor(rGradient.GetEndColor());
        OString sStartColor = msfilter::util::ConvertColor(Color(rGradient.GetColorStops().front().getStopColor()));
        OString sEndColor = msfilter::util::ConvertColor(Color(rGradient.GetColorStops().back().getStopColor()));

        // Calculate the angle that was originally in the imported DOCX file
        // (reverse calculate the angle that was converted in the file
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx
index 67eb0f9..d4f417b 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -3595,13 +3595,13 @@ void RtfAttributeOutput::FormatFillGradient(const XFillGradientItem& rFillGradie
        "fillType", OString::number(7))); // Shade using the fillAngle

    const XGradient& rGradient = rFillGradient.GetGradientValue();
    const Color& rStartColor = rGradient.GetStartColor();
    const Color aStartColor(rGradient.GetColorStops().front().getStopColor());
    m_aFlyProperties.push_back(std::make_pair<OString, OString>(
        "fillBackColor", OString::number(wwUtility::RGBToBGR(rStartColor))));
        "fillBackColor", OString::number(wwUtility::RGBToBGR(aStartColor))));

    const Color& rEndColor = rGradient.GetEndColor();
    const Color aEndColor(rGradient.GetColorStops().back().getStopColor());
    m_aFlyProperties.push_back(std::make_pair<OString, OString>(
        "fillColor", OString::number(wwUtility::RGBToBGR(rEndColor))));
        "fillColor", OString::number(wwUtility::RGBToBGR(aEndColor))));

    switch (rGradient.GetGradientStyle())
    {
diff --git a/sw/source/uibase/docvw/HeaderFooterWin.cxx b/sw/source/uibase/docvw/HeaderFooterWin.cxx
index 654e6be..b4fe2f5 100644
--- a/sw/source/uibase/docvw/HeaderFooterWin.cxx
+++ b/sw/source/uibase/docvw/HeaderFooterWin.cxx
@@ -152,10 +152,8 @@ void SwFrameButtonPainter::PaintButton(drawinglayer::primitive2d::Primitive2DCon
        if (bOnTop)
            nAngle = 0;

        const basegfx::ColorSteps aColorSteps {
            basegfx::ColorStep(0.0, aLighterColor),
            basegfx::ColorStep(1.0, aFillColor) };
        FillGradientAttribute aFillAttrs(drawinglayer::attribute::GradientStyle::Linear, 0.0, 0.0, 0.0, nAngle, aColorSteps );
        FillGradientAttribute aFillAttrs(drawinglayer::attribute::GradientStyle::Linear, 0.0, 0.0, 0.0, nAngle,
            basegfx::utils::createColorStopsFromStartEndColor(aLighterColor, aFillColor));
        rSeq.push_back(drawinglayer::primitive2d::Primitive2DReference(
                            new drawinglayer::primitive2d::FillGradientPrimitive2D(aGradientRect, std::move(aFillAttrs))));
    }
diff --git a/sw/source/uibase/docvw/ShadowOverlayObject.cxx b/sw/source/uibase/docvw/ShadowOverlayObject.cxx
index 002a40d..418c915 100644
--- a/sw/source/uibase/docvw/ShadowOverlayObject.cxx
+++ b/sw/source/uibase/docvw/ShadowOverlayObject.cxx
@@ -84,16 +84,15 @@ void ShadowPrimitive::create2DDecomposition(
        {
            aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (2.0 * getDiscreteUnit())));

            const basegfx::ColorSteps aColorSteps {
                basegfx::ColorStep(0.0, basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0)),
                basegfx::ColorStep(1.0, basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0)) };
            ::drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute(
                drawinglayer::attribute::GradientStyle::Linear,
                0.0,
                0.5,
                0.5,
                M_PI,
                aColorSteps);
                basegfx::utils::createColorStopsFromStartEndColor(
                    basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0),
                    basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0)));

            rContainer.push_back(
                new drawinglayer::primitive2d::FillGradientPrimitive2D(
@@ -104,16 +103,15 @@ void ShadowPrimitive::create2DDecomposition(
        case SS_VIEW:
        {
            aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (4.0 * getDiscreteUnit())));
            const basegfx::ColorSteps aColorSteps {
                basegfx::ColorStep(0.0, basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0)),
                basegfx::ColorStep(1.0, basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0)) };
            drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute(
                drawinglayer::attribute::GradientStyle::Linear,
                0.0,
                0.5,
                0.5,
                M_PI,
                aColorSteps);
                basegfx::utils::createColorStopsFromStartEndColor(
                    basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0),
                    basegfx::BColor(180.0/255.0,180.0/255.0,180.0/255.0)));

            rContainer.push_back(
                new drawinglayer::primitive2d::FillGradientPrimitive2D(
@@ -124,16 +122,15 @@ void ShadowPrimitive::create2DDecomposition(
        case SS_EDIT:
        {
            aRange.expand(basegfx::B2DTuple(getSecondPosition().getX(), getSecondPosition().getY() + (4.0 * getDiscreteUnit())));
            const basegfx::ColorSteps aColorSteps {
                basegfx::ColorStep(0.0, basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0)),
                basegfx::ColorStep(1.0, basegfx::BColor(83.0/255.0,83.0/255.0,83.0/255.0)) };
            drawinglayer::attribute::FillGradientAttribute aFillGradientAttribute(
                drawinglayer::attribute::GradientStyle::Linear,
                0.0,
                0.5,
                0.5,
                M_PI,
                aColorSteps);
                basegfx::utils::createColorStopsFromStartEndColor(
                    basegfx::BColor(230.0/255.0,230.0/255.0,230.0/255.0),
                    basegfx::BColor(83.0/255.0,83.0/255.0,83.0/255.0)));

            rContainer.push_back(
                new drawinglayer::primitive2d::FillGradientPrimitive2D(
diff --git a/sw/source/uibase/sidebar/PageStylesPanel.cxx b/sw/source/uibase/sidebar/PageStylesPanel.cxx
index 1956b41..0577473 100644
--- a/sw/source/uibase/sidebar/PageStylesPanel.cxx
+++ b/sw/source/uibase/sidebar/PageStylesPanel.cxx
@@ -193,9 +193,9 @@ void PageStylesPanel::Update()
            mxBgGradientLB->show();

            const XGradient xGradient = GetGradientSetOrDefault();
            const Color aStartColor = xGradient.GetStartColor();
            const Color aStartColor(xGradient.GetColorStops().front().getStopColor());
            mxBgColorLB->SelectEntry(aStartColor);
            const Color aEndColor = xGradient.GetEndColor();
            const Color aEndColor(xGradient.GetColorStops().back().getStopColor());
            mxBgGradientLB->SelectEntry(aEndColor);
        }
        break;
@@ -550,9 +550,10 @@ void PageStylesPanel::ModifyFillColor()
        break;
        case GRADIENT:
        {
            XGradient aGradient;
            aGradient.SetStartColor(mxBgColorLB->GetSelectEntryColor());
            aGradient.SetEndColor(mxBgGradientLB->GetSelectEntryColor());
            XGradient aGradient(
                basegfx::utils::createColorStopsFromStartEndColor(
                    mxBgColorLB->GetSelectEntryColor().getBColor(),
                    mxBgGradientLB->GetSelectEntryColor().getBColor()));

            XFillGradientItem aItem(aGradient);
            GetBindings()->GetDispatcher()->ExecuteList(SID_ATTR_PAGE_GRADIENT, SfxCallMode::RECORD, { &aItem });