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 { 3496fc4b33SArmin 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 4196fc4b33SArmin 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 */ 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 */ 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 */ 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 { 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 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 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 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 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 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 36196fc4b33SArmin Le Grand double getLinearGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 36296fc4b33SArmin Le Grand { 36396fc4b33SArmin Le Grand const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV); 364*07540651SArmin Le Grand 365*07540651SArmin Le Grand if(aCoor.getX() < 0.0 || aCoor.getX() > 1.0) 366*07540651SArmin Le Grand { 367*07540651SArmin Le Grand return 0.0; 368*07540651SArmin Le Grand } 369*07540651SArmin Le Grand 370*07540651SArmin Le Grand if(aCoor.getY() <= 0.0) 371*07540651SArmin Le Grand { 372*07540651SArmin Le Grand return 0.0; 373*07540651SArmin Le Grand } 374*07540651SArmin Le Grand 375*07540651SArmin Le Grand if(aCoor.getY() >= 1.0) 376*07540651SArmin Le Grand { 377*07540651SArmin Le Grand return 1.0; 378*07540651SArmin Le Grand } 379*07540651SArmin Le Grand 38096fc4b33SArmin Le Grand const sal_uInt32 nSteps(rGradInfo.getSteps()); 381cdf0e10cSrcweir 38296fc4b33SArmin Le Grand if(nSteps) 38396fc4b33SArmin Le Grand { 384*07540651SArmin Le Grand return floor(aCoor.getY() * nSteps) / double(nSteps - 1); 38596fc4b33SArmin Le Grand } 38696fc4b33SArmin Le Grand 387*07540651SArmin Le Grand return aCoor.getY(); 38896fc4b33SArmin Le Grand } 38996fc4b33SArmin Le Grand 39096fc4b33SArmin Le Grand double getAxialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 39196fc4b33SArmin Le Grand { 39296fc4b33SArmin Le Grand const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV); 393*07540651SArmin Le Grand 394*07540651SArmin Le Grand if(aCoor.getX() < 0.0 || aCoor.getX() > 1.0) 395*07540651SArmin Le Grand { 396*07540651SArmin Le Grand return 0.0; 397*07540651SArmin Le Grand } 398*07540651SArmin Le Grand 399*07540651SArmin Le Grand const double fAbsY(fabs(aCoor.getY())); 400*07540651SArmin Le Grand 401*07540651SArmin Le Grand if(fAbsY >= 1.0) 402*07540651SArmin Le Grand { 403*07540651SArmin Le Grand return 0.0; 404*07540651SArmin Le Grand } 405*07540651SArmin Le Grand 40696fc4b33SArmin Le Grand const sal_uInt32 nSteps(rGradInfo.getSteps()); 40796fc4b33SArmin Le Grand 40896fc4b33SArmin Le Grand if(nSteps) 40996fc4b33SArmin Le Grand { 410*07540651SArmin Le Grand return floor(fAbsY * nSteps) / double(nSteps - 1); 41196fc4b33SArmin Le Grand } 41296fc4b33SArmin Le Grand 413*07540651SArmin Le Grand return fAbsY; 41496fc4b33SArmin Le Grand } 41596fc4b33SArmin Le Grand 41696fc4b33SArmin Le Grand double getRadialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 41796fc4b33SArmin Le Grand { 41896fc4b33SArmin Le Grand const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV); 419*07540651SArmin Le Grand 420*07540651SArmin Le Grand if(aCoor.getX() < -1.0 || aCoor.getX() > 1.0 || aCoor.getY() < -1.0 || aCoor.getY() > 1.0) 421*07540651SArmin Le Grand { 422*07540651SArmin Le Grand return 0.0; 423*07540651SArmin Le Grand } 424*07540651SArmin Le Grand 425*07540651SArmin Le Grand const double t(1.0 - sqrt(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY())); 42696fc4b33SArmin Le Grand const sal_uInt32 nSteps(rGradInfo.getSteps()); 42796fc4b33SArmin Le Grand 428*07540651SArmin Le Grand if(nSteps && t < 1.0) 42996fc4b33SArmin Le Grand { 430*07540651SArmin Le Grand return floor(t * nSteps) / double(nSteps - 1); 43196fc4b33SArmin Le Grand } 43296fc4b33SArmin Le Grand 43396fc4b33SArmin Le Grand return t; 43496fc4b33SArmin Le Grand } 43596fc4b33SArmin Le Grand 43696fc4b33SArmin Le Grand double getEllipticalGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 43796fc4b33SArmin Le Grand { 43896fc4b33SArmin Le Grand return getRadialGradientAlpha(rUV, rGradInfo); // only matrix setup differs 43996fc4b33SArmin Le Grand } 44096fc4b33SArmin Le Grand 44196fc4b33SArmin Le Grand double getSquareGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 44296fc4b33SArmin Le Grand { 44396fc4b33SArmin Le Grand const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV); 44496fc4b33SArmin Le Grand const double fAbsX(fabs(aCoor.getX())); 445*07540651SArmin Le Grand 446*07540651SArmin Le Grand if(fAbsX >= 1.0) 447*07540651SArmin Le Grand { 448*07540651SArmin Le Grand return 0.0; 449*07540651SArmin Le Grand } 450*07540651SArmin Le Grand 45196fc4b33SArmin Le Grand const double fAbsY(fabs(aCoor.getY())); 45296fc4b33SArmin Le Grand 453*07540651SArmin Le Grand if(fAbsY >= 1.0) 45496fc4b33SArmin Le Grand { 45596fc4b33SArmin Le Grand return 0.0; 45696fc4b33SArmin Le Grand } 45796fc4b33SArmin Le Grand 45896fc4b33SArmin Le Grand const double t(1.0 - std::max(fAbsX, fAbsY)); 45996fc4b33SArmin Le Grand const sal_uInt32 nSteps(rGradInfo.getSteps()); 46096fc4b33SArmin Le Grand 461*07540651SArmin Le Grand if(nSteps && t < 1.0) 46296fc4b33SArmin Le Grand { 463*07540651SArmin Le Grand return floor(t * nSteps) / double(nSteps - 1); 46496fc4b33SArmin Le Grand } 46596fc4b33SArmin Le Grand 46696fc4b33SArmin Le Grand return t; 46796fc4b33SArmin Le Grand } 46896fc4b33SArmin Le Grand 46996fc4b33SArmin Le Grand double getRectangularGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo) 47096fc4b33SArmin Le Grand { 47196fc4b33SArmin Le Grand return getSquareGradientAlpha(rUV, rGradInfo); // only matrix setup differs 47296fc4b33SArmin Le Grand } 47396fc4b33SArmin Le Grand } // namespace tools 474cdf0e10cSrcweir } // namespace basegfx 47596fc4b33SArmin Le Grand 47696fc4b33SArmin Le Grand // eof 477