12#include <com/sun/star/awt/Gradient2.hpp>
13#include <boost/property_tree/json_parser.hpp>
20css::awt::GradientStyle lcl_getStyleFromString(std::u16string_view rStyle)
22 if (rStyle ==
u"LINEAR")
23 return css::awt::GradientStyle_LINEAR;
24 else if (rStyle ==
u"AXIAL")
25 return css::awt::GradientStyle_AXIAL;
26 else if (rStyle ==
u"RADIAL")
27 return css::awt::GradientStyle_RADIAL;
28 else if (rStyle ==
u"ELLIPTICAL")
29 return css::awt::GradientStyle_ELLIPTICAL;
30 else if (rStyle ==
u"SQUARE")
31 return css::awt::GradientStyle_SQUARE;
32 else if (rStyle ==
u"RECT")
33 return css::awt::GradientStyle_RECT;
35 return css::awt::GradientStyle_LINEAR;
38StringMap lcl_jsonToStringMap(std::u16string_view rJSON)
41 if (rJSON.size() && rJSON[0] !=
'\0')
43 std::stringstream aStream(std::string(
OUStringToOString(rJSON, RTL_TEXTENCODING_ASCII_US)));
44 boost::property_tree::ptree aTree;
45 boost::property_tree::read_json(aStream, aTree);
47 for (
const auto& rPair : aTree)
49 aArgs[OUString::fromUtf8(rPair.first)]
50 = OUString::fromUtf8(rPair.second.get_value<std::string>(
"."));
60 ColorToBColorConverter(rMap[
"endcolor"].
toInt32(16)).getBColor()));
73 const sal_Int32 nLen(rColorStops.getLength());
79 const css::awt::ColorStop* pSourceColorStop(rColorStops.getConstArray());
81 for (sal_Int32
a(0);
a < nLen;
a++, pSourceColorStop++)
83 emplace_back(pSourceColorStop->StopOffset,
84 BColor(pSourceColorStop->StopColor.Red, pSourceColorStop->StopColor.Green,
85 pSourceColorStop->StopColor.Blue));
97 if (rVal.has<css::awt::ColorStopSequence>())
100 css::awt::ColorStopSequence aColorStopSequence;
101 rVal >>= aColorStopSequence;
110 emplace_back(0.0, rStart);
111 emplace_back(1.0, rEnd);
127 const double fMin(front().getStopOffset());
128 if (fPosition < fMin)
129 return front().getStopColor();
132 const double fMax(back().getStopOffset());
133 if (fPosition > fMax)
134 return back().getStopColor();
143 return front().getStopColor();
149 if (aCStart == aCEnd)
153 const sal_uInt32 nSteps(
160 fPosition = (fPosition - fMin) / (fMax - fMin);
162 nSteps > 1 ? floor(fPosition * nSteps) /
double(nSteps - 1)
185 return x.getStopOffset() <
y.getStopOffset();
189 if (
end() == upperBound)
190 return back().getStopColor();
193 const auto lowerBound(upperBound - 1);
196 if (
end() == lowerBound)
197 return back().getStopColor();
200 rLastColorStopRange.
maColorStart = lowerBound->getStopColor();
201 rLastColorStopRange.
maColorEnd = upperBound->getStopColor();
202 rLastColorStopRange.
mfOffsetStart = lowerBound->getStopOffset();
203 rLastColorStopRange.
mfOffsetEnd = upperBound->getStopOffset();
214 const double fAdaptedScaler(
222 nSteps > 1 ? floor(fAdaptedScaler * nSteps) /
double(nSteps - 1)
234 BColorStops::iterator a1stNonStartColor(
begin());
238 while (a1stNonStartColor !=
end()
246 aNewColorStops.reserve(
size() + 1);
247 aNewColorStops.emplace_back(0.0, rStart);
248 aNewColorStops.insert(aNewColorStops.end(), a1stNonStartColor,
end());
251 *
this = aNewColorStops;
267 emplace_back(1.0, rEnd);
284 const BColor& rBlendColor)
291 fStartIntensity = std::max(std::min(1.0, fStartIntensity), 0.0);
292 fEndIntensity = std::max(std::min(1.0, fEndIntensity), 0.0);
299 for (
auto& candidate : *
this)
301 const double fOffset(candidate.getStopOffset());
302 const double fIntensity((fStartIntensity * (1.0 - fOffset)) + (fEndIntensity * fOffset));
366 for (
size_t read(0); read <
size(); read++)
369 double fOff((*
this)[read].getStopOffset());
375 const double fOff2((*
this)[read + 1].getStopOffset());
383 (*
this)[read + 1].getStopColor(),
384 (0.0 - fOff) / (fOff2 - fOff)));
401 const double fOff2((*
this)[read + 1].getStopOffset());
409 (*
this)[read + 1].getStopColor(),
410 (1.0 - fOff) / (fOff2 - fOff)));
427 if (0 == write || !((*
this)[read] == (*
this)[write - 1]))
432 (*this)[write] = (*this)[read];
452 const BColor aBackColor(back().getStopColor());
454 emplace_back(0.0, aBackColor);
459 const BColor aFrontColor(front().getStopColor());
461 emplace_back(1.0, aFrontColor);
482 const auto penultimate(rbegin() + 1);
485 if (penultimate == rend())
495 if (back().getStopColor() == penultimate->getStopColor())
507 css::awt::ColorStopSequence aRetval(
size());
509 css::awt::ColorStop* pTargetColorStop(aRetval.getArray());
511 for (
const auto& candidate : *
this)
513 pTargetColorStop->StopOffset = candidate.getStopOffset();
514 pTargetColorStop->StopColor = css::rendering::RGBColor(candidate.getStopColor().getRed(),
515 candidate.getStopColor().getGreen(),
516 candidate.getStopColor().getBlue());
540 rSingleColor = front().getStopColor();
544 rSingleColor = front().getStopColor();
546 for (
auto const& rCandidate : *
this)
548 if (rCandidate.getStopColor() != rSingleColor)
562 for (
auto& candidate : *
this)
563 candidate =
BColorStop(1.0 - candidate.getStopOffset(), candidate.getStopColor());
575 fOffset = std::max(std::min(1.0, fOffset), 0.0);
583 for (
const auto& candidate : *
this)
585 aNewStops.emplace_back(fOffset + (candidate.getStopOffset() * (1.0 - fOffset)),
586 candidate.getStopColor());
602 fOffset = std::max(std::min(1.0, fOffset), 0.0);
611 for (
const auto& candidate : *
this)
615 aNewStops.emplace_back((candidate.getStopOffset() - fOffset) * fMul,
616 candidate.getStopColor());
636 BColorStops::const_iterator aColorR(
begin());
637 BColorStops::const_iterator aColorL(aColorR++);
643 while (aColorR !=
end() && aColorL->getStopColor() == aColorR->getStopColor())
651 if (aColorL ==
end())
657 return aColorL->getStopOffset();
668 BColorStops::const_iterator aIter(
begin());
669 BColorStops::const_iterator aRIter(
end());
673 while (aIter <= aRIter && aIter->getStopColor().
equal(aRIter->getStopColor())
679 return aIter > aRIter;
688 basegfx::BColorStops::const_reverse_iterator aRevCurrColor(rbegin());
690 while (aRevCurrColor != rend())
692 aNewColorStops.emplace_back((1.0 - aRevCurrColor->getStopOffset()) * 0.5,
693 aRevCurrColor->getStopColor());
698 basegfx::BColorStops::const_iterator aCurrColor(
begin());
709 while (aCurrColor !=
end())
711 aNewColorStops.emplace_back((aCurrColor->getStopOffset() * 0.5) + 0.5,
712 aCurrColor->getStopColor());
717 *
this = aNewColorStops;
723 if (0 == nStepCount || nStepCount > 100)
733 basegfx::BColorStops::const_iterator aColorR(
begin());
734 basegfx::BColorStops::const_iterator aColorL(aColorR++);
736 while (aColorR !=
end())
739 const double fStart(aColorL->getStopOffset());
740 const double fDelta(aColorR->getStopOffset() - fStart);
742 if (aNewColorStops.empty() || aNewColorStops.back() != *aColorL)
747 aNewColorStops.push_back(*aColorL);
756 if (rStartColor != rEndColor)
760 const double fSingleStep(1.0 /
static_cast<double>(nStepCount - 1));
761 const double fOffsetStep(fDelta /
static_cast<double>(nStepCount));
763 for (sal_uInt16
a(1);
a < nStepCount;
a++)
766 const double fPosition(fStart + fOffsetStep *
static_cast<double>(
a));
769 aNewColorStops.emplace_back(
771 static_cast<double>(
a - 1) * fSingleStep));
774 aNewColorStops.emplace_back(
776 static_cast<double>(
a) * fSingleStep));
782 aNewColorStops.push_back(*aColorR);
790 *
this = aNewColorStops;
797 case css::awt::GradientStyle::GradientStyle_LINEAR:
800 case css::awt::GradientStyle::GradientStyle_AXIAL:
803 case css::awt::GradientStyle::GradientStyle_RADIAL:
806 case css::awt::GradientStyle::GradientStyle_ELLIPTICAL:
809 case css::awt::GradientStyle::GradientStyle_SQUARE:
812 case css::awt::GradientStyle::GradientStyle_RECT:
815 case css::awt::GradientStyle::GradientStyle_MAKE_FIXED_SIZE:
816 return "MAKE_FIXED_SIZE";
825 return lcl_buildGradientFromStringMap(
aMap);
829 : eStyle(css::awt::GradientStyle_LINEAR)
844 Degree10 nTheAngle, sal_uInt16 nXOfs, sal_uInt16 nYOfs, sal_uInt16 nTheBorder,
845 sal_uInt16 nStartIntens, sal_uInt16 nEndIntens, sal_uInt16 nSteps)
847 , aColorStops(rColorStops)
852 , nIntensStart(nStartIntens)
853 , nIntensEnd(nEndIntens)
872 if (rGradient2.ColorStops.hasElements())
882 BColorStop(0.0, ColorToBColorConverter(rGradient2.StartColor).getBColor()),
883 BColorStop(1.0, ColorToBColorConverter(rGradient2.EndColor).getBColor())
893 if (rVal.has<css::awt::Gradient2>())
896 css::awt::Gradient2 aGradient2;
901 else if (rVal.has<css::awt::Gradient>())
904 css::awt::Gradient aGradient;
919 BColorStop(0.0, ColorToBColorConverter(aGradient.StartColor).getBColor()),
920 BColorStop(1.0, ColorToBColorConverter(aGradient.EndColor).getBColor())
944OUString AsRGBHexString(
const ColorToBColorConverter& rVal)
946 std::stringstream ss;
947 ss << std::hex << std::setfill(
'0') << std::setw(6) << sal_uInt32(rVal);
948 return OUString::createFromAscii(ss.str());
954 boost::property_tree::ptree aTree;
957 const ColorToBColorConverter aStart(
GetColorStops().front().getStopColor());
958 aTree.put(
"startcolor", AsRGBHexString(aStart.GetRGBColor()));
959 const ColorToBColorConverter aEnd(
GetColorStops().back().getStopColor());
960 aTree.put(
"endcolor", AsRGBHexString(aEnd.GetRGBColor()));
961 aTree.put(
"angle", std::to_string(
nAngle.
get()));
962 aTree.put(
"border", std::to_string(
nBorder));
963 aTree.put(
"x", std::to_string(
nOfsX));
964 aTree.put(
"y", std::to_string(
nOfsY));
966 aTree.put(
"intensend", std::to_string(
nIntensEnd));
967 aTree.put(
"stepcount", std::to_string(
nStepCount));
974 css::awt::Gradient2 aRetval;
978 aRetval.Angle =
static_cast<short>(
GetAngle());
1006 =
static_cast<sal_Int32
>(ColorToBColorConverter(
aColorStops.front().getStopColor()));
1008 =
static_cast<sal_Int32
>(ColorToBColorConverter(
aColorStops.back().getStopColor()));
1023 const bool bSingleColor(
GetColorStops().isSingleColor(aSingleColor));
1035 if (
nullptr != pAssociatedTransparencyStops)
1049 if (
nullptr != pAssociatedTransparencyStops)
1053 SetBorder(
static_cast<sal_uInt16
>(std::lround(fOffset * 100.0)));
1060 if (
nullptr != pAssociatedTransparencyStops)
1074 const double fOffset(
GetBorder() * 0.01);
1126 BColorStop aNextStop(std::clamp((*aIter).getStopOffset() * 2.0, 0.0, 1.0),
1127 (*aIter).getStopColor());
1128 aAxialColorStops.push_back(aNextStop);
std::map< OUString, OUString > StringMap
const BColor & getStopColor() const
double getStopOffset() const
void setColorStopSequence(const css::awt::ColorStopSequence &rColorStops)
void blendToIntensity(double fStartIntensity, double fEndIntensity, const BColor &rBlendColor)
bool isSingleColor(BColor &rSingleColor) const
void replaceEndColor(const BColor &rEnd)
void removeSpaceAtStart(double fOffset)
bool checkPenultimate() const
BColor getInterpolatedBColor(double fPosition, sal_uInt32 nRequestedSteps, BColorStopRange &rLastColorStopRange) const
css::awt::ColorStopSequence getAsColorStopSequence() const
void createSpaceAtStart(double fOffset)
bool isSymmetrical() const
double detectPossibleOffsetAtStart() const
void replaceStartColor(const BColor &rStart)
void doApplySteps(sal_uInt16 nStepCount)
Base Color class with three double values.
bool operator==(const BGradient &rGradient) const
void tryToRecreateBorder(basegfx::BColorStops *pAssociatedTransparencyStops=nullptr)
sal_uInt16 GetBorder() const
void SetGradientStyle(css::awt::GradientStyle eNewStyle)
sal_uInt16 GetStartIntens() const
void SetColorStops(const basegfx::BColorStops &rSteps)
sal_uInt16 GetSteps() const
void SetEndIntens(sal_uInt16 nNewIntens)
void SetYOffset(sal_uInt16 nNewOffset)
void SetXOffset(sal_uInt16 nNewOffset)
basegfx::BColorStops aColorStops
sal_uInt16 GetXOffset() const
void tryToApplyStartEndIntensity()
void SetSteps(sal_uInt16 nSteps)
void SetBorder(sal_uInt16 nNewBorder)
const basegfx::BColorStops & GetColorStops() const
static std::string GradientStyleToString(css::awt::GradientStyle eStyle)
css::awt::Gradient2 getAsGradient2() const
Tooling method to fill awt::Gradient2 from data contained in the given basegfx::BGradient.
sal_uInt16 GetEndIntens() const
void setGradient2(const css::awt::Gradient2 &rGradient2)
void tryToConvertToAxial()
Degree10 GetAngle() const
static BGradient fromJSON(std::u16string_view rJSON)
css::awt::GradientStyle eStyle
css::awt::GradientStyle GetGradientStyle() const
void SetStartIntens(sal_uInt16 nNewIntens)
boost::property_tree::ptree dumpAsJSON() const
void SetAngle(Degree10 nNewAngle)
sal_uInt16 GetYOffset() const
tools::Long const nBorder
sal_uInt32 calculateNumberOfSteps(sal_uInt32 nRequestedSteps, const BColor &rStart, const BColor &rEnd)
B2DTuple interpolate(const B2DTuple &rOld1, const B2DTuple &rOld2, double t)
enumrange< T >::Iterator begin(enumrange< T >)
OString OUStringToOString(std::u16string_view str, ConnectionSettings const *settings)
sal_Int32 toInt32(std::u16string_view rStr)
HashMap_OWString_Interface aMap
basegfx::BColor maColorStart
basegfx::BColor maColorEnd
UNDERLYING_TYPE get() const
std::map< OUString, OUString > StringMap