109dbbe93SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 309dbbe93SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 409dbbe93SAndrew Rist * or more contributor license agreements. See the NOTICE file 509dbbe93SAndrew Rist * distributed with this work for additional information 609dbbe93SAndrew Rist * regarding copyright ownership. The ASF licenses this file 709dbbe93SAndrew Rist * to you under the Apache License, Version 2.0 (the 809dbbe93SAndrew Rist * "License"); you may not use this file except in compliance 909dbbe93SAndrew Rist * with the License. You may obtain a copy of the License at 10cdf0e10cSrcweir * 1109dbbe93SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12cdf0e10cSrcweir * 1309dbbe93SAndrew Rist * Unless required by applicable law or agreed to in writing, 1409dbbe93SAndrew Rist * software distributed under the License is distributed on an 1509dbbe93SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 1609dbbe93SAndrew Rist * KIND, either express or implied. See the License for the 1709dbbe93SAndrew Rist * specific language governing permissions and limitations 1809dbbe93SAndrew Rist * under the License. 19cdf0e10cSrcweir * 2009dbbe93SAndrew Rist *************************************************************/ 2109dbbe93SAndrew Rist 2209dbbe93SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_basegfx.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <basegfx/tools/gradienttools.hxx> 28cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 29cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx> 30cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx> 31cdf0e10cSrcweir 32cdf0e10cSrcweir namespace basegfx 33cdf0e10cSrcweir { operator ==(const ODFGradientInfo & rODFGradientInfo) const3496fc4b33SArmin Le Grand bool ODFGradientInfo::operator==(const ODFGradientInfo& rODFGradientInfo) const 3596fc4b33SArmin Le Grand { 3696fc4b33SArmin Le Grand return getTextureTransform() == rODFGradientInfo.getTextureTransform() 3796fc4b33SArmin Le Grand && getAspectRatio() == rODFGradientInfo.getAspectRatio() 3896fc4b33SArmin Le Grand && getSteps() == rODFGradientInfo.getSteps(); 3996fc4b33SArmin Le Grand } 4096fc4b33SArmin Le Grand getBackTextureTransform() const4196fc4b33SArmin Le Grand const B2DHomMatrix& ODFGradientInfo::getBackTextureTransform() const 4296fc4b33SArmin Le Grand { 4396fc4b33SArmin Le Grand if(maBackTextureTransform.isIdentity()) 4496fc4b33SArmin Le Grand { 4596fc4b33SArmin Le Grand const_cast< ODFGradientInfo* >(this)->maBackTextureTransform = getTextureTransform(); 4696fc4b33SArmin Le Grand const_cast< ODFGradientInfo* >(this)->maBackTextureTransform.invert(); 4796fc4b33SArmin Le Grand } 4896fc4b33SArmin Le Grand 4996fc4b33SArmin Le Grand return maBackTextureTransform; 5096fc4b33SArmin Le Grand } 5196fc4b33SArmin Le Grand 52cdf0e10cSrcweir /** Most of the setup for linear & axial gradient is the same, except 53cdf0e10cSrcweir for the border treatment. Factored out here. 54cdf0e10cSrcweir */ init1DGradientInfo(const B2DRange & rTargetRange,sal_uInt32 nSteps,double fBorder,double fAngle,bool bAxial)5596fc4b33SArmin Le Grand ODFGradientInfo init1DGradientInfo( 56cdf0e10cSrcweir const B2DRange& rTargetRange, 57cdf0e10cSrcweir sal_uInt32 nSteps, 58cdf0e10cSrcweir double fBorder, 59cdf0e10cSrcweir double fAngle, 60cdf0e10cSrcweir bool bAxial) 61cdf0e10cSrcweir { 6296fc4b33SArmin Le Grand B2DHomMatrix aTextureTransform; 63cdf0e10cSrcweir 64cdf0e10cSrcweir fAngle = -fAngle; 65cdf0e10cSrcweir 66cdf0e10cSrcweir double fTargetSizeX(rTargetRange.getWidth()); 67cdf0e10cSrcweir double fTargetSizeY(rTargetRange.getHeight()); 68cdf0e10cSrcweir double fTargetOffsetX(rTargetRange.getMinX()); 69cdf0e10cSrcweir double fTargetOffsetY(rTargetRange.getMinY()); 70cdf0e10cSrcweir 71cdf0e10cSrcweir // add object expansion 7296fc4b33SArmin Le Grand const bool bAngleUsed(!fTools::equalZero(fAngle)); 7396fc4b33SArmin Le Grand 7496fc4b33SArmin Le Grand if(bAngleUsed) 75cdf0e10cSrcweir { 76cdf0e10cSrcweir const double fAbsCos(fabs(cos(fAngle))); 77cdf0e10cSrcweir const double fAbsSin(fabs(sin(fAngle))); 78cdf0e10cSrcweir const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin); 79cdf0e10cSrcweir const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin); 8096fc4b33SArmin Le Grand 81cdf0e10cSrcweir fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0; 82cdf0e10cSrcweir fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0; 83cdf0e10cSrcweir fTargetSizeX = fNewX; 84cdf0e10cSrcweir fTargetSizeY = fNewY; 85cdf0e10cSrcweir } 86cdf0e10cSrcweir 8796fc4b33SArmin Le Grand const double fSizeWithoutBorder(1.0 - fBorder); 8896fc4b33SArmin Le Grand 89cdf0e10cSrcweir if(bAxial) 90cdf0e10cSrcweir { 9196fc4b33SArmin Le Grand aTextureTransform.scale(1.0, fSizeWithoutBorder * 0.5); 9296fc4b33SArmin Le Grand aTextureTransform.translate(0.0, 0.5); 93cdf0e10cSrcweir } 94cdf0e10cSrcweir else 95cdf0e10cSrcweir { 96cdf0e10cSrcweir if(!fTools::equal(fSizeWithoutBorder, 1.0)) 97cdf0e10cSrcweir { 9896fc4b33SArmin Le Grand aTextureTransform.scale(1.0, fSizeWithoutBorder); 9996fc4b33SArmin Le Grand aTextureTransform.translate(0.0, fBorder); 100cdf0e10cSrcweir } 101cdf0e10cSrcweir } 102cdf0e10cSrcweir 10396fc4b33SArmin Le Grand aTextureTransform.scale(fTargetSizeX, fTargetSizeY); 104cdf0e10cSrcweir 105cdf0e10cSrcweir // add texture rotate after scale to keep perpendicular angles 10696fc4b33SArmin Le Grand if(bAngleUsed) 107cdf0e10cSrcweir { 10896fc4b33SArmin Le Grand const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY); 10996fc4b33SArmin Le Grand 11096fc4b33SArmin Le Grand aTextureTransform *= basegfx::tools::createRotateAroundPoint(aCenter, fAngle); 111cdf0e10cSrcweir } 112cdf0e10cSrcweir 113cdf0e10cSrcweir // add object translate 11496fc4b33SArmin Le Grand aTextureTransform.translate(fTargetOffsetX, fTargetOffsetY); 115cdf0e10cSrcweir 116cdf0e10cSrcweir // prepare aspect for texture 11796fc4b33SArmin Le Grand const double fAspectRatio(fTools::equalZero(fTargetSizeY) ? 1.0 : fTargetSizeX / fTargetSizeY); 118cdf0e10cSrcweir 11996fc4b33SArmin Le Grand return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps); 120cdf0e10cSrcweir } 121cdf0e10cSrcweir 122cdf0e10cSrcweir /** Most of the setup for radial & ellipsoidal gradient is the same, 123cdf0e10cSrcweir except for the border treatment. Factored out here. 124cdf0e10cSrcweir */ initEllipticalGradientInfo(const B2DRange & rTargetRange,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle,bool bCircular)12596fc4b33SArmin Le Grand ODFGradientInfo initEllipticalGradientInfo( 126cdf0e10cSrcweir const B2DRange& rTargetRange, 127cdf0e10cSrcweir const B2DVector& rOffset, 128cdf0e10cSrcweir sal_uInt32 nSteps, 129cdf0e10cSrcweir double fBorder, 130cdf0e10cSrcweir double fAngle, 131cdf0e10cSrcweir bool bCircular) 132cdf0e10cSrcweir { 13396fc4b33SArmin Le Grand B2DHomMatrix aTextureTransform; 134cdf0e10cSrcweir 135cdf0e10cSrcweir fAngle = -fAngle; 136cdf0e10cSrcweir 137cdf0e10cSrcweir double fTargetSizeX(rTargetRange.getWidth()); 138cdf0e10cSrcweir double fTargetSizeY(rTargetRange.getHeight()); 139cdf0e10cSrcweir double fTargetOffsetX(rTargetRange.getMinX()); 140cdf0e10cSrcweir double fTargetOffsetY(rTargetRange.getMinY()); 141cdf0e10cSrcweir 142cdf0e10cSrcweir // add object expansion 143cdf0e10cSrcweir if(bCircular) 144cdf0e10cSrcweir { 145cdf0e10cSrcweir const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY))); 14696fc4b33SArmin Le Grand 147cdf0e10cSrcweir fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0; 148cdf0e10cSrcweir fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0; 149cdf0e10cSrcweir fTargetSizeX = fOriginalDiag; 150cdf0e10cSrcweir fTargetSizeY = fOriginalDiag; 151cdf0e10cSrcweir } 152cdf0e10cSrcweir else 153cdf0e10cSrcweir { 154cdf0e10cSrcweir fTargetOffsetX -= (0.4142 / 2.0 ) * fTargetSizeX; 155cdf0e10cSrcweir fTargetOffsetY -= (0.4142 / 2.0 ) * fTargetSizeY; 156cdf0e10cSrcweir fTargetSizeX = 1.4142 * fTargetSizeX; 157cdf0e10cSrcweir fTargetSizeY = 1.4142 * fTargetSizeY; 158cdf0e10cSrcweir } 159cdf0e10cSrcweir 160cdf0e10cSrcweir const double fHalfBorder((1.0 - fBorder) * 0.5); 161cdf0e10cSrcweir 16296fc4b33SArmin Le Grand aTextureTransform.scale(fHalfBorder, fHalfBorder); 16396fc4b33SArmin Le Grand aTextureTransform.translate(0.5, 0.5); 16496fc4b33SArmin Le Grand aTextureTransform.scale(fTargetSizeX, fTargetSizeY); 165cdf0e10cSrcweir 166cdf0e10cSrcweir // add texture rotate after scale to keep perpendicular angles 16796fc4b33SArmin Le Grand if(!bCircular && !fTools::equalZero(fAngle)) 168cdf0e10cSrcweir { 16996fc4b33SArmin Le Grand const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY); 17096fc4b33SArmin Le Grand 17196fc4b33SArmin Le Grand aTextureTransform *= basegfx::tools::createRotateAroundPoint(aCenter, fAngle); 172cdf0e10cSrcweir } 173cdf0e10cSrcweir 174cdf0e10cSrcweir // add defined offsets after rotation 17596fc4b33SArmin Le Grand if(!fTools::equal(0.5, rOffset.getX()) || !fTools::equal(0.5, rOffset.getY())) 176cdf0e10cSrcweir { 177cdf0e10cSrcweir // use original target size 178cdf0e10cSrcweir fTargetOffsetX += (rOffset.getX() - 0.5) * rTargetRange.getWidth(); 179cdf0e10cSrcweir fTargetOffsetY += (rOffset.getY() - 0.5) * rTargetRange.getHeight(); 180cdf0e10cSrcweir } 181cdf0e10cSrcweir 182cdf0e10cSrcweir // add object translate 18396fc4b33SArmin Le Grand aTextureTransform.translate(fTargetOffsetX, fTargetOffsetY); 184cdf0e10cSrcweir 185cdf0e10cSrcweir // prepare aspect for texture 18696fc4b33SArmin Le Grand const double fAspectRatio((0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0); 187cdf0e10cSrcweir 18896fc4b33SArmin Le Grand return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps); 189cdf0e10cSrcweir } 190cdf0e10cSrcweir 191cdf0e10cSrcweir /** Setup for rect & square gradient is exactly the same. Factored out 192cdf0e10cSrcweir here. 193cdf0e10cSrcweir */ initRectGradientInfo(const B2DRange & rTargetRange,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle,bool bSquare)19496fc4b33SArmin Le Grand ODFGradientInfo initRectGradientInfo( 195cdf0e10cSrcweir const B2DRange& rTargetRange, 196cdf0e10cSrcweir const B2DVector& rOffset, 197cdf0e10cSrcweir sal_uInt32 nSteps, 198cdf0e10cSrcweir double fBorder, 199d939e20fSArmin Le Grand double fAngle, 200d939e20fSArmin Le Grand bool bSquare) 201cdf0e10cSrcweir { 20296fc4b33SArmin Le Grand B2DHomMatrix aTextureTransform; 203cdf0e10cSrcweir 204cdf0e10cSrcweir fAngle = -fAngle; 205cdf0e10cSrcweir 206cdf0e10cSrcweir double fTargetSizeX(rTargetRange.getWidth()); 207cdf0e10cSrcweir double fTargetSizeY(rTargetRange.getHeight()); 208cdf0e10cSrcweir double fTargetOffsetX(rTargetRange.getMinX()); 209cdf0e10cSrcweir double fTargetOffsetY(rTargetRange.getMinY()); 210cdf0e10cSrcweir 211cdf0e10cSrcweir // add object expansion 212d939e20fSArmin Le Grand if(bSquare) 213d939e20fSArmin Le Grand { 214849a1ce7SArmin Le Grand const double fSquareWidth(std::max(fTargetSizeX, fTargetSizeY)); 21596fc4b33SArmin Le Grand 216849a1ce7SArmin Le Grand fTargetOffsetX -= (fSquareWidth - fTargetSizeX) / 2.0; 217849a1ce7SArmin Le Grand fTargetOffsetY -= (fSquareWidth - fTargetSizeY) / 2.0; 218849a1ce7SArmin Le Grand fTargetSizeX = fTargetSizeY = fSquareWidth; 219d939e20fSArmin Le Grand } 220d939e20fSArmin Le Grand 221d939e20fSArmin Le Grand // add object expansion 22296fc4b33SArmin Le Grand const bool bAngleUsed(!fTools::equalZero(fAngle)); 22396fc4b33SArmin Le Grand 22496fc4b33SArmin Le Grand if(bAngleUsed) 225cdf0e10cSrcweir { 226cdf0e10cSrcweir const double fAbsCos(fabs(cos(fAngle))); 227cdf0e10cSrcweir const double fAbsSin(fabs(sin(fAngle))); 228cdf0e10cSrcweir const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin); 229cdf0e10cSrcweir const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin); 23096fc4b33SArmin Le Grand 231cdf0e10cSrcweir fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0; 232cdf0e10cSrcweir fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0; 233cdf0e10cSrcweir fTargetSizeX = fNewX; 234cdf0e10cSrcweir fTargetSizeY = fNewY; 235cdf0e10cSrcweir } 236cdf0e10cSrcweir 237cdf0e10cSrcweir const double fHalfBorder((1.0 - fBorder) * 0.5); 238cdf0e10cSrcweir 23996fc4b33SArmin Le Grand aTextureTransform.scale(fHalfBorder, fHalfBorder); 24096fc4b33SArmin Le Grand aTextureTransform.translate(0.5, 0.5); 24196fc4b33SArmin Le Grand aTextureTransform.scale(fTargetSizeX, fTargetSizeY); 242cdf0e10cSrcweir 243cdf0e10cSrcweir // add texture rotate after scale to keep perpendicular angles 24496fc4b33SArmin Le Grand if(bAngleUsed) 245cdf0e10cSrcweir { 24696fc4b33SArmin Le Grand const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY); 24796fc4b33SArmin Le Grand 24896fc4b33SArmin Le Grand aTextureTransform *= basegfx::tools::createRotateAroundPoint(aCenter, fAngle); 249cdf0e10cSrcweir } 250cdf0e10cSrcweir 251cdf0e10cSrcweir // add defined offsets after rotation 25296fc4b33SArmin Le Grand if(!fTools::equal(0.5, rOffset.getX()) || !fTools::equal(0.5, rOffset.getY())) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir // use scaled target size 255cdf0e10cSrcweir fTargetOffsetX += (rOffset.getX() - 0.5) * fTargetSizeX; 256cdf0e10cSrcweir fTargetOffsetY += (rOffset.getY() - 0.5) * fTargetSizeY; 257cdf0e10cSrcweir } 258cdf0e10cSrcweir 259cdf0e10cSrcweir // add object translate 26096fc4b33SArmin Le Grand aTextureTransform.translate(fTargetOffsetX, fTargetOffsetY); 261cdf0e10cSrcweir 262cdf0e10cSrcweir // prepare aspect for texture 26396fc4b33SArmin Le Grand const double fAspectRatio((0.0 != fTargetSizeY) ? fTargetSizeX / fTargetSizeY : 1.0); 264cdf0e10cSrcweir 26596fc4b33SArmin Le Grand return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps); 266cdf0e10cSrcweir } 267cdf0e10cSrcweir 268cdf0e10cSrcweir namespace tools 269cdf0e10cSrcweir { createLinearODFGradientInfo(const B2DRange & rTargetArea,sal_uInt32 nSteps,double fBorder,double fAngle)27096fc4b33SArmin Le Grand ODFGradientInfo createLinearODFGradientInfo( 271cdf0e10cSrcweir const B2DRange& rTargetArea, 272cdf0e10cSrcweir sal_uInt32 nSteps, 273cdf0e10cSrcweir double fBorder, 274cdf0e10cSrcweir double fAngle) 275cdf0e10cSrcweir { 27696fc4b33SArmin Le Grand return init1DGradientInfo( 277cdf0e10cSrcweir rTargetArea, 278cdf0e10cSrcweir nSteps, 279cdf0e10cSrcweir fBorder, 280cdf0e10cSrcweir fAngle, 281cdf0e10cSrcweir false); 282cdf0e10cSrcweir } 283cdf0e10cSrcweir createAxialODFGradientInfo(const B2DRange & rTargetArea,sal_uInt32 nSteps,double fBorder,double fAngle)28496fc4b33SArmin Le Grand ODFGradientInfo createAxialODFGradientInfo( 285cdf0e10cSrcweir const B2DRange& rTargetArea, 286cdf0e10cSrcweir sal_uInt32 nSteps, 287cdf0e10cSrcweir double fBorder, 288cdf0e10cSrcweir double fAngle) 289cdf0e10cSrcweir { 29096fc4b33SArmin Le Grand return init1DGradientInfo( 291cdf0e10cSrcweir rTargetArea, 292cdf0e10cSrcweir nSteps, 293cdf0e10cSrcweir fBorder, 294cdf0e10cSrcweir fAngle, 295cdf0e10cSrcweir true); 296cdf0e10cSrcweir } 297cdf0e10cSrcweir createRadialODFGradientInfo(const B2DRange & rTargetArea,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder)29896fc4b33SArmin Le Grand ODFGradientInfo createRadialODFGradientInfo( 299cdf0e10cSrcweir const B2DRange& rTargetArea, 300cdf0e10cSrcweir const B2DVector& rOffset, 301cdf0e10cSrcweir sal_uInt32 nSteps, 302cdf0e10cSrcweir double fBorder) 303cdf0e10cSrcweir { 30496fc4b33SArmin Le Grand return initEllipticalGradientInfo( 305cdf0e10cSrcweir rTargetArea, 306cdf0e10cSrcweir rOffset, 307cdf0e10cSrcweir nSteps, 308cdf0e10cSrcweir fBorder, 309cdf0e10cSrcweir 0.0, 310cdf0e10cSrcweir true); 311cdf0e10cSrcweir } 312cdf0e10cSrcweir createEllipticalODFGradientInfo(const B2DRange & rTargetArea,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle)31396fc4b33SArmin Le Grand ODFGradientInfo createEllipticalODFGradientInfo( 314cdf0e10cSrcweir const B2DRange& rTargetArea, 315cdf0e10cSrcweir const B2DVector& rOffset, 316cdf0e10cSrcweir sal_uInt32 nSteps, 317cdf0e10cSrcweir double fBorder, 318cdf0e10cSrcweir double fAngle) 319cdf0e10cSrcweir { 32096fc4b33SArmin Le Grand return initEllipticalGradientInfo( 321cdf0e10cSrcweir rTargetArea, 322cdf0e10cSrcweir rOffset, 323cdf0e10cSrcweir nSteps, 324cdf0e10cSrcweir fBorder, 325cdf0e10cSrcweir fAngle, 326cdf0e10cSrcweir false); 327cdf0e10cSrcweir } 328cdf0e10cSrcweir createSquareODFGradientInfo(const B2DRange & rTargetArea,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle)32996fc4b33SArmin Le Grand ODFGradientInfo createSquareODFGradientInfo( 330cdf0e10cSrcweir const B2DRange& rTargetArea, 331cdf0e10cSrcweir const B2DVector& rOffset, 332cdf0e10cSrcweir sal_uInt32 nSteps, 333cdf0e10cSrcweir double fBorder, 334cdf0e10cSrcweir double fAngle) 335cdf0e10cSrcweir { 33696fc4b33SArmin Le Grand return initRectGradientInfo( 337cdf0e10cSrcweir rTargetArea, 338cdf0e10cSrcweir rOffset, 339cdf0e10cSrcweir nSteps, 340cdf0e10cSrcweir fBorder, 341d939e20fSArmin Le Grand fAngle, 342d939e20fSArmin Le Grand true); 343cdf0e10cSrcweir } 344cdf0e10cSrcweir createRectangularODFGradientInfo(const B2DRange & rTargetArea,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle)34596fc4b33SArmin Le Grand ODFGradientInfo createRectangularODFGradientInfo( 346cdf0e10cSrcweir const B2DRange& rTargetArea, 347cdf0e10cSrcweir const B2DVector& rOffset, 348cdf0e10cSrcweir sal_uInt32 nSteps, 349cdf0e10cSrcweir double fBorder, 350cdf0e10cSrcweir double fAngle) 351cdf0e10cSrcweir { 35296fc4b33SArmin Le Grand return initRectGradientInfo( 353cdf0e10cSrcweir rTargetArea, 354cdf0e10cSrcweir rOffset, 355cdf0e10cSrcweir nSteps, 356cdf0e10cSrcweir fBorder, 357d939e20fSArmin Le Grand fAngle, 358d939e20fSArmin Le Grand false); 359cdf0e10cSrcweir } 360cdf0e10cSrcweir getLinearGradientAlpha(const B2DPoint & rUV,const ODFGradientInfo & rGradInfo)36196fc4b33SArmin Le Grand double getLinearGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 36296fc4b33SArmin Le Grand { 36396fc4b33SArmin Le Grand const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV); 36407540651SArmin Le Grand 365*7024eca9SArmin Le Grand // Ignore Y, this is not needed at all for Y-Oriented gradients 366*7024eca9SArmin Le Grand // if(aCoor.getX() < 0.0 || aCoor.getX() > 1.0) 367*7024eca9SArmin Le Grand // { 368*7024eca9SArmin Le Grand // return 0.0; 369*7024eca9SArmin Le Grand // } 37007540651SArmin Le Grand 37107540651SArmin Le Grand if(aCoor.getY() <= 0.0) 37207540651SArmin Le Grand { 373*7024eca9SArmin Le Grand return 0.0; // start value for inside 37407540651SArmin Le Grand } 37507540651SArmin Le Grand 37607540651SArmin Le Grand if(aCoor.getY() >= 1.0) 37707540651SArmin Le Grand { 378*7024eca9SArmin Le Grand return 1.0; // end value for outside 37907540651SArmin Le Grand } 38007540651SArmin Le Grand 38196fc4b33SArmin Le Grand const sal_uInt32 nSteps(rGradInfo.getSteps()); 382cdf0e10cSrcweir 38396fc4b33SArmin Le Grand if(nSteps) 38496fc4b33SArmin Le Grand { 38507540651SArmin Le Grand return floor(aCoor.getY() * nSteps) / double(nSteps - 1); 38696fc4b33SArmin Le Grand } 38796fc4b33SArmin Le Grand 38807540651SArmin Le Grand return aCoor.getY(); 38996fc4b33SArmin Le Grand } 39096fc4b33SArmin Le Grand getAxialGradientAlpha(const B2DPoint & rUV,const ODFGradientInfo & rGradInfo)39196fc4b33SArmin Le Grand double getAxialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 39296fc4b33SArmin Le Grand { 39396fc4b33SArmin Le Grand const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV); 39407540651SArmin Le Grand 395*7024eca9SArmin Le Grand // Ignore Y, this is not needed at all for Y-Oriented gradients 396*7024eca9SArmin Le Grand //if(aCoor.getX() < 0.0 || aCoor.getX() > 1.0) 397*7024eca9SArmin Le Grand //{ 398*7024eca9SArmin Le Grand // return 0.0; 399*7024eca9SArmin Le Grand //} 40007540651SArmin Le Grand 40107540651SArmin Le Grand const double fAbsY(fabs(aCoor.getY())); 40207540651SArmin Le Grand 40307540651SArmin Le Grand if(fAbsY >= 1.0) 40407540651SArmin Le Grand { 405*7024eca9SArmin Le Grand return 1.0; // use end value when outside in Y 40607540651SArmin Le Grand } 40707540651SArmin Le Grand 40896fc4b33SArmin Le Grand const sal_uInt32 nSteps(rGradInfo.getSteps()); 40996fc4b33SArmin Le Grand 41096fc4b33SArmin Le Grand if(nSteps) 41196fc4b33SArmin Le Grand { 41207540651SArmin Le Grand return floor(fAbsY * nSteps) / double(nSteps - 1); 41396fc4b33SArmin Le Grand } 41496fc4b33SArmin Le Grand 41507540651SArmin Le Grand return fAbsY; 41696fc4b33SArmin Le Grand } 41796fc4b33SArmin Le Grand getRadialGradientAlpha(const B2DPoint & rUV,const ODFGradientInfo & rGradInfo)41896fc4b33SArmin Le Grand double getRadialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 41996fc4b33SArmin Le Grand { 42096fc4b33SArmin Le Grand const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV); 42107540651SArmin Le Grand 42207540651SArmin Le Grand if(aCoor.getX() < -1.0 || aCoor.getX() > 1.0 || aCoor.getY() < -1.0 || aCoor.getY() > 1.0) 42307540651SArmin Le Grand { 42407540651SArmin Le Grand return 0.0; 42507540651SArmin Le Grand } 42607540651SArmin Le Grand 42707540651SArmin Le Grand const double t(1.0 - sqrt(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY())); 42896fc4b33SArmin Le Grand const sal_uInt32 nSteps(rGradInfo.getSteps()); 42996fc4b33SArmin Le Grand 43007540651SArmin Le Grand if(nSteps && t < 1.0) 43196fc4b33SArmin Le Grand { 43207540651SArmin Le Grand return floor(t * nSteps) / double(nSteps - 1); 43396fc4b33SArmin Le Grand } 43496fc4b33SArmin Le Grand 43596fc4b33SArmin Le Grand return t; 43696fc4b33SArmin Le Grand } 43796fc4b33SArmin Le Grand getEllipticalGradientAlpha(const B2DPoint & rUV,const ODFGradientInfo & rGradInfo)43896fc4b33SArmin Le Grand double getEllipticalGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 43996fc4b33SArmin Le Grand { 44096fc4b33SArmin Le Grand return getRadialGradientAlpha(rUV, rGradInfo); // only matrix setup differs 44196fc4b33SArmin Le Grand } 44296fc4b33SArmin Le Grand getSquareGradientAlpha(const B2DPoint & rUV,const ODFGradientInfo & rGradInfo)44396fc4b33SArmin Le Grand double getSquareGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 44496fc4b33SArmin Le Grand { 44596fc4b33SArmin Le Grand const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV); 44696fc4b33SArmin Le Grand const double fAbsX(fabs(aCoor.getX())); 44707540651SArmin Le Grand 44807540651SArmin Le Grand if(fAbsX >= 1.0) 44907540651SArmin Le Grand { 45007540651SArmin Le Grand return 0.0; 45107540651SArmin Le Grand } 45207540651SArmin Le Grand 45396fc4b33SArmin Le Grand const double fAbsY(fabs(aCoor.getY())); 45496fc4b33SArmin Le Grand 45507540651SArmin Le Grand if(fAbsY >= 1.0) 45696fc4b33SArmin Le Grand { 45796fc4b33SArmin Le Grand return 0.0; 45896fc4b33SArmin Le Grand } 45996fc4b33SArmin Le Grand 46096fc4b33SArmin Le Grand const double t(1.0 - std::max(fAbsX, fAbsY)); 46196fc4b33SArmin Le Grand const sal_uInt32 nSteps(rGradInfo.getSteps()); 46296fc4b33SArmin Le Grand 46307540651SArmin Le Grand if(nSteps && t < 1.0) 46496fc4b33SArmin Le Grand { 46507540651SArmin Le Grand return floor(t * nSteps) / double(nSteps - 1); 46696fc4b33SArmin Le Grand } 46796fc4b33SArmin Le Grand 46896fc4b33SArmin Le Grand return t; 46996fc4b33SArmin Le Grand } 47096fc4b33SArmin Le Grand getRectangularGradientAlpha(const B2DPoint & rUV,const ODFGradientInfo & rGradInfo)47196fc4b33SArmin Le Grand double getRectangularGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 47296fc4b33SArmin Le Grand { 47396fc4b33SArmin Le Grand return getSquareGradientAlpha(rUV, rGradInfo); // only matrix setup differs 47496fc4b33SArmin Le Grand } 47596fc4b33SArmin Le Grand } // namespace tools 476cdf0e10cSrcweir } // namespace basegfx 47796fc4b33SArmin Le Grand 47896fc4b33SArmin Le Grand // eof 479