diff options
author | Armin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de> | 2023-02-24 17:34:53 +0100 |
---|---|---|
committer | Armin Le Grand <Armin.Le.Grand@me.com> | 2023-02-27 17:43:13 +0000 |
commit | 16e728a8a88a7a04acec069512a5268ae89cf420 (patch) | |
tree | e1fe9c3ffb38daca8ac025ffdc2a7fcd8f08420f /drawinglayer | |
parent | 9027920783dd04db925c41b559abe6442cedf39e (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.cxx | 253 |
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); } |