1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
11 #include <docmodel/uno/UnoGradientTools.hxx>
12 #include <com/sun/star/awt/Gradient.hpp>
13 #include <com/sun/star/awt/Gradient2.hpp>
14 #include <com/sun/star/rendering/RGBColor.hpp>
15 #include <basegfx/utils/bgradient.hxx>
16 #include <tools/color.hxx>
20 namespace model::gradient
22 css::awt::ColorStopSequence
createColorStopSequence(basegfx::BColorStops
const& rColorStops
)
25 css::awt::ColorStopSequence
aSequence(rColorStops
.size());
26 css::awt::ColorStop
* pSequence(aSequence
.getArray());
28 for (const auto& rStop
: rColorStops
)
30 auto rBColor
= rStop
.getStopColor();
31 pSequence
->StopOffset
= rStop
.getStopOffset();
33 = css::rendering::RGBColor(rBColor
.getRed(), rBColor
.getGreen(), rBColor
.getBlue());
40 css::awt::Gradient2
createUnoGradient2(basegfx::BGradient
const& rGradient
)
42 css::awt::Gradient2 aGradient2
;
45 aGradient2
.Style
= rGradient
.GetGradientStyle();
46 aGradient2
.Angle
= static_cast<short>(rGradient
.GetAngle());
47 aGradient2
.Border
= rGradient
.GetBorder();
48 aGradient2
.XOffset
= rGradient
.GetXOffset();
49 aGradient2
.YOffset
= rGradient
.GetYOffset();
50 aGradient2
.StartIntensity
= rGradient
.GetStartIntens();
51 aGradient2
.EndIntensity
= rGradient
.GetEndIntens();
52 aGradient2
.StepCount
= rGradient
.GetSteps();
54 // for compatibility, still set StartColor/EndColor
55 // NOTE: All code after adapting to multi color gradients works
56 // using the ColorSteps, so in principle Start/EndColor might
58 // (a) ignored consequently everywhere or
59 // (b) be set/added consequently everywhere
60 // since this is - in principle - redundant data.
61 // Be aware that e.g. cases like DrawingML::EqualGradients
62 // and others would have to be identified and adapted (!)
63 // Since awt::Gradient2 is UNO API data there might
64 // be cases where just awt::Gradient is transferred, so (b)
65 // is far better backwards compatible and thus more safe, so
66 // all changes will make use of additionally using/setting
67 // these additionally, but will only make use of the given
68 // ColorSteps if these are not empty, assuming that these
69 // already contain Start/EndColor.
70 // In principle that redundancy and that it is conflict-free
71 // could even be checked and asserted, but consequently using
72 // (b) methodically should be safe.
73 const basegfx::BColorStops
& rColorStops
= rGradient
.GetColorStops();
74 aGradient2
.StartColor
= static_cast<sal_Int32
>(::Color(rColorStops
.front().getStopColor()));
75 aGradient2
.EndColor
= static_cast<sal_Int32
>(::Color(rColorStops
.back().getStopColor()));
77 aGradient2
.ColorStops
= createColorStopSequence(rColorStops
);
84 void fillFromColorStopSequence(basegfx::BColorStops
& rColorStops
,
85 css::awt::ColorStopSequence
const& rUnoColorStopSequence
)
87 const auto nLength
= rUnoColorStopSequence
.getLength();
91 rColorStops
.reserve(nLength
);
93 for (css::awt::ColorStop
const& rSourceStop
: rUnoColorStopSequence
)
95 rColorStops
.emplace_back(rSourceStop
.StopOffset
,
96 basegfx::BColor(rSourceStop
.StopColor
.Red
,
97 rSourceStop
.StopColor
.Green
,
98 rSourceStop
.StopColor
.Blue
));
103 void fillFromGradient2(basegfx::BGradient
& rBGradient
, css::awt::Gradient2
const& rGradient2
)
105 rBGradient
.SetGradientStyle(rGradient2
.Style
);
106 rBGradient
.SetAngle(Degree10(rGradient2
.Angle
));
107 rBGradient
.SetBorder(rGradient2
.Border
);
108 rBGradient
.SetXOffset(rGradient2
.XOffset
);
109 rBGradient
.SetYOffset(rGradient2
.YOffset
);
110 rBGradient
.SetStartIntens(rGradient2
.StartIntensity
);
111 rBGradient
.SetEndIntens(rGradient2
.EndIntensity
);
112 rBGradient
.SetSteps(rGradient2
.StepCount
);
115 if (rGradient2
.ColorStops
.hasElements())
117 basegfx::BColorStops aColorStops
;
118 fillFromColorStopSequence(aColorStops
, rGradient2
.ColorStops
);
119 rBGradient
.SetColorStops(aColorStops
);
123 // if not, for compatibility, use StartColor/EndColor
124 basegfx::BColorStops aColorStops
{
125 basegfx::BColorStop(0.0, ::Color(ColorTransparency
, rGradient2
.StartColor
).getBColor()),
126 basegfx::BColorStop(1.0, ::Color(ColorTransparency
, rGradient2
.EndColor
).getBColor())
128 rBGradient
.SetColorStops(aColorStops
);
134 basegfx::BColorStops
getColorStopsFromUno(css::awt::ColorStopSequence
const& rColorStopSequence
)
136 basegfx::BColorStops aColorStops
;
137 fillFromColorStopSequence(aColorStops
, rColorStopSequence
);
141 basegfx::BColorStops
getColorStopsFromAny(css::uno::Any
const& rAny
)
143 basegfx::BColorStops aColorStops
;
144 if (!rAny
.has
<css::awt::ColorStopSequence
>())
147 auto aSequence
= rAny
.get
<css::awt::ColorStopSequence
>();
148 fillFromColorStopSequence(aColorStops
, aSequence
);
152 basegfx::BGradient
getFromUnoGradient2(css::awt::Gradient2
const& rGradient2
)
154 basegfx::BGradient aBGradient
;
155 fillFromGradient2(aBGradient
, rGradient2
);
159 basegfx::BGradient
getFromAny(css::uno::Any
const& rAny
)
161 basegfx::BGradient aBGradient
;
163 if (rAny
.has
<css::awt::Gradient2
>())
165 // we can use awt::Gradient2 directly
166 css::awt::Gradient2 aGradient2
;
169 fillFromGradient2(aBGradient
, aGradient2
);
171 else if (rAny
.has
<css::awt::Gradient
>())
174 css::awt::Gradient aGradient
;
178 aBGradient
.SetGradientStyle(aGradient
.Style
);
179 aBGradient
.SetAngle(Degree10(aGradient
.Angle
));
180 aBGradient
.SetBorder(aGradient
.Border
);
181 aBGradient
.SetXOffset(aGradient
.XOffset
);
182 aBGradient
.SetYOffset(aGradient
.YOffset
);
183 aBGradient
.SetStartIntens(aGradient
.StartIntensity
);
184 aBGradient
.SetEndIntens(aGradient
.EndIntensity
);
185 aBGradient
.SetSteps(aGradient
.StepCount
);
187 basegfx::BColorStops aColorStops
{
188 basegfx::BColorStop(0.0, ::Color(ColorTransparency
, aGradient
.StartColor
).getBColor()),
189 basegfx::BColorStop(1.0, ::Color(ColorTransparency
, aGradient
.EndColor
).getBColor())
192 aBGradient
.SetColorStops(aColorStops
);
198 } // end model::gradient
200 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */