diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-15 05:54:39 +0000 |
commit | 267c6f2ac71f92999e969232431ba04678e7437e (patch) | |
tree | 358c9467650e1d0a1d7227a21dac2e3d08b622b2 /docmodel/source/uno/UnoGradientTools.cxx | |
parent | Initial commit. (diff) | |
download | libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.tar.xz libreoffice-267c6f2ac71f92999e969232431ba04678e7437e.zip |
Adding upstream version 4:24.2.0.upstream/4%24.2.0
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'docmodel/source/uno/UnoGradientTools.cxx')
-rw-r--r-- | docmodel/source/uno/UnoGradientTools.cxx | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/docmodel/source/uno/UnoGradientTools.cxx b/docmodel/source/uno/UnoGradientTools.cxx new file mode 100644 index 0000000000..0f05e398de --- /dev/null +++ b/docmodel/source/uno/UnoGradientTools.cxx @@ -0,0 +1,200 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + */ + +#include <docmodel/uno/UnoGradientTools.hxx> +#include <com/sun/star/awt/Gradient.hpp> +#include <com/sun/star/awt/Gradient2.hpp> +#include <com/sun/star/rendering/RGBColor.hpp> +#include <basegfx/utils/bgradient.hxx> +#include <tools/color.hxx> + +using namespace css; + +namespace model::gradient +{ +css::awt::ColorStopSequence createColorStopSequence(basegfx::BColorStops const& rColorStops) +{ + // Fill color stops + css::awt::ColorStopSequence aSequence(rColorStops.size()); + css::awt::ColorStop* pSequence(aSequence.getArray()); + + for (const auto& rStop : rColorStops) + { + auto rBColor = rStop.getStopColor(); + pSequence->StopOffset = rStop.getStopOffset(); + pSequence->StopColor + = css::rendering::RGBColor(rBColor.getRed(), rBColor.getGreen(), rBColor.getBlue()); + pSequence++; + } + + return aSequence; +} + +css::awt::Gradient2 createUnoGradient2(basegfx::BGradient const& rGradient) +{ + css::awt::Gradient2 aGradient2; + + // standard values + aGradient2.Style = rGradient.GetGradientStyle(); + aGradient2.Angle = static_cast<short>(rGradient.GetAngle()); + aGradient2.Border = rGradient.GetBorder(); + aGradient2.XOffset = rGradient.GetXOffset(); + aGradient2.YOffset = rGradient.GetYOffset(); + aGradient2.StartIntensity = rGradient.GetStartIntens(); + aGradient2.EndIntensity = rGradient.GetEndIntens(); + aGradient2.StepCount = rGradient.GetSteps(); + + // for compatibility, still set StartColor/EndColor + // NOTE: All code after adapting to multi color gradients works + // using the ColorSteps, so in principle Start/EndColor might + // be either + // (a) ignored consequently everywhere or + // (b) be set/added consequently everywhere + // since this is - in principle - redundant data. + // Be aware that e.g. cases like DrawingML::EqualGradients + // and others would have to be identified and adapted (!) + // Since awt::Gradient2 is UNO API data there might + // be cases where just awt::Gradient is transferred, so (b) + // is far better backwards compatible and thus more safe, so + // all changes will make use of additionally using/setting + // these additionally, but will only make use of the given + // ColorSteps if these are not empty, assuming that these + // already contain Start/EndColor. + // In principle that redundancy and that it is conflict-free + // could even be checked and asserted, but consequently using + // (b) methodically should be safe. + const basegfx::BColorStops& rColorStops = rGradient.GetColorStops(); + aGradient2.StartColor = static_cast<sal_Int32>(::Color(rColorStops.front().getStopColor())); + aGradient2.EndColor = static_cast<sal_Int32>(::Color(rColorStops.back().getStopColor())); + + aGradient2.ColorStops = createColorStopSequence(rColorStops); + + return aGradient2; +} + +namespace +{ +void fillFromColorStopSequence(basegfx::BColorStops& rColorStops, + css::awt::ColorStopSequence const& rUnoColorStopSequence) +{ + const auto nLength = rUnoColorStopSequence.getLength(); + if (0 != nLength) + { + rColorStops.clear(); + rColorStops.reserve(nLength); + + for (css::awt::ColorStop const& rSourceStop : rUnoColorStopSequence) + { + rColorStops.emplace_back(rSourceStop.StopOffset, + basegfx::BColor(rSourceStop.StopColor.Red, + rSourceStop.StopColor.Green, + rSourceStop.StopColor.Blue)); + } + } +} + +void fillFromGradient2(basegfx::BGradient& rBGradient, css::awt::Gradient2 const& rGradient2) +{ + rBGradient.SetGradientStyle(rGradient2.Style); + rBGradient.SetAngle(Degree10(rGradient2.Angle)); + rBGradient.SetBorder(rGradient2.Border); + rBGradient.SetXOffset(rGradient2.XOffset); + rBGradient.SetYOffset(rGradient2.YOffset); + rBGradient.SetStartIntens(rGradient2.StartIntensity); + rBGradient.SetEndIntens(rGradient2.EndIntensity); + rBGradient.SetSteps(rGradient2.StepCount); + + // set ColorStops + if (rGradient2.ColorStops.hasElements()) + { + basegfx::BColorStops aColorStops; + fillFromColorStopSequence(aColorStops, rGradient2.ColorStops); + rBGradient.SetColorStops(aColorStops); + } + else + { + // if not, for compatibility, use StartColor/EndColor + basegfx::BColorStops aColorStops{ + basegfx::BColorStop(0.0, ::Color(ColorTransparency, rGradient2.StartColor).getBColor()), + basegfx::BColorStop(1.0, ::Color(ColorTransparency, rGradient2.EndColor).getBColor()) + }; + rBGradient.SetColorStops(aColorStops); + } +} + +} // end anonymous + +basegfx::BColorStops getColorStopsFromUno(css::awt::ColorStopSequence const& rColorStopSequence) +{ + basegfx::BColorStops aColorStops; + fillFromColorStopSequence(aColorStops, rColorStopSequence); + return aColorStops; +} + +basegfx::BColorStops getColorStopsFromAny(css::uno::Any const& rAny) +{ + basegfx::BColorStops aColorStops; + if (!rAny.has<css::awt::ColorStopSequence>()) + return aColorStops; + + auto aSequence = rAny.get<css::awt::ColorStopSequence>(); + fillFromColorStopSequence(aColorStops, aSequence); + return aColorStops; +} + +basegfx::BGradient getFromUnoGradient2(css::awt::Gradient2 const& rGradient2) +{ + basegfx::BGradient aBGradient; + fillFromGradient2(aBGradient, rGradient2); + return aBGradient; +} + +basegfx::BGradient getFromAny(css::uno::Any const& rAny) +{ + basegfx::BGradient aBGradient; + + if (rAny.has<css::awt::Gradient2>()) + { + // we can use awt::Gradient2 directly + css::awt::Gradient2 aGradient2; + rAny >>= aGradient2; + + fillFromGradient2(aBGradient, aGradient2); + } + else if (rAny.has<css::awt::Gradient>()) + { + // use awt::Gradient + css::awt::Gradient aGradient; + rAny >>= aGradient; + + // set values + aBGradient.SetGradientStyle(aGradient.Style); + aBGradient.SetAngle(Degree10(aGradient.Angle)); + aBGradient.SetBorder(aGradient.Border); + aBGradient.SetXOffset(aGradient.XOffset); + aBGradient.SetYOffset(aGradient.YOffset); + aBGradient.SetStartIntens(aGradient.StartIntensity); + aBGradient.SetEndIntens(aGradient.EndIntensity); + aBGradient.SetSteps(aGradient.StepCount); + + basegfx::BColorStops aColorStops{ + basegfx::BColorStop(0.0, ::Color(ColorTransparency, aGradient.StartColor).getBColor()), + basegfx::BColorStop(1.0, ::Color(ColorTransparency, aGradient.EndColor).getBColor()) + }; + + aBGradient.SetColorStops(aColorStops); + } + + return aBGradient; +} + +} // end model::gradient + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |