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 { 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( 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 */ initEllipticalGradientInfo(const B2DRange & rTargetRange,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle,bool bCircular)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 */ initRectGradientInfo(const B2DRange & rTargetRange,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle,bool bSquare)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 { createLinearODFGradientInfo(const B2DRange & rTargetArea,sal_uInt32 nSteps,double fBorder,double fAngle)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 createAxialODFGradientInfo(const B2DRange & rTargetArea,sal_uInt32 nSteps,double fBorder,double fAngle)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 createRadialODFGradientInfo(const B2DRange & rTargetArea,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder)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 createEllipticalODFGradientInfo(const B2DRange & rTargetArea,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle)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 createSquareODFGradientInfo(const B2DRange & rTargetArea,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle)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 createRectangularODFGradientInfo(const B2DRange & rTargetArea,const B2DVector & rOffset,sal_uInt32 nSteps,double fBorder,double fAngle)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 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()); 38296fc4b33SArmin Le Grand 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