basegfx/source/tools/gradienttools.cxx  |   18 ----
 drawinglayer/source/texture/texture.cxx |  119 +++++++++++++++++++-------------
 2 files changed, 73 insertions(+), 64 deletions(-)

New commits:
commit 94cdbfb9316ab3b04327f960fa40aee07abbba91
Author:     Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de>
AuthorDate: Thu Feb 23 11:22:31 2023 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Thu Feb 23 13:06:06 2023 +0000

    MCGR: Adapted GradientAxial to make use of MCGR
    
    Added to make GradientAxial work using the MCGR
    as 2nd of six types. This one was complicated
    since it uses the gradient(s) 'reversed' when you
    look at it, from outside to inside. Had to do
    quite some tickeling to get it all work, but
    looks good now.
    
    For modifyBColor I Could re-use the started
    tooling as planned.
    
    To get the reverse usage working I ended up in
    1st adapting the previous usage to make more use
    of std::iterator and reverse_iterator to be able
    to use the reversed state of the ColorSteps more
    'controlled' as if trying to adapt the numerical
    indices to the vector (that ended in chaos).
    
    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 this one, see the static
    variable nUseGradientSteps.
    
    Change-Id: I0117ec9a24b5e55869b3e2741c67fb87b549db97
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147510
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/basegfx/source/tools/gradienttools.cxx 
b/basegfx/source/tools/gradienttools.cxx
index 4aa909fcf58c..b27443898f4e 100644
--- a/basegfx/source/tools/gradienttools.cxx
+++ b/basegfx/source/tools/gradienttools.cxx
@@ -467,7 +467,7 @@ namespace basegfx
         {
             const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
 
-            // Ignore Y, this is not needed at all for Y-Oriented gradients
+            // Ignore X, this is not needed at all for Y-Oriented gradients
             // if(aCoor.getX() < 0.0 || aCoor.getX() > 1.0)
             // {
             //     return 0.0;
@@ -483,13 +483,6 @@ namespace basegfx
                 return 1.0; // end value for outside
             }
 
-            // const sal_uInt32 nSteps(rGradInfo.getRequestedSteps());
-
-            // if(nSteps)
-            // {
-            //     return floor(aCoor.getY() * nSteps) / double(nSteps - 1);
-            // }
-
             return aCoor.getY();
         }
 
@@ -497,7 +490,7 @@ namespace basegfx
         {
             const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
 
-            // Ignore Y, this is not needed at all for Y-Oriented gradients
+            // Ignore X, this is not needed at all for Y-Oriented gradients
             //if(aCoor.getX() < 0.0 || aCoor.getX() > 1.0)
             //{
             //    return 0.0;
@@ -510,13 +503,6 @@ namespace basegfx
                 return 1.0; // use end value when outside in Y
             }
 
-            const sal_uInt32 nSteps(rGradInfo.getRequestedSteps());
-
-            if(nSteps)
-            {
-                return floor(fAbsY * nSteps) / double(nSteps - 1);
-            }
-
             return fAbsY;
         }
 
diff --git a/drawinglayer/source/texture/texture.cxx 
b/drawinglayer/source/texture/texture.cxx
index 326d3bbe9146..73110fc8b8fd 100644
--- a/drawinglayer/source/texture/texture.cxx
+++ b/drawinglayer/source/texture/texture.cxx
@@ -138,18 +138,13 @@ namespace drawinglayer::texture
             if (mnColorSteps.empty())
                 return;
 
-            // get start color and also cc to rOuterColor
-            basegfx::BColor aCStart(mnColorSteps[0].getColor());
-            rOuterColor = aCStart;
+            // fill in return parameter rOuterColor before returning
+            rOuterColor = mnColorSteps.front().getColor();
 
             // only one color, done
             if (mnColorSteps.size() < 2)
                 return;
 
-            // here we could check that fOffsetStart == 
mnColorSteps[0].getOffset(),
-            // but just assume/correct that StartColor is at 0.0
-            double fOffsetStart(0.0 /*mnColorSteps[0].getOffset()*/);
-
             // prepare unit range transform
             basegfx::B2DHomMatrix aPattern;
 
@@ -161,14 +156,19 @@ namespace drawinglayer::texture
             aPattern.scale(mfUnitWidth, 1.0);
             aPattern.translate(mfUnitMinX, 0.0);
 
-            for (size_t outerLoop(1); outerLoop < mnColorSteps.size(); 
outerLoop++)
+            // 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 basegfx::BColor 
aCEnd(mnColorSteps[outerLoop].getColor());
+                // 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));
-                const double fOffsetEnd(mnColorSteps[outerLoop].getOffset());
 
+                // get offsets & calculate StripeWidth
                 // nSteps is >= 1, see getRequestedSteps, so no check needed 
here
+                const double fOffsetStart(cs_l->getOffset());
+                const double fOffsetEnd(cs_r->getOffset());
                 const double fStripeWidth((fOffsetEnd - fOffsetStart) / 
nSteps);
 
                 // for the 1st color range we do not need to create the 1st 
