summaryrefslogtreecommitdiff
path: root/drawinglayer/source/texture
diff options
context:
space:
mode:
authorArmin Le Grand (allotropia) <armin.le.grand.extern@allotropia.de>2023-02-21 18:35:39 +0100
committerArmin Le Grand <Armin.Le.Grand@me.com>2023-02-22 09:13:20 +0000
commitc4f252035cd71f9a1b226e69095cc9f4e8f19f3e (patch)
tree3fba6649662028a15288bbd803acea5a73f500ad /drawinglayer/source/texture
parent0c14b1ba0d560c1de120d2562da6b24db9802149 (diff)
MCGR: Adapted GradientLinear to make use of MCGR
Added to make GradientLinear work using the MCGR as 1st of six types. Had to do quite some tickeling to get it all work, but looks good. Five more to go, already started to put some things to tooling to make re-usable for the other types. Besides adapting this the main change is that the adaption of defined step-count (versus automatic) has to be done in modifyBColor now instead of the back-mapping methods (e.g. getLinearGradientAlpha). It is still 100% backward-compatible, so as long as there is no source using this it will stay invisible - by purpose. I started to do quite some tests (and fixes/ adaptions in consequence), see the static variable nUseGradientSteps. If you want to play with this, you might set it to '1' instead of '0' and use a linear gradient on an object. Change-Id: I9d61934defb0674456247f2879f0a89b6a5e50f7 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/147413 Tested-by: Jenkins Reviewed-by: Armin Le Grand <Armin.Le.Grand@me.com>
Diffstat (limited to 'drawinglayer/source/texture')
-rw-r--r--drawinglayer/source/texture/texture.cxx95
1 files changed, 63 insertions, 32 deletions
diff --git a/drawinglayer/source/texture/texture.cxx b/drawinglayer/source/texture/texture.cxx
index 623336187495..326d3bbe9146 100644
--- a/drawinglayer/source/texture/texture.cxx
+++ b/drawinglayer/source/texture/texture.cxx
@@ -134,17 +134,23 @@ 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));
+ // get start color and also cc to rOuterColor
+ basegfx::BColor aCStart(mnColorSteps[0].getColor());
+ rOuterColor = aCStart;
- rOuterColor = maStart;
- const double fStripeWidth(1.0 / nSteps);
- B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
+ // 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;
// bring from unit circle [-1, -1, 1, 1] to unit range [0, 0, 1, 1]
@@ -155,47 +161,72 @@ namespace drawinglayer::texture
aPattern.scale(mfUnitWidth, 1.0);
aPattern.translate(mfUnitMinX, 0.0);
- for(sal_uInt32 a(1); a < nSteps; a++)
+ for (size_t outerLoop(1); outerLoop < mnColorSteps.size(); outerLoop++)
{
- const double fPos(fStripeWidth * a);
- basegfx::B2DHomMatrix aNew(aPattern);
+ const basegfx::BColor aCEnd(mnColorSteps[outerLoop].getColor());
+ const sal_uInt32 nSteps(basegfx::utils::calculateNumberOfSteps(
+ maGradientInfo.getRequestedSteps(), aCStart, aCEnd));
+ const double fOffsetEnd(mnColorSteps[outerLoop].getOffset());
- // scale and translate in Y
- double fHeight(1.0 - fPos);
+ // nSteps is >= 1, see getRequestedSteps, so no check needed here
+ const double fStripeWidth((fOffsetEnd - fOffsetStart) / nSteps);
- if(a + 1 == nSteps && mfUnitMaxY > 1.0)
+ // for the 1st color range we do not need to create the 1st step
+ // since it will be equal to StartColor and thus rOuterColor, so
+ // will be painted by the 1st, always-created background polygon
+ // 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);
+
+ for (sal_uInt32 innerLoop(nStartInnerLoop); innerLoop < nSteps; innerLoop++)
{
- fHeight += mfUnitMaxY - 1.0;
- }
+ // calculate pos in Y
+ const double fPos(fOffsetStart + (fStripeWidth * innerLoop));
- aNew.scale(1.0, fHeight);
- aNew.translate(0.0, fPos);
+ // scale and translate in Y. For GradientLinear we always have
+ // the full height
+ double fHeight(1.0 - fPos);
- // set at target
- aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
+ if (mfUnitMaxY > 1.0)
+ {
+ // extend when difference between definition and OutputRange exists
+ fHeight += mfUnitMaxY - 1.0;
+ }
- // interpolate and set color
- aB2DHomMatrixAndBColor.maBColor = interpolate(maStart, maEnd, double(a) / double(nSteps - 1));
+ basegfx::B2DHomMatrix aNew(aPattern);
+ aNew.scale(1.0, fHeight);
+ aNew.translate(0.0, fPos);
- rEntries.push_back(aB2DHomMatrixAndBColor);
+ // set and add at target
+ B2DHomMatrixAndBColor aB2DHomMatrixAndBColor;
+
+ aB2DHomMatrixAndBColor.maB2DHomMatrix = maGradientInfo.getTextureTransform() * aNew;
+ aB2DHomMatrixAndBColor.maBColor = interpolate(aCStart, aCEnd, double(innerLoop) / double(nSteps - 1));
+ rEntries.push_back(aB2DHomMatrixAndBColor);
+ }
+
+ aCStart = aCEnd;
+ fOffsetStart = fOffsetEnd;
}
}
void GeoTexSvxGradientLinear::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::getLinearGradientAlpha(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::getLinearGradientAlpha(rUV, maGradientInfo));
+ rBColor = basegfx::utils::modifyBColor(mnColorSteps, fScaler, mnRequestedSteps);
}
GeoTexSvxGradientAxial::GeoTexSvxGradientAxial(