24#include <com/sun/star/awt/Gradient2.hpp>
25#include <osl/endian.h>
32 bool ODFGradientInfo::operator==(
const ODFGradientInfo& rODFGradientInfo)
const
34 return getTextureTransform() == rODFGradientInfo.getTextureTransform()
35 && getAspectRatio() == rODFGradientInfo.getAspectRatio()
36 && getRequestedSteps() == rODFGradientInfo.getRequestedSteps();
39 const B2DHomMatrix& ODFGradientInfo::getBackTextureTransform()
const
41 if(maBackTextureTransform.isIdentity())
43 const_cast< ODFGradientInfo*
>(
this)->maBackTextureTransform = getTextureTransform();
44 const_cast< ODFGradientInfo*
>(
this)->maBackTextureTransform.invert();
47 return maBackTextureTransform;
64 double fTargetSizeX(rTargetRange.
getWidth());
65 double fTargetSizeY(rTargetRange.
getHeight());
66 double fTargetOffsetX(rTargetRange.
getMinX());
67 double fTargetOffsetY(rTargetRange.
getMinY());
74 const double fAbsCos(fabs(cos(fAngle)));
75 const double fAbsSin(fabs(sin(fAngle)));
76 const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
77 const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
79 fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
80 fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
85 const double fSizeWithoutBorder(1.0 - fBorder);
89 aTextureTransform.
scale(1.0, fSizeWithoutBorder * 0.5);
96 aTextureTransform.
scale(1.0, fSizeWithoutBorder);
97 aTextureTransform.
translate(0.0, fBorder);
101 aTextureTransform.
scale(fTargetSizeX, fTargetSizeY);
106 const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY);
112 aTextureTransform.
translate(fTargetOffsetX, fTargetOffsetY);
115 const double fAspectRatio(
fTools::equalZero(fTargetSizeY) ? 1.0 : fTargetSizeX / fTargetSizeY);
117 return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps);
135 double fTargetSizeX(rTargetRange.
getWidth());
136 double fTargetSizeY(rTargetRange.
getHeight());
137 double fTargetOffsetX(rTargetRange.
getMinX());
138 double fTargetOffsetY(rTargetRange.
getMinY());
143 const double fOriginalDiag(std::hypot(fTargetSizeX, fTargetSizeY));
145 fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0;
146 fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0;
147 fTargetSizeX = fOriginalDiag;
148 fTargetSizeY = fOriginalDiag;
152 fTargetOffsetX -= ((M_SQRT2 - 1) / 2.0 ) * fTargetSizeX;
153 fTargetOffsetY -= ((M_SQRT2 - 1) / 2.0 ) * fTargetSizeY;
154 fTargetSizeX = M_SQRT2 * fTargetSizeX;
155 fTargetSizeY = M_SQRT2 * fTargetSizeY;
158 const double fHalfBorder((1.0 - fBorder) * 0.5);
160 aTextureTransform.
scale(fHalfBorder, fHalfBorder);
162 aTextureTransform.
scale(fTargetSizeX, fTargetSizeY);
167 const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY);
176 fTargetOffsetX += (rOffset.
getX() - 0.5) * rTargetRange.
getWidth();
177 fTargetOffsetY += (rOffset.
getY() - 0.5) * rTargetRange.
getHeight();
181 aTextureTransform.
translate(fTargetOffsetX, fTargetOffsetY);
184 const double fAspectRatio(fTargetSizeY == 0.0 ? 1.0 : (fTargetSizeX / fTargetSizeY));
186 return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps);
204 double fTargetSizeX(rTargetRange.
getWidth());
205 double fTargetSizeY(rTargetRange.
getHeight());
206 double fTargetOffsetX(rTargetRange.
getMinX());
207 double fTargetOffsetY(rTargetRange.
getMinY());
212 const double fSquareWidth(std::max(fTargetSizeX, fTargetSizeY));
214 fTargetOffsetX -= (fSquareWidth - fTargetSizeX) / 2.0;
215 fTargetOffsetY -= (fSquareWidth - fTargetSizeY) / 2.0;
216 fTargetSizeX = fTargetSizeY = fSquareWidth;
224 const double fAbsCos(fabs(cos(fAngle)));
225 const double fAbsSin(fabs(sin(fAngle)));
226 const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
227 const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
229 fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
230 fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
231 fTargetSizeX = fNewX;
232 fTargetSizeY = fNewY;
235 const double fHalfBorder((1.0 - fBorder) * 0.5);
237 aTextureTransform.
scale(fHalfBorder, fHalfBorder);
239 aTextureTransform.
scale(fTargetSizeX, fTargetSizeY);
244 const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY);
253 fTargetOffsetX += (rOffset.
getX() - 0.5) * rTargetRange.
getWidth();
254 fTargetOffsetY += (rOffset.
getY() - 0.5) * rTargetRange.
getHeight();
258 aTextureTransform.
translate(fTargetOffsetX, fTargetOffsetY);
261 const double fAspectRatio(fTargetSizeY == 0.0 ? 1.0 : (fTargetSizeX / fTargetSizeY));
263 return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps);
285 const bool bAdaptBorder(0 != rGradient.
GetBorder());
287 if (!bAdaptStartEndIntensity && !bAdaptBorder)
297 if (bAdaptStartEndIntensity)
326 const BColor& rSingleColor,
327 const BColor& rSingleAlpha)
329 if (rColorStops.empty())
331 if (rAlphaStops.empty())
346 for (
const auto& cand : rAlphaStops)
348 rColorStops.emplace_back(cand.getStopOffset(), rSingleColor);
355 else if (rAlphaStops.empty())
359 for (
const auto& cand : rColorStops)
361 rAlphaStops.emplace_back(cand.getStopOffset(), rSingleAlpha);
371 bool bNeedToSyncronize(rColorStops.size() != rAlphaStops.size());
373 if (!bNeedToSyncronize)
376 BColorStops::const_iterator aCurrColor(rColorStops.begin());
377 BColorStops::const_iterator aCurrAlpha(rAlphaStops.begin());
379 while (!bNeedToSyncronize &&
380 aCurrColor != rColorStops.end() &&
381 aCurrAlpha != rAlphaStops.end())
383 if (
fTools::equal(aCurrColor->getStopOffset(), aCurrAlpha->getStopOffset()))
390 bNeedToSyncronize =
true;
395 if (bNeedToSyncronize)
398 BColorStops::const_iterator aCurrColor(rColorStops.begin());
399 BColorStops::const_iterator aCurrAlpha(rAlphaStops.begin());
404 bool bRealChange(
false);
407 const bool bColor(aCurrColor != rColorStops.end());
408 const bool bAlpha(aCurrAlpha != rAlphaStops.end());
410 if (bColor && bAlpha)
412 const double fColorOff(aCurrColor->getStopOffset());
413 const double fAlphaOff(aCurrAlpha->getStopOffset());
418 aNewColor.emplace_back(fColorOff, aCurrColor->getStopColor());
427 aNewAlpha.emplace_back(fAlphaOff, aCurrAlpha->getStopColor());
434 aNewColor.emplace_back(fColorOff, aCurrColor->getStopColor());
435 aNewAlpha.emplace_back(fAlphaOff, aCurrAlpha->getStopColor());
442 const double fColorOff(aCurrColor->getStopOffset());
444 aNewColor.emplace_back(fColorOff, aCurrColor->getStopColor());
450 const double fAlphaOff(aCurrAlpha->getStopOffset());
452 aNewAlpha.emplace_back(fAlphaOff, aCurrAlpha->getStopColor());
469 rColorStops = aNewColor;
470 rAlphaStops = aNewAlpha;
476 sal_uInt32 nRequestedSteps,
480 const sal_uInt32 nMaxSteps(sal_uInt32((rStart.
getMaximumDistance(rEnd) * 127.5) + 0.5));
482 if (0 == nRequestedSteps)
484 nRequestedSteps = nMaxSteps;
487 if(nRequestedSteps > nMaxSteps)
489 nRequestedSteps = nMaxSteps;
492 return std::max(sal_uInt32(1), nRequestedSteps);
588 const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
596 if(aCoor.
getY() <= 0.0)
601 if(aCoor.
getY() >= 1.0)
611 const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
619 const double fAbsY(fabs(aCoor.
getY()));
631 const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
633 if(aCoor.
getX() < -1.0 || aCoor.
getX() > 1.0 || aCoor.
getY() < -1.0 || aCoor.
getY() > 1.0)
638 return 1.0 - std::hypot(aCoor.
getX(), aCoor.
getY());
643 const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
645 if(aCoor.
getX() < -1.0 || aCoor.
getX() > 1.0 || aCoor.
getY() < -1.0 || aCoor.
getY() > 1.0)
650 double fAspectRatio(rGradInfo.getAspectRatio());
658 if(fAspectRatio > 1.0)
660 t = 1.0 - std::hypot(aCoor.
getX() / fAspectRatio, aCoor.
getY());
662 else if(fAspectRatio > 0.0)
664 t = 1.0 - std::hypot(aCoor.
getX(), aCoor.
getY() * fAspectRatio);
672 const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
673 const double fAbsX(fabs(aCoor.
getX()));
680 const double fAbsY(fabs(aCoor.
getY()));
687 return 1.0 - std::max(fAbsX, fAbsY);
692 const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
693 double fAbsX(fabs(aCoor.
getX()));
700 double fAbsY(fabs(aCoor.
getY()));
741 double fAspectRatio(rGradInfo.getAspectRatio());
742 if(fAspectRatio > 1.0)
744 fAbsX = ((fAbsX - 1) * fAspectRatio) + 1;
746 else if(fAspectRatio > 0.0)
748 fAbsY = ((fAbsY - 1) / fAspectRatio) + 1;
751 return 1.0 - std::max(fAbsX, fAbsY);
void translate(double fX, double fY)
void scale(double fX, double fY)
Base Point class with two double values.
A two-dimensional interval over doubles.
Base Point class with two double values.
bool isSingleColor(BColor &rSingleColor) const
BColor getInterpolatedBColor(double fPosition, sal_uInt32 nRequestedSteps, BColorStopRange &rLastColorStopRange) const
Base Color class with three double values.
double getMaximumDistance(const BColor &rColor) const
sal_uInt16 GetBorder() const
sal_uInt16 GetStartIntens() const
void tryToApplyStartEndIntensity()
const basegfx::BColorStops & GetColorStops() const
sal_uInt16 GetEndIntens() const
TYPE getWidth() const
return difference between upper and lower X value. returns 0 for empty sets.
TYPE getMinX() const
get lower bound of the set. returns arbitrary values for empty sets.
TYPE getMinY() const
get lower bound of the set. returns arbitrary values for empty sets.
TYPE getHeight() const
return difference between upper and lower Y value. returns 0 for empty sets.
TYPE getX() const
Get X-Coordinate of 2D Tuple.
TYPE getY() const
Get Y-Coordinate of 2D Tuple.
ODFGradientInfo createRadialODFGradientInfo(const B2DRange &rTargetArea, const B2DVector &rOffset, sal_uInt32 nSteps, double fBorder)
Create matrix for ODF's radial gradient definition.
double getAxialGradientAlpha(const B2DPoint &rUV, const ODFGradientInfo &rGradInfo)
Calculate axial gradient blend value.
ODFGradientInfo createAxialODFGradientInfo(const B2DRange &rTargetArea, sal_uInt32 nSteps, double fBorder, double fAngle)
Create matrix for ODF's axial gradient definition.
double getLinearGradientAlpha(const B2DPoint &rUV, const ODFGradientInfo &rGradInfo)
Calculate linear gradient blend value.
B2DHomMatrix createRotateAroundPoint(double fPointX, double fPointY, double fRadiant)
special for the often used case of rotation around a point
double getRectangularGradientAlpha(const B2DPoint &rUV, const ODFGradientInfo &rGradInfo)
Calculate rectangular gradient blend value.
double getEllipticalGradientAlpha(const B2DPoint &rUV, const ODFGradientInfo &rGradInfo)
Calculate elliptical gradient blend value.
double getSquareGradientAlpha(const B2DPoint &rUV, const ODFGradientInfo &rGradInfo)
Calculate square gradient blend value.
void synchronizeColorStops(BColorStops &rColorStops, BColorStops &rAlphaStops, const BColor &rSingleColor, const BColor &rSingleAlpha)
ODFGradientInfo createLinearODFGradientInfo(const B2DRange &rTargetArea, sal_uInt32 nSteps, double fBorder, double fAngle)
Create matrix for ODF's linear gradient definition.
void prepareColorStops(const basegfx::BGradient &rGradient, BColorStops &rColorStops, BColor &rSingleColor)
double getRadialGradientAlpha(const B2DPoint &rUV, const ODFGradientInfo &rGradInfo)
Calculate radial gradient blend value.
ODFGradientInfo createSquareODFGradientInfo(const B2DRange &rTargetArea, const B2DVector &rOffset, sal_uInt32 nSteps, double fBorder, double fAngle)
Create matrix for ODF's square gradient definition.
ODFGradientInfo createEllipticalODFGradientInfo(const B2DRange &rTargetArea, const B2DVector &rOffset, sal_uInt32 nSteps, double fBorder, double fAngle)
Create matrix for ODF's elliptical gradient definition.
ODFGradientInfo createRectangularODFGradientInfo(const B2DRange &rTargetArea, const B2DVector &rOffset, sal_uInt32 nSteps, double fBorder, double fAngle)
Create matrix for ODF's rectangular gradient definition.
sal_uInt32 calculateNumberOfSteps(sal_uInt32 nRequestedSteps, const BColor &rStart, const BColor &rEnd)
static ODFGradientInfo initEllipticalGradientInfo(const B2DRange &rTargetRange, const B2DVector &rOffset, sal_uInt32 nSteps, double fBorder, double fAngle, bool bCircular)
Most of the setup for radial & ellipsoidal gradient is the same, except for the border treatment.
static ODFGradientInfo init1DGradientInfo(const B2DRange &rTargetRange, sal_uInt32 nSteps, double fBorder, double fAngle, bool bAxial)
Most of the setup for linear & axial gradient is the same, except for the border treatment.
static ODFGradientInfo initRectGradientInfo(const B2DRange &rTargetRange, const B2DVector &rOffset, sal_uInt32 nSteps, double fBorder, double fAngle, bool bSquare)
Setup for rect & square gradient is exactly the same.