step
@@ -177,7 +177,7 @@ namespace drawinglayer::texture
                 // colored using rOuterColor.
                 // We *need* to create this though for all 'inner' color ranges
                 // to get a correct start
-                const sal_uInt32 nStartInnerLoop(1 == outerLoop ? 1 : 0);
+                const sal_uInt32 nStartInnerLoop(cs_l == mnColorSteps.begin() 
? 1 : 0);
 
                 for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < 
nSteps; innerLoop++)
                 {
@@ -205,9 +205,6 @@ namespace drawinglayer::texture
                     aB2DHomMatrixAndBColor.maBColor = interpolate(aCStart, 
aCEnd, double(innerLoop) / double(nSteps - 1));
                     rEntries.push_back(aB2DHomMatrixAndBColor);
                 }
-
-                aCStart = aCEnd;
-                fOffsetStart = fOffsetEnd;
             }
         }
 
@@ -264,59 +261,85 @@ 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
+            // CAUTION: for GradientAxial the color range is inverted (!)
+            rOuterColor = mnColorSteps.back().getColor();
 
-            rOuterColor = maEnd;
-            const double fStripeWidth(1.0 / nSteps);
-            B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
+            // only one color, done
+            if (mnColorSteps.size() < 2)
+                return;
 
-            for(sal_uInt32 a(1); a < nSteps; a++)
+            // prepare unit range transform
+            basegfx::B2DHomMatrix aPattern;
+
+            // bring in X from unit circle [-1, -1, 1, 1] to unit range [0, 0, 
1, 1]
+            aPattern.scale(0.5, 1.0);
+            aPattern.translate(0.5, 0.0);
+
+            // scale/translate in X
+            aPattern.scale(mfUnitWidth, 1.0);
+            aPattern.translate(mfUnitMinX, 0.0);
+
+            // outer loop over ColorSteps, each is from cs_l to cs_r
+            // CAUTION: for GradientAxial the color range is used inverted (!)
+            //          thus, to loop backward, use rbegin/rend
+            for (auto cs_r(mnColorSteps.rbegin()), cs_l(cs_r + 1); cs_l != 
mnColorSteps.rend(); cs_l++, cs_r++)
             {
-                const double fPos(fStripeWidth * a);
-                basegfx::B2DHomMatrix aNew;
+                // 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));
 
-                // bring in X from unit circle [-1, -1, 1, 1] to unit range 
[0, 0, 1, 1]
-                aNew.scale(0.5, 1.0);
-                aNew.translate(0.5, 0.0);
+                // get offsets & calculate StripeWidth
+                // nSteps is >= 1, see getRequestedSteps, so no check needed 
here
+                const double fOffsetStart(cs_l->getOffset());
+                const double fOffsetEnd(cs_r->getOffset());
+                const double fStripeWidth((fOffsetEnd - fOffsetStart) / 
nSteps);
 
-                // scale/translate in X
-                aNew.scale(mfUnitWidth, 1.0);
-                aNew.translate(mfUnitMinX, 0.0);
+                // for the 1st color range we do not need to create the 1st 
step, see above
+                const sal_uInt32 nStartInnerLoop(cs_r == mnColorSteps.rbegin() 
? 1 : 0);
 
-                // already centered in Y on X-Axis, just scale in Y
-                aNew.scale(1.0, 1.0 - fPos);
+                for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < 
nSteps; innerLoop++)
+                {
+                    // calculate pos in Y
+                    const double fPos(fOffsetEnd - (fStripeWidth * innerLoop));
 
-                // set at target
-                aB2DHomMatrixAndBColor.maB2DHomMatrix = 
maGradientInfo.getTextureTransform() * aNew;
+                    // already centered in Y on X-Axis, just scale in Y
+                    basegfx::B2DHomMatrix aNew(aPattern);
+                    aNew.scale(1.0, fPos);
 
-                // interpolate and set color
-                aB2DHomMatrixAndBColor.maBColor = interpolate(maEnd, maStart, 
double(a) / double(nSteps - 1));
+                    // set and add at target
+                    B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
 
-                rEntries.push_back(aB2DHomMatrixAndBColor);
+                    aB2DHomMatrixAndBColor.maB2DHomMatrix = 
maGradientInfo.getTextureTransform() * aNew;
+                    aB2DHomMatrixAndBColor.maBColor = interpolate(aCEnd, 
aCStart, double(innerLoop) / double(nSteps - 1));
+                    rEntries.push_back(aB2DHomMatrixAndBColor);
+                }
             }
         }
 
         void GeoTexSvxGradientAxial::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();
+                // CAUTION: for GradientAxial the color range is used inverted 
(!)
+                rBColor = mnColorSteps.back().getColor();
+                return;
             }
-            else
-            {
-                const double 
fScaler(basegfx::utils::getAxialGradientAlpha(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::getAxialGradientAlpha(rUV, 
maGradientInfo));
+            rBColor = basegfx::utils::modifyBColor(mnColorSteps, fScaler, 
mnRequestedSteps);
         }
 
 

Reply via email to