summaryrefslogtreecommitdiff
path: root/drawinglayer
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2023-02-24 17:34:53 +0100
committerArmin Le Grand <Armin.Le.Grand@me.com>2023-02-27 17:43:13 +0000
commit16e728a8a88a7a04acec069512a5268ae89cf420 (patch)
treee1fe9c3ffb38daca8ac025ffdc2a7fcd8f08420f /drawinglayer
parent9027920783dd04db925c41b559abe6442cedf39e (diff)
MCGR: Adapted other Gradient* to make use of MCGR
Added to make GeoTexSvxGradientElliptical GeoTexSvxGradientSquare GeoTexSvxGradientRect work using the MCGR. It is still 100% backward-compatible, so as long as there is no source using this it will stay invisible - by purpose. Tests look good with all three, see the static variable nUseGradientSteps. NOTE: GeoTexSvxGradientElliptical still looks not optimal due to texture back-mapping method getEllipticalGradientAlpha, see notes in commit "MCGR: Adapted GradientRadial to make use of MCGR" ac824594c577ab4880177b3411a25297b1d08074 Change-Id: I56b82b867af88fe532f840dde15e0f5c299ed6a3 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147662 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'drawinglayer')
-rw-r--r--drawinglayer/source/texture/texture.cxx253
1 files changed, 157 insertions, 96 deletions
diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx
index e3ed2780af4e..22f56f33b8bd 100644
--- a/drawinglayer/source/texture/texture.cxx
+++ b/drawinglayer/source/texture/texture.cxx
@@ -455,60 +455,79 @@ namespace drawinglayer::texture
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
- if(mnColorSteps.size() <= 1)
+ // no color at all, done
+ if (mnColorSteps.empty())
return;
- const basegfx::BColor maStart(mnColorSteps.front().getColor());
- const basegfx::BColor maEnd(mnColorSteps.back().getColor());
- const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
- maGradientInfo.getRequestedSteps(), maStart, maEnd));
+ // fill in return parameter rOuterColor before returning
+ rOuterColor = mnColorSteps.front().getColor();
- rOuterColor = maStart;
- double fWidth(1.0);
- double fHeight(1.0);
- double fIncrementX(0.0);
- double fIncrementY(0.0);
+ // only one color, done
+ if (mnColorSteps.size() < 2)
+ return;
- if(maGradientInfo.getAspectRatio() > 1.0)
- {
- fIncrementY = fHeight / nSteps;
- fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
- }
- else
+ // need to start with the offsets *outside* of all loops, these will
+ // get modified non-linear below, now in more than one gradient section,
+ // but *constantly* over the whole range
+ double fAllWidth(0.0);
+ double fAllHeight(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++)
{
- fIncrementX = fWidth / nSteps;
- fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
- }
+ // get colors & calculate steps
+ const basegfx::BColor aCStart(cs_l->getColor());
+ const basegfx::BColor aCEnd(cs_r->getColor());
+ const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
+ maGradientInfo.getRequestedSteps(), aCStart, aCEnd));
- B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
+ // get offsets & calculate StripeWidth
+ const double fOffsetStart(cs_l->getOffset());
+ const double fOffsetEnd(cs_r->getOffset());
+ const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);
- for(sal_uInt32 a(1); a < nSteps; a++)
- {
- // next step
- fWidth -= fIncrementX;
- fHeight -= fIncrementY;
+ // prepare individual increments for X/Y dependent on aspect ratio
+ const double fAR(maGradientInfo.getAspectRatio());
+ const bool bMTO(fAR > 1.0);
+ const double fIncrementX(bMTO ? fStripeWidth / fAR : fStripeWidth);
+ const double fIncrementY(bMTO ? fStripeWidth : fStripeWidth * fAR);
+
+ // get correct start for innner loop (see above)
+ const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0);
+
+ for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
+ {
+ // next step, actively adapt outer-loop w/h values
+ fAllWidth += fIncrementX;
+ fAllHeight += fIncrementY;
+
+ // set and add at target
+ B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
- aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::utils::createScaleB2DHomMatrix(fWidth, fHeight);
- aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(nSteps - 1));
- rEntries.push_back(aB2DHomMatrixAndBColor);
+ aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform()
+ * basegfx::utils::createScaleB2DHomMatrix(1.0 - fAllWidth, 1.0 - fAllHeight);
+ aB2DHomMatrixAndBColor.maBColor = interpolate(aCStart, aCEnd, double(innerLoop) / double(nSteps - 1));
+ rEntries.push_back(aB2DHomMatrixAndBColor);
+ }
}
}
void GeoTexSvxGradientElliptical::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
- if(mnColorSteps.size() <= 1)
+ // no color at all, done
+ if (mnColorSteps.empty())
+ return;
+
+ // just single color, done
+ if (mnColorSteps.size() < 2)
{
rBColor = mnColorSteps.front().getColor();
+ return;
}
- else
- {
- const double fScaler(basegfx::utils::getEllipticalGradientAlpha(rUV, maGradientInfo));
-
- const basegfx::BColor maStart(mnColorSteps.front().getColor());
- const basegfx::BColor maEnd(mnColorSteps.back().getColor());
- rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
- }
+ // 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);
}
@@ -538,42 +557,65 @@ namespace drawinglayer::texture
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
- if(mnColorSteps.size() <= 1)
+ // no color at all, done
+ if (mnColorSteps.empty())
return;
- const basegfx::BColor maStart(mnColorSteps.front().getColor());
- const basegfx::BColor maEnd(mnColorSteps.back().getColor());
- const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
- maGradientInfo.getRequestedSteps(), maStart, maEnd));
+ // fill in return parameter rOuterColor before returning
+ rOuterColor = mnColorSteps.front().getColor();
- rOuterColor = maStart;
- const double fStepSize(1.0 / nSteps);
- B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
+ // only one color, done
+ if (mnColorSteps.size() < 2)
+ return;
- for(sal_uInt32 a(1); a < nSteps; a++)
+ // 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++)
{
- const double fSize(1.0 - (fStepSize * a));
- aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::utils::createScaleB2DHomMatrix(fSize, fSize);
- aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(nSteps - 1));
- rEntries.push_back(aB2DHomMatrixAndBColor);
+ // get colors & calculate steps
+ const basegfx::BColor aCStart(cs_l->getColor());
+ const basegfx::BColor aCEnd(cs_r->getColor());
+ 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 fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);
+
+ // get correct start for innner loop (see above)
+ const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0);
+
+ for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
+ {
+ // calculate size/radius
+ const double fSize(1.0 - (fOffsetStart + (fStripeWidth * innerLoop)));
+
+ // set and add at target
+ B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
+
+ aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::utils::createScaleB2DHomMatrix(fSize, fSize);
+ aB2DHomMatrixAndBColor.maBColor = interpolate(aCStart, aCEnd, double(innerLoop) / double(nSteps - 1));
+ rEntries.push_back(aB2DHomMatrixAndBColor);
+ }
}
}
void GeoTexSvxGradientSquare::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
- if(mnColorSteps.size() <= 1)
+ // no color at all, done
+ if (mnColorSteps.empty())
+ return;
+
+ // just single color, done
+ if (mnColorSteps.size() < 2)
{
rBColor = mnColorSteps.front().getColor();
+ return;
}
- else
- {
- const double fScaler(basegfx::utils::getSquareGradientAlpha(rUV, maGradientInfo));
-
- const basegfx::BColor maStart(mnColorSteps.front().getColor());
- const basegfx::BColor maEnd(mnColorSteps.back().getColor());
- rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
- }
+ // 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);
}
@@ -603,60 +645,79 @@ namespace drawinglayer::texture
std::vector< B2DHomMatrixAndBColor >& rEntries,
basegfx::BColor& rOuterColor)
{
- if(mnColorSteps.size() <= 1)
+ // no color at all, done
+ if (mnColorSteps.empty())
return;
- const basegfx::BColor maStart(mnColorSteps.front().getColor());
- const basegfx::BColor maEnd(mnColorSteps.back().getColor());
- const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
- maGradientInfo.getRequestedSteps(), maStart, maEnd));
+ // fill in return parameter rOuterColor before returning
+ rOuterColor = mnColorSteps.front().getColor();
+
+ // only one color, done
+ if (mnColorSteps.size() < 2)
+ return;
- rOuterColor = maStart;
- double fWidth(1.0);
- double fHeight(1.0);
- double fIncrementX(0.0);
- double fIncrementY(0.0);
+ // need to start with the offsets *outside* of all loops, these will
+ // get modified non-linear below, now in more than one gradient section,
+ // but *constantly* over the whole range
+ double fAllWidth(0.0);
+ double fAllHeight(0.0);
- if(maGradientInfo.getAspectRatio() > 1.0)
- {
- fIncrementY = fHeight / nSteps;
- fIncrementX = fIncrementY / maGradientInfo.getAspectRatio();
- }
- else
+ // 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++)
{
- fIncrementX = fWidth / nSteps;
- fIncrementY = fIncrementX * maGradientInfo.getAspectRatio();
- }
+ // get colors & calculate steps
+ const basegfx::BColor aCStart(cs_l->getColor());
+ const basegfx::BColor aCEnd(cs_r->getColor());
+ 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 fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);
- B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
+ // prepare individual increments for X/Y dependent on aspect ratio
+ const double fAR(maGradientInfo.getAspectRatio());
+ const bool bMTO(fAR > 1.0);
+ const double fIncrementX(bMTO ? fStripeWidth / fAR : fStripeWidth);
+ const double fIncrementY(bMTO ? fStripeWidth : fStripeWidth * fAR);
- for(sal_uInt32 a(1); a < nSteps; a++)
- {
- // next step
- fWidth -= fIncrementX;
- fHeight -= fIncrementY;
+ // get correct start for innner loop (see above)
+ const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() ? 1 : 0);
- aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * basegfx::utils::createScaleB2DHomMatrix(fWidth, fHeight);
- aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(nSteps - 1));
- rEntries.push_back(aB2DHomMatrixAndBColor);
+ for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
+ {
+ // next step, actively adapt outer-loop w/h values
+ fAllWidth += fIncrementX;
+ fAllHeight += fIncrementY;
+
+ // set and add at target
+ B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
+
+ aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform()
+ * basegfx::utils::createScaleB2DHomMatrix(1.0 - fAllWidth, 1.0 - fAllHeight);
+ aB2DHomMatrixAndBColor.maBColor = interpolate(aCStart, aCEnd, double(innerLoop) / double(nSteps - 1));
+ rEntries.push_back(aB2DHomMatrixAndBColor);
+ }
}
}
void GeoTexSvxGradientRect::modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& /*rfOpacity*/) const
{
- if(mnColorSteps.size() <= 1)
+ // no color at all, done
+ if (mnColorSteps.empty())
+ return;
+
+ // just single color, done
+ if (mnColorSteps.size() < 2)
{
rBColor = mnColorSteps.front().getColor();
+ return;
}
- else
- {
- const double fScaler(basegfx::utils::getRectangularGradientAlpha(rUV, maGradientInfo));
- const basegfx::BColor maStart(mnColorSteps.front().getColor());
- const basegfx::BColor maEnd(mnColorSteps.back().getColor());
-
- rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
- }
+ // 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);
}