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.Grand@me.com>
This commit is contained in:
parent
bddc275d1e
commit
94cdbfb931
2 changed files with 74 additions and 65 deletions
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
rBColor = mnColorSteps.front().getColor();
|
||||
}
|
||||
else
|
||||
{
|
||||
const double fScaler(basegfx::utils::getAxialGradientAlpha(rUV, maGradientInfo));
|
||||
// no color at all, done
|
||||
if (mnColorSteps.empty())
|
||||
return;
|
||||
|
||||
const basegfx::BColor maStart(mnColorSteps.front().getColor());
|
||||
const basegfx::BColor maEnd(mnColorSteps.back().getColor());
|
||||
|
||||
rBColor = basegfx::interpolate(maStart, maEnd, fScaler);
|
||||
// just single color, done
|
||||
if (mnColorSteps.size() < 2)
|
||||
{
|
||||
// CAUTION: for GradientAxial the color range is used inverted (!)
|
||||
rBColor = mnColorSteps.back().getColor();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue