diff options
52 files changed, 966 insertions, 608 deletions
diff --git a/basegfx/source/tools/gradienttools.cxx b/basegfx/source/tools/gradienttools.cxx index 02ab81cf2581..adf24c689c4b 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 reducved to a single entry with offset 0.0 - (StartColor) + be reduced to a single entry with offset 0.0 + (force to StartColor) Some more notes: - It can happen that the result is empty @@ -283,32 +388,32 @@ 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()); - // preapare status values + // prepare status values bool bSameColorInit(false); bool bAllTheSameColor(true); basegfx::BColor aFirstColor; @@ -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/ressources low - // by avoiding some calculatins and an O(log(N)) array access - if (2 == rColorSteps.size()) + // we can optimize that and keep the speed/resources low + // by avoiding some calculations and an O(log(N)) array access + 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 e2f11c7eb655..8cd3fd99045c 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 31a846d9cb96..dfe59e878334 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 75180022f3a1..259446ef5f46 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 567a24417f51..8eff5bee261a 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 ff839319c732..b98c66b031a8 100644 --- a/drawinglayer/qa/unit/vclpixelprocessor2d.cxx +++ b/drawinglayer/qa/unit/vclpixelprocessor2d.cxx @@ -59,10 +59,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 3d78273a6428..62bde03a29f6 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 a92a5f9e0d8d..c1246f1cce36 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 549932e93049..977670446c8a 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 == EndCoOlor == 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 3136eab6cc31..49a270cedc11 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) { @@ -2049,9 +2049,9 @@ void VclMetafileProcessor2D::processPolyPolygonGradientPrimitive2D( return; } - if (!rGradientCandidate.getFillGradient().getColorSteps().empty()) + if (!rGradientCandidate.getFillGradient().getColorStops().empty()) { - // MCGR: if we have COlorSteps, do not try to fallbacl 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 7efb80db2dfb..1b85cf9d519f 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 caf31e9aa5dc..a2a5111bc49b 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 b377266107e2..5cd708243143 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 innner loop (see above) - const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0); + // get correct start for inner loop (see above) + 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 innner loop (see above) - const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0); + // get correct start for inner loop (see above) + 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 55d2c6a8e29a..31c88c6482ed 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 ce52fe558f61..6e1b0bb4faa7 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 cdcad2778f6f..44ff353b872d 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 cb6381fb6fd3..2e3a75cae40b 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 328a86b8335c..85802749478c 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 - // cortrect entry when corrections are applied to the - // vector of entries (see sortAndCorrectColorSteps) + // correct entry when corrections are applied to the + // 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 50d169cb5772..8a2df4d6baaf 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 existance + 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 fe07fee51054..766996a57ac0 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 553dfe23b93b..9dda79d06c7c 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 494256b29f78..7456d1c904c5 100644 --- a/offapi/UnoApi_offapi.mk +++ b/offapi/UnoApi_offapi.mk @@ -1718,6 +1718,8 @@ $(eval $(call gb_UnoApi_add_idlfiles,offapi,com/sun/star/awt,\ AdjustmentEvent \ AdjustmentType \ CharSet \ + ColorStop \ + ColorStopSequence \ Command \ DeviceCapability \ DeviceInfo \ @@ -1741,6 +1743,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 000000000000..7b67aa20547d --- /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 000000000000..05d3e6110156 --- /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 000000000000..c9d38657f47d --- /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 ae54ed3a6c56..e928bbd7cf2b 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 fb389172985e..b83cc4de160a 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/bugfix-test.cxx b/sc/qa/unit/bugfix-test.cxx index 10bfd7199a67..18720a41f4f5 100644 --- a/sc/qa/unit/bugfix-test.cxx +++ b/sc/qa/unit/bugfix-test.cxx @@ -584,8 +584,12 @@ void ScFiltersTest::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); @@ -593,8 +597,12 @@ void ScFiltersTest::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 8e65d630d2aa..931c8e4b10a3 100644 --- a/sd/qa/unit/uiimpress.cxx +++ b/sd/qa/unit/uiimpress.cxx @@ -803,8 +803,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 c487c041c75a..b697be203095 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 5f8bcff886b7..101b8c6133a3 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 274fdaf01789..f0a6cae461a5 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 d93dbee142a3..e6b0173c5bc2 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 720adcf26a78..6a96870a4b79 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 bebdaa79b12b..dc36502ea810 100644 --- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx +++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx @@ -447,8 +447,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) @@ -475,62 +475,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; } @@ -538,63 +512,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; } @@ -604,13 +578,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; @@ -750,8 +743,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); @@ -764,17 +757,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 220e3f04b829..9f585e55d935 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 2d92b6b4b3b8..4cbfa7b3581e 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 d665cd48ce16..c559e580cf67 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 b642f8e69117..5c28ebaf92f9 100644 --- a/svx/source/svdraw/svdetc.cxx +++ b/svx/source/svdraw/svdetc.cxx @@ -279,8 +279,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 eb1c9648b127..86cb829119ec 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 44ecb8fefded..4496465c949b 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 c1105335ae84..586bba387699 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 bc9d04747f9c..ba0924be803f 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 f0d17dbc0b14..64df04216530 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(); + + // 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())); + + // fill ColorStops to extended Gradient2 + basegfx::utils::fillColorStopSequenceFromColorStops(rGradient2.ColorStops, rColorStops); + } +} - 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(); +css::awt::Gradient2 XGradient::toGradientUNO() const +{ + css::awt::Gradient2 aGradient2; - return aGradient; + // 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 65a096de3910..5294092a3183 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 219ee2801d69..e44141d45428 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 0f26e0463cd3..687340e74c81 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 c090fca4240d..2a3d4b5095d3 100644 --- a/sw/source/filter/ww8/docxattributeoutput.cxx +++ b/sw/source/filter/ww8/docxattributeoutput.cxx @@ -9343,8 +9343,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 c0b5194a5083..d638bfcd5f1d 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -3691,13 +3691,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 71f4e6782791..4aac6013236a 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 002a40d5db91..418c9157a7c2 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 1956b414a951..05774730daea 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 }); |