LCOV - code coverage report
Current view: top level - basegfx/source/tools - gradienttools.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 38 121 31.4 %
Date: 2012-08-25 Functions: 3 9 33.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 23 84 27.4 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : #include <basegfx/tools/gradienttools.hxx>
      30                 :            : #include <basegfx/point/b2dpoint.hxx>
      31                 :            : #include <basegfx/range/b2drange.hxx>
      32                 :            : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      33                 :            : 
      34                 :            : namespace basegfx
      35                 :            : {
      36                 :            :     /** Most of the setup for linear & axial gradient is the same, except
      37                 :            :         for the border treatment. Factored out here.
      38                 :            :     */
      39                 :       1585 :     static void init1DGradientInfo(ODFGradientInfo& o_rGradientInfo,
      40                 :            :                                    const B2DRange&  rTargetRange,
      41                 :            :                                    sal_uInt32       nSteps,
      42                 :            :                                    double           fBorder,
      43                 :            :                                    double           fAngle,
      44                 :            :                                    bool             bAxial)
      45                 :            :     {
      46         [ +  - ]:       1585 :         o_rGradientInfo.maTextureTransform.identity();
      47         [ +  - ]:       1585 :         o_rGradientInfo.maBackTextureTransform.identity();
      48                 :       1585 :         o_rGradientInfo.mnSteps = nSteps;
      49                 :            : 
      50                 :       1585 :         fAngle = -fAngle;
      51                 :            : 
      52         [ +  - ]:       1585 :         double fTargetSizeX(rTargetRange.getWidth());
      53         [ +  - ]:       1585 :         double fTargetSizeY(rTargetRange.getHeight());
      54         [ +  - ]:       1585 :         double fTargetOffsetX(rTargetRange.getMinX());
      55         [ +  - ]:       1585 :         double fTargetOffsetY(rTargetRange.getMinY());
      56                 :            : 
      57                 :            :         // add object expansion
      58         [ +  + ]:       1585 :         if(0.0 != fAngle)
      59                 :            :         {
      60                 :        341 :             const double fAbsCos(fabs(cos(fAngle)));
      61                 :        341 :             const double fAbsSin(fabs(sin(fAngle)));
      62                 :        341 :             const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
      63                 :        341 :             const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
      64                 :        341 :             fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
      65                 :        341 :             fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
      66                 :        341 :             fTargetSizeX = fNewX;
      67                 :        341 :             fTargetSizeY = fNewY;
      68                 :            :         }
      69                 :            : 
      70                 :       1585 :         const double fSizeWithoutBorder=1.0 - fBorder;
      71         [ +  + ]:       1585 :         if( bAxial )
      72                 :            :         {
      73         [ +  - ]:        337 :             o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder * .5);
      74         [ +  - ]:        337 :             o_rGradientInfo.maTextureTransform.translate(0.0, 0.5);
      75                 :            :         }
      76                 :            :         else
      77                 :            :         {
      78         [ -  + ]:       1248 :             if(!fTools::equal(fSizeWithoutBorder, 1.0))
      79                 :            :             {
      80         [ #  # ]:          0 :                 o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder);
      81         [ #  # ]:          0 :                 o_rGradientInfo.maTextureTransform.translate(0.0, fBorder);
      82                 :            :             }
      83                 :            :         }
      84                 :            : 
      85         [ +  - ]:       1585 :         o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
      86                 :            : 
      87                 :            :         // add texture rotate after scale to keep perpendicular angles
      88         [ +  + ]:       1585 :         if(0.0 != fAngle)
      89                 :            :         {
      90                 :            :             const B2DPoint aCenter(0.5*fTargetSizeX,
      91                 :        341 :                                    0.5*fTargetSizeY);
      92                 :            :             o_rGradientInfo.maTextureTransform *=
      93 [ +  - ][ +  - ]:        341 :                 basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
                 [ +  - ]
      94                 :            :         }
      95                 :            : 
      96                 :            :         // add object translate
      97         [ +  - ]:       1585 :         o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
      98                 :            : 
      99                 :            :         // prepare aspect for texture
     100         [ +  - ]:       1585 :         o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;
     101                 :            : 
     102                 :            :         // build transform from u,v to [0.0 .. 1.0].
     103         [ +  - ]:       1585 :         o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
     104         [ +  - ]:       1585 :         o_rGradientInfo.maBackTextureTransform.invert();
     105                 :       1585 :     }
     106                 :            : 
     107                 :            :     /** Most of the setup for radial & ellipsoidal gradient is the same,
     108                 :            :         except for the border treatment. Factored out here.
     109                 :            :     */
     110                 :          0 :     static void initEllipticalGradientInfo(ODFGradientInfo& o_rGradientInfo,
     111                 :            :                                            const B2DRange&  rTargetRange,
     112                 :            :                                            const B2DVector& rOffset,
     113                 :            :                                            sal_uInt32       nSteps,
     114                 :            :                                            double           fBorder,
     115                 :            :                                            double           fAngle,
     116                 :            :                                            bool             bCircular)
     117                 :            :     {
     118                 :          0 :         o_rGradientInfo.maTextureTransform.identity();
     119                 :          0 :         o_rGradientInfo.maBackTextureTransform.identity();
     120                 :          0 :         o_rGradientInfo.mnSteps = nSteps;
     121                 :            : 
     122                 :          0 :         fAngle = -fAngle;
     123                 :            : 
     124                 :          0 :         double fTargetSizeX(rTargetRange.getWidth());
     125                 :          0 :         double fTargetSizeY(rTargetRange.getHeight());
     126                 :          0 :         double fTargetOffsetX(rTargetRange.getMinX());
     127                 :          0 :         double fTargetOffsetY(rTargetRange.getMinY());
     128                 :            : 
     129                 :            :         // add object expansion
     130         [ #  # ]:          0 :         if( bCircular )
     131                 :            :         {
     132                 :          0 :             const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY)));
     133                 :          0 :             fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0;
     134                 :          0 :             fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0;
     135                 :          0 :             fTargetSizeX = fOriginalDiag;
     136                 :          0 :             fTargetSizeY = fOriginalDiag;
     137                 :            :         }
     138                 :            :         else
     139                 :            :         {
     140                 :          0 :             fTargetOffsetX -= (0.4142 / 2.0 ) * fTargetSizeX;
     141                 :          0 :             fTargetOffsetY -= (0.4142 / 2.0 ) * fTargetSizeY;
     142                 :          0 :             fTargetSizeX = 1.4142 * fTargetSizeX;
     143                 :          0 :             fTargetSizeY = 1.4142 * fTargetSizeY;
     144                 :            :         }
     145                 :            : 
     146                 :          0 :         const double fHalfBorder((1.0 - fBorder) * 0.5);
     147                 :          0 :         o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder);
     148                 :            : 
     149                 :          0 :         o_rGradientInfo.maTextureTransform.translate(0.5, 0.5);
     150                 :          0 :         o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
     151                 :            : 
     152                 :            :         // add texture rotate after scale to keep perpendicular angles
     153 [ #  # ][ #  # ]:          0 :         if( !bCircular && 0.0 != fAngle)
     154                 :            :         {
     155                 :            :             const B2DPoint aCenter(0.5*fTargetSizeX,
     156                 :          0 :                                    0.5*fTargetSizeY);
     157                 :            :             o_rGradientInfo.maTextureTransform *=
     158 [ #  # ][ #  # ]:          0 :                 basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
                 [ #  # ]
     159                 :            :         }
     160                 :            : 
     161                 :            :         // add defined offsets after rotation
     162 [ #  # ][ #  # ]:          0 :         if(0.5 != rOffset.getX() || 0.5 != rOffset.getY())
                 [ #  # ]
     163                 :            :         {
     164                 :            :             // use original target size
     165                 :          0 :             fTargetOffsetX += (rOffset.getX() - 0.5) * rTargetRange.getWidth();
     166                 :          0 :             fTargetOffsetY += (rOffset.getY() - 0.5) * rTargetRange.getHeight();
     167                 :            :         }
     168                 :            : 
     169                 :            :         // add object translate
     170                 :          0 :         o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
     171                 :            : 
     172                 :            :         // prepare aspect for texture
     173         [ #  # ]:          0 :         o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;
     174                 :            : 
     175                 :            :         // build transform from u,v to [0.0 .. 1.0].
     176                 :          0 :         o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
     177                 :          0 :         o_rGradientInfo.maBackTextureTransform.invert();
     178                 :          0 :     }
     179                 :            : 
     180                 :            :     /** Setup for rect & square gradient is exactly the same. Factored out
     181                 :            :         here.
     182                 :            :     */
     183                 :          0 :     static void initRectGradientInfo(ODFGradientInfo& o_rGradientInfo,
     184                 :            :                                      const B2DRange&  rTargetRange,
     185                 :            :                                      const B2DVector& rOffset,
     186                 :            :                                      sal_uInt32       nSteps,
     187                 :            :                                      double           fBorder,
     188                 :            :                                      double           fAngle,
     189                 :            :                                      bool             bSquare)
     190                 :            :     {
     191                 :          0 :         o_rGradientInfo.maTextureTransform.identity();
     192                 :          0 :         o_rGradientInfo.maBackTextureTransform.identity();
     193                 :          0 :         o_rGradientInfo.mnSteps = nSteps;
     194                 :            : 
     195                 :          0 :         fAngle = -fAngle;
     196                 :            : 
     197                 :          0 :         double fTargetSizeX(rTargetRange.getWidth());
     198                 :          0 :         double fTargetSizeY(rTargetRange.getHeight());
     199                 :          0 :         double fTargetOffsetX(rTargetRange.getMinX());
     200                 :          0 :         double fTargetOffsetY(rTargetRange.getMinY());
     201                 :            : 
     202                 :            :         // add object expansion
     203         [ #  # ]:          0 :         if(0.0 != fAngle)
     204                 :            :         {
     205                 :          0 :             const double fAbsCos(fabs(cos(fAngle)));
     206                 :          0 :             const double fAbsSin(fabs(sin(fAngle)));
     207                 :          0 :             const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
     208                 :          0 :             const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
     209                 :          0 :             fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
     210                 :          0 :             fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
     211                 :          0 :             fTargetSizeX = fNewX;
     212                 :          0 :             fTargetSizeY = fNewY;
     213                 :            :         }
     214                 :            : 
     215                 :          0 :         const double fHalfBorder((1.0 - fBorder) * 0.5);
     216                 :          0 :         o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder);
     217                 :            : 
     218                 :          0 :         o_rGradientInfo.maTextureTransform.translate(0.5, 0.5);
     219                 :          0 :         o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
     220                 :            : 
     221                 :            :         // add texture rotate after scale to keep perpendicular angles
     222         [ #  # ]:          0 :         if(0.0 != fAngle)
     223                 :            :         {
     224                 :            :             const B2DPoint aCenter(0.5*fTargetSizeX,
     225                 :          0 :                                    0.5*fTargetSizeY);
     226                 :            :             o_rGradientInfo.maTextureTransform *=
     227 [ #  # ][ #  # ]:          0 :                 basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
                 [ #  # ]
     228                 :            :         }
     229                 :            : 
     230                 :            :         // add defined offsets after rotation
     231 [ #  # ][ #  # ]:          0 :         if(0.5 != rOffset.getX() || 0.5 != rOffset.getY())
                 [ #  # ]
     232                 :            :         {
     233                 :            :             // use scaled target size
     234                 :          0 :             fTargetOffsetX += (rOffset.getX() - 0.5) * fTargetSizeX;
     235                 :          0 :             fTargetOffsetY += (rOffset.getY() - 0.5) * fTargetSizeY;
     236                 :            :         }
     237                 :            : 
     238                 :            :         // add object translate
     239                 :          0 :         o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
     240                 :            : 
     241                 :            :         // prepare aspect for texture
     242         [ #  # ]:          0 :         if( bSquare )
     243                 :          0 :             o_rGradientInfo.mfAspectRatio = 1.0; // since we want a square
     244                 :            :         else
     245         [ #  # ]:          0 :             o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;
     246                 :            : 
     247                 :            :         // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
     248                 :          0 :         o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
     249                 :          0 :         o_rGradientInfo.maBackTextureTransform.invert();
     250                 :          0 :     }
     251                 :            : 
     252                 :            :     namespace tools
     253                 :            :     {
     254                 :       1248 :         ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
     255                 :            :                                                      const B2DRange&  rTargetArea,
     256                 :            :                                                      sal_uInt32       nSteps,
     257                 :            :                                                      double           fBorder,
     258                 :            :                                                      double           fAngle)
     259                 :            :         {
     260                 :            :             init1DGradientInfo(o_rGradientInfo,
     261                 :            :                                rTargetArea,
     262                 :            :                                nSteps,
     263                 :            :                                fBorder,
     264                 :            :                                fAngle,
     265                 :       1248 :                                false);
     266                 :       1248 :             return o_rGradientInfo;
     267                 :            :         }
     268                 :            : 
     269                 :        337 :         ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
     270                 :            :                                                     const B2DRange&  rTargetArea,
     271                 :            :                                                     sal_uInt32       nSteps,
     272                 :            :                                                     double           fBorder,
     273                 :            :                                                     double           fAngle)
     274                 :            :         {
     275                 :            :             init1DGradientInfo(o_rGradientInfo,
     276                 :            :                                rTargetArea,
     277                 :            :                                nSteps,
     278                 :            :                                fBorder,
     279                 :            :                                fAngle,
     280                 :        337 :                                true);
     281                 :        337 :             return o_rGradientInfo;
     282                 :            :         }
     283                 :            : 
     284                 :          0 :         ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
     285                 :            :                                                      const B2DRange&  rTargetArea,
     286                 :            :                                                      const B2DVector& rOffset,
     287                 :            :                                                      sal_uInt32       nSteps,
     288                 :            :                                                      double           fBorder)
     289                 :            :         {
     290                 :            :             initEllipticalGradientInfo(o_rGradientInfo,
     291                 :            :                                        rTargetArea,
     292                 :            :                                        rOffset,
     293                 :            :                                        nSteps,
     294                 :            :                                        fBorder,
     295                 :            :                                        0.0,
     296                 :          0 :                                        true);
     297                 :          0 :             return o_rGradientInfo;
     298                 :            :         }
     299                 :            : 
     300                 :          0 :         ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
     301                 :            :                                                          const B2DRange&  rTargetArea,
     302                 :            :                                                          const B2DVector& rOffset,
     303                 :            :                                                          sal_uInt32       nSteps,
     304                 :            :                                                          double           fBorder,
     305                 :            :                                                          double           fAngle)
     306                 :            :         {
     307                 :            :             initEllipticalGradientInfo(o_rGradientInfo,
     308                 :            :                                        rTargetArea,
     309                 :            :                                        rOffset,
     310                 :            :                                        nSteps,
     311                 :            :                                        fBorder,
     312                 :            :                                        fAngle,
     313                 :          0 :                                        false);
     314                 :          0 :             return o_rGradientInfo;
     315                 :            :         }
     316                 :            : 
     317                 :          0 :         ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
     318                 :            :                                                      const B2DRange&  rTargetArea,
     319                 :            :                                                      const B2DVector& rOffset,
     320                 :            :                                                      sal_uInt32       nSteps,
     321                 :            :                                                      double           fBorder,
     322                 :            :                                                      double           fAngle)
     323                 :            :         {
     324                 :            :             initRectGradientInfo(o_rGradientInfo,
     325                 :            :                                  rTargetArea,
     326                 :            :                                  rOffset,
     327                 :            :                                  nSteps,
     328                 :            :                                  fBorder,
     329                 :            :                                  fAngle,
     330                 :          0 :                                  true);
     331                 :          0 :             return o_rGradientInfo;
     332                 :            :         }
     333                 :            : 
     334                 :          0 :         ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
     335                 :            :                                                           const B2DRange&  rTargetArea,
     336                 :            :                                                           const B2DVector& rOffset,
     337                 :            :                                                           sal_uInt32       nSteps,
     338                 :            :                                                           double           fBorder,
     339                 :            :                                                           double           fAngle)
     340                 :            :         {
     341                 :            :             initRectGradientInfo(o_rGradientInfo,
     342                 :            :                                  rTargetArea,
     343                 :            :                                  rOffset,
     344                 :            :                                  nSteps,
     345                 :            :                                  fBorder,
     346                 :            :                                  fAngle,
     347                 :          0 :                                  false);
     348                 :          0 :             return o_rGradientInfo;
     349                 :            :         }
     350                 :            : 
     351                 :            :     } // namespace tools
     352                 :            : 
     353                 :            : } // namespace basegfx
     354                 :            : 
     355                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10