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 1009dbbe93SAndrew Rist * 1109dbbe93SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 1209dbbe93SAndrew Rist * 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. 1909dbbe93SAndrew Rist * 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( 5696fc4b33SArmin Le Grand const B2DRange& rTargetRange, 5796fc4b33SArmin Le Grand sal_uInt32 nSteps, 5896fc4b33SArmin Le Grand double fBorder, 5996fc4b33SArmin Le Grand double fAngle, 6096fc4b33SArmin Le Grand 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 8996fc4b33SArmin Le Grand 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( 12696fc4b33SArmin Le Grand const B2DRange& rTargetRange, 12796fc4b33SArmin Le Grand const B2DVector& rOffset, 12896fc4b33SArmin Le Grand sal_uInt32 nSteps, 12996fc4b33SArmin Le Grand double fBorder, 13096fc4b33SArmin Le Grand double fAngle, 13196fc4b33SArmin Le Grand bool bCircular) 132cdf0e10cSrcweir { 13396fc4b33SArmin Le Grand B2DHomMatrix aTextureTransform; 13496fc4b33SArmin Le Grand 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 14396fc4b33SArmin Le Grand 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( 19596fc4b33SArmin Le Grand const B2DRange& rTargetRange, 19696fc4b33SArmin Le Grand const B2DVector& rOffset, 19796fc4b33SArmin Le Grand sal_uInt32 nSteps, 19896fc4b33SArmin Le Grand double fBorder, 19996fc4b33SArmin Le Grand double fAngle, 20096fc4b33SArmin 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 211d939e20fSArmin Le Grand // 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 221cdf0e10cSrcweir // 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); 23896fc4b33SArmin Le Grand 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( 27196fc4b33SArmin Le Grand const B2DRange& rTargetArea, 27296fc4b33SArmin Le Grand sal_uInt32 nSteps, 27396fc4b33SArmin Le Grand double fBorder, 27496fc4b33SArmin Le Grand double fAngle) 275cdf0e10cSrcweir { 27696fc4b33SArmin Le Grand return init1DGradientInfo( 27796fc4b33SArmin Le Grand rTargetArea, 27896fc4b33SArmin Le Grand nSteps, 27996fc4b33SArmin Le Grand fBorder, 28096fc4b33SArmin Le Grand fAngle, 28196fc4b33SArmin Le Grand false); 282cdf0e10cSrcweir } 283cdf0e10cSrcweir 28496fc4b33SArmin Le Grand ODFGradientInfo createAxialODFGradientInfo( 28596fc4b33SArmin Le Grand const B2DRange& rTargetArea, 28696fc4b33SArmin Le Grand sal_uInt32 nSteps, 28796fc4b33SArmin Le Grand double fBorder, 28896fc4b33SArmin Le Grand double fAngle) 289cdf0e10cSrcweir { 29096fc4b33SArmin Le Grand return init1DGradientInfo( 29196fc4b33SArmin Le Grand rTargetArea, 29296fc4b33SArmin Le Grand nSteps, 29396fc4b33SArmin Le Grand fBorder, 29496fc4b33SArmin Le Grand fAngle, 29596fc4b33SArmin Le Grand true); 296cdf0e10cSrcweir } 297cdf0e10cSrcweir 29896fc4b33SArmin Le Grand ODFGradientInfo createRadialODFGradientInfo( 29996fc4b33SArmin Le Grand const B2DRange& rTargetArea, 30096fc4b33SArmin Le Grand const B2DVector& rOffset, 30196fc4b33SArmin Le Grand sal_uInt32 nSteps, 30296fc4b33SArmin Le Grand double fBorder) 303cdf0e10cSrcweir { 30496fc4b33SArmin Le Grand return initEllipticalGradientInfo( 30596fc4b33SArmin Le Grand rTargetArea, 30696fc4b33SArmin Le Grand rOffset, 30796fc4b33SArmin Le Grand nSteps, 30896fc4b33SArmin Le Grand fBorder, 30996fc4b33SArmin Le Grand 0.0, 31096fc4b33SArmin Le Grand true); 311cdf0e10cSrcweir } 312cdf0e10cSrcweir 31396fc4b33SArmin Le Grand ODFGradientInfo createEllipticalODFGradientInfo( 31496fc4b33SArmin Le Grand const B2DRange& rTargetArea, 31596fc4b33SArmin Le Grand const B2DVector& rOffset, 31696fc4b33SArmin Le Grand sal_uInt32 nSteps, 31796fc4b33SArmin Le Grand double fBorder, 31896fc4b33SArmin Le Grand double fAngle) 319cdf0e10cSrcweir { 32096fc4b33SArmin Le Grand return initEllipticalGradientInfo( 32196fc4b33SArmin Le Grand rTargetArea, 32296fc4b33SArmin Le Grand rOffset, 32396fc4b33SArmin Le Grand nSteps, 32496fc4b33SArmin Le Grand fBorder, 32596fc4b33SArmin Le Grand fAngle, 32696fc4b33SArmin Le Grand false); 327cdf0e10cSrcweir } 328cdf0e10cSrcweir 32996fc4b33SArmin Le Grand ODFGradientInfo createSquareODFGradientInfo( 33096fc4b33SArmin Le Grand const B2DRange& rTargetArea, 33196fc4b33SArmin Le Grand const B2DVector& rOffset, 33296fc4b33SArmin Le Grand sal_uInt32 nSteps, 33396fc4b33SArmin Le Grand double fBorder, 33496fc4b33SArmin Le Grand double fAngle) 335cdf0e10cSrcweir { 33696fc4b33SArmin Le Grand return initRectGradientInfo( 33796fc4b33SArmin Le Grand rTargetArea, 33896fc4b33SArmin Le Grand rOffset, 33996fc4b33SArmin Le Grand nSteps, 34096fc4b33SArmin Le Grand fBorder, 34196fc4b33SArmin Le Grand fAngle, 34296fc4b33SArmin Le Grand true); 343cdf0e10cSrcweir } 344cdf0e10cSrcweir 34596fc4b33SArmin Le Grand ODFGradientInfo createRectangularODFGradientInfo( 34696fc4b33SArmin Le Grand const B2DRange& rTargetArea, 34796fc4b33SArmin Le Grand const B2DVector& rOffset, 34896fc4b33SArmin Le Grand sal_uInt32 nSteps, 34996fc4b33SArmin Le Grand double fBorder, 35096fc4b33SArmin Le Grand double fAngle) 351cdf0e10cSrcweir { 35296fc4b33SArmin Le Grand return initRectGradientInfo( 35396fc4b33SArmin Le Grand rTargetArea, 35496fc4b33SArmin Le Grand rOffset, 35596fc4b33SArmin Le Grand nSteps, 35696fc4b33SArmin Le Grand fBorder, 35796fc4b33SArmin Le Grand fAngle, 35896fc4b33SArmin 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()); 38196fc4b33SArmin Le Grand 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