summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2023-04-03 12:09:16 +0200
committerArmin Le Grand <Armin.Le.Grand@me.com>2023-04-03 17:16:48 +0200
commit64007cb308ead90ba6ffa2963c5de8ef89cec5ce (patch)
tree12f4c472541b21e1d77f6e95195d5994abd79965
parentaec0830f31c2fd258de711baaa7da24bd01488c9 (diff)
MCGR: Unify Gradient intensity handling in tooling
Moved the Gradient intensity handling to tooling since it is also needed for TransparencyGradients. Added missing use of GradientStepCount for transparency. Change-Id: I63ae6683fa0131be7faadc8572e19f5c43bf27e3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/149957 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
-rw-r--r--basegfx/source/tools/gradienttools.cxx38
-rw-r--r--include/basegfx/utils/gradienttools.hxx15
-rw-r--r--svx/source/sdr/primitive2d/sdrattributecreator.cxx45
3 files changed, 81 insertions, 17 deletions
diff --git a/basegfx/source/tools/gradienttools.cxx b/basegfx/source/tools/gradienttools.cxx
index 49cf831da262..d1b5874e5b77 100644
--- a/basegfx/source/tools/gradienttools.cxx
+++ b/basegfx/source/tools/gradienttools.cxx
@@ -264,6 +264,44 @@ namespace basegfx
namespace utils
{
+ /* Tooling method to linearly blend the Colors contained in
+ a given ColorStop vector against a given Color using the
+ given intensity values.
+ The intensity values fStartIntensity, fEndIntensity are
+ in the range of [0.0 .. 1.0] and describe how much the
+ blend is supposed to be done at the start color position
+ and the end color position resprectively, where 0.0 means
+ to fully use the given BlendColor, 1.0 means to not change
+ the existing color in the ColorStop.
+ Every color entry in the given ColorStop is blended
+ relative to it's StopPosition, interpolating the
+ given intensities with the range [0.0 .. 1.0] to do so.
+ */
+ void blendColorStopsToIntensity(ColorStops& rColorStops, double fStartIntensity, double fEndIntensity, const basegfx::BColor& rBlendColor)
+ {
+ // no entries, done
+ if (rColorStops.empty())
+ return;
+
+ // correct intensities (maybe assert when input was wrong)
+ fStartIntensity = std::max(std::min(1.0, fStartIntensity), 0.0);
+ fEndIntensity = std::max(std::min(1.0, fEndIntensity), 0.0);
+
+ // all 100%, no real blend, done
+ if (basegfx::fTools::equal(fStartIntensity, 1.0) && basegfx::fTools::equal(fEndIntensity, 1.0))
+ return;
+
+ // blend relative to StopOffset position
+ for (auto& candidate : rColorStops)
+ {
+ const double fOffset(candidate.getStopOffset());
+ const double fIntensity((fStartIntensity * (1.0 - fOffset)) + (fEndIntensity * fOffset));
+ candidate = basegfx::ColorStop(
+ fOffset,
+ basegfx::interpolate(rBlendColor, candidate.getStopColor(), fIntensity));
+ }
+ }
+
/* Tooling method to check if a ColorStop vector is defined
by a single color. It returns true if this is the case.
If true is returned, rSingleColor contains that single
diff --git a/include/basegfx/utils/gradienttools.hxx b/include/basegfx/utils/gradienttools.hxx
index c7123bc81db3..dfa1f35b38c4 100644
--- a/include/basegfx/utils/gradienttools.hxx
+++ b/include/basegfx/utils/gradienttools.hxx
@@ -196,6 +196,21 @@ namespace basegfx
namespace utils
{
+ /* Tooling method to linearly blend the Colors contained in
+ a given ColorStop vector against a given Color using the
+ given intensity values.
+ The intensity values fStartIntensity, fEndIntensity are
+ in the range of [0.0 .. 1.0] and describe how much the
+ blend is supposed to be done at the start color position
+ and the end color position resprectively, where 0.0 means
+ to fully use the given BlendColor, 1.0 means to not change
+ the existing color in the ColorStop.
+ Every color entry in the given ColorStop is blended
+ relative to it's StopPosition, interpolating the
+ given intensities with the range [0.0 .. 1.0] to do so.
+ */
+ BASEGFX_DLLPUBLIC void blendColorStopsToIntensity(ColorStops& rColorStops, double fStartIntensity, double fEndIntensity, const basegfx::BColor& rBlendColor);
+
/* Tooling method to check if a ColorStop vector is defined
by a single color. It returns true if this is the case.
If true is returned, rSingleColor contains that single
diff --git a/svx/source/sdr/primitive2d/sdrattributecreator.cxx b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
index 813c9884bc9b..89493e4d5a45 100644
--- a/svx/source/sdr/primitive2d/sdrattributecreator.cxx
+++ b/svx/source/sdr/primitive2d/sdrattributecreator.cxx
@@ -756,23 +756,16 @@ namespace drawinglayer::primitive2d
}
}
- if(aXGradient.GetStartIntens() != 100 || aXGradient.GetEndIntens() != 100)
+ 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));
- }
+ basegfx::utils::blendColorStopsToIntensity(
+ aColorStops,
+ aXGradient.GetStartIntens() * 0.01,
+ aXGradient.GetEndIntens() * 0.01,
+ basegfx::BColor()); // COL_BLACK
}
aGradient = attribute::FillGradientAttribute(
@@ -919,8 +912,8 @@ namespace drawinglayer::primitive2d
if((pGradientItem = rSet.GetItemIfSet(XATTR_FILLFLOATTRANSPARENCE))
&& pGradientItem->IsEnabled())
{
- // test if float transparence is completely transparent
- const XGradient& rGradient = pGradientItem->GetGradientValue();
+ // test if float transparency is completely transparent
+ const XGradient& rGradient(pGradientItem->GetGradientValue());
basegfx::BColor aSingleColor;
const bool bSingleColor(basegfx::utils::isSingleColor(rGradient.GetColorStops(), aSingleColor));
const bool bCompletelyTransparent(bSingleColor && basegfx::fTools::equal(aSingleColor.luminance(), 1.0));
@@ -930,15 +923,33 @@ namespace drawinglayer::primitive2d
// normal fill attributes, XFILL_NONE will be used.
// create nothing when not transparent: use normal fill, no need t create a FillGradientAttribute.
// Both cases are optimizations, always creating FillGradientAttribute will work, too
- if(!bNotTransparent && !bCompletelyTransparent)
+ if (!bNotTransparent && !bCompletelyTransparent)
{
+ basegfx::ColorStops aColorStops(rGradient.GetColorStops());
+
+ if (rGradient.GetStartIntens() != 100 || rGradient.GetEndIntens() != 100)
+ {
+ // this may also be set for transparence, so need to take care of it
+ basegfx::utils::blendColorStopsToIntensity(
+ aColorStops,
+ rGradient.GetStartIntens() * 0.01,
+ rGradient.GetEndIntens() * 0.01,
+ basegfx::BColor()); // COL_BLACK
+ }
+
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()),
- rGradient.GetColorStops());
+ aColorStops,
+ // oops - the gradientStepCount was missing here. If we want to use
+ // a combination of gradient & transparencyGradient to represent
+ // imported gradients of formats which do originally support transparency
+ // in gradients, then the gradient has to be exactly defined the same,
+ // including the (evtl. used) gradientStepCount
+ rSet.Get(XATTR_GRADIENTSTEPCOUNT).GetValue());
}
}