LCOV - code coverage report
Current view: top level - drawinglayer/source/primitive2d - fillgradientprimitive2d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 59 113 52.2 %
Date: 2012-08-25 Functions: 7 9 77.8 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 74 313 23.6 %

           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 <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
      30                 :            : #include <basegfx/polygon/b2dpolygon.hxx>
      31                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      32                 :            : #include <drawinglayer/texture/texture.hxx>
      33                 :            : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
      34                 :            : #include <basegfx/tools/canvastools.hxx>
      35                 :            : #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
      36                 :            : 
      37                 :            : //////////////////////////////////////////////////////////////////////////////
      38                 :            : 
      39                 :            : using namespace com::sun::star;
      40                 :            : 
      41                 :            : //////////////////////////////////////////////////////////////////////////////
      42                 :            : 
      43                 :            : namespace drawinglayer
      44                 :            : {
      45                 :            :     namespace primitive2d
      46                 :            :     {
      47                 :       1332 :         void FillGradientPrimitive2D::generateMatricesAndColors(
      48                 :            :             std::vector< basegfx::B2DHomMatrix >& rMatrices,
      49                 :            :             std::vector< basegfx::BColor >& rColors) const
      50                 :            :         {
      51                 :       1332 :             rMatrices.clear();
      52                 :       1332 :             rColors.clear();
      53                 :            : 
      54                 :            :             // make sure steps is not too high/low
      55         [ +  - ]:       1332 :             const basegfx::BColor aStart(getFillGradient().getStartColor());
      56         [ +  - ]:       1332 :             const basegfx::BColor aEnd(getFillGradient().getEndColor());
      57                 :       1332 :             const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5));
      58         [ +  - ]:       1332 :             sal_uInt32 nSteps(getFillGradient().getSteps());
      59                 :            : 
      60         [ +  + ]:       1332 :             if(nSteps == 0)
      61                 :            :             {
      62                 :       1329 :                 nSteps = nMaxSteps;
      63                 :            :             }
      64                 :            : 
      65         [ -  + ]:       1332 :             if(nSteps < 2)
      66                 :            :             {
      67                 :          0 :                 nSteps = 2;
      68                 :            :             }
      69                 :            : 
      70         [ -  + ]:       1332 :             if(nSteps > nMaxSteps)
      71                 :            :             {
      72                 :          0 :                 nSteps = nMaxSteps;
      73                 :            :             }
      74                 :            : 
      75         [ +  - ]:       1332 :             nSteps = std::max(sal_uInt32(1), nSteps);
      76                 :            : 
      77 [ +  - ][ +  +  :       1332 :             switch(getFillGradient().getStyle())
             -  -  -  -  
                      - ]
      78                 :            :             {
      79                 :            :                 case attribute::GRADIENTSTYLE_LINEAR:
      80                 :            :                 {
      81 [ +  - ][ +  - ]:       1008 :                     texture::GeoTexSvxGradientLinear aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
                 [ +  - ]
      82         [ +  - ]:       1008 :                     aGradient.appendTransformations(rMatrices);
      83         [ +  - ]:       1008 :                     aGradient.appendColors(rColors);
      84         [ +  - ]:       1008 :                     break;
      85                 :            :                 }
      86                 :            :                 case attribute::GRADIENTSTYLE_AXIAL:
      87                 :            :                 {
      88 [ +  - ][ +  - ]:        324 :                     texture::GeoTexSvxGradientAxial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
                 [ +  - ]
      89         [ +  - ]:        324 :                     aGradient.appendTransformations(rMatrices);
      90         [ +  - ]:        324 :                     aGradient.appendColors(rColors);
      91         [ +  - ]:        324 :                     break;
      92                 :            :                 }
      93                 :            :                 case attribute::GRADIENTSTYLE_RADIAL:
      94                 :            :                 {
      95 [ #  # ][ #  # ]:          0 :                     texture::GeoTexSvxGradientRadial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY());
         [ #  # ][ #  # ]
      96         [ #  # ]:          0 :                     aGradient.appendTransformations(rMatrices);
      97         [ #  # ]:          0 :                     aGradient.appendColors(rColors);
      98         [ #  # ]:          0 :                     break;
      99                 :            :                 }
     100                 :            :                 case attribute::GRADIENTSTYLE_ELLIPTICAL:
     101                 :            :                 {
     102 [ #  # ][ #  # ]:          0 :                     texture::GeoTexSvxGradientElliptical aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
         [ #  # ][ #  # ]
                 [ #  # ]
     103         [ #  # ]:          0 :                     aGradient.appendTransformations(rMatrices);
     104         [ #  # ]:          0 :                     aGradient.appendColors(rColors);
     105         [ #  # ]:          0 :                     break;
     106                 :            :                 }
     107                 :            :                 case attribute::GRADIENTSTYLE_SQUARE:
     108                 :            :                 {
     109 [ #  # ][ #  # ]:          0 :                     texture::GeoTexSvxGradientSquare aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
         [ #  # ][ #  # ]
                 [ #  # ]
     110         [ #  # ]:          0 :                     aGradient.appendTransformations(rMatrices);
     111         [ #  # ]:          0 :                     aGradient.appendColors(rColors);
     112         [ #  # ]:          0 :                     break;
     113                 :            :                 }
     114                 :            :                 case attribute::GRADIENTSTYLE_RECT:
     115                 :            :                 {
     116 [ #  # ][ #  # ]:          0 :                     texture::GeoTexSvxGradientRect aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
         [ #  # ][ #  # ]
                 [ #  # ]
     117         [ #  # ]:          0 :                     aGradient.appendTransformations(rMatrices);
     118         [ #  # ]:          0 :                     aGradient.appendColors(rColors);
     119         [ #  # ]:          0 :                     break;
     120                 :            :                 }
     121                 :       1332 :             }
     122                 :       1332 :         }
     123                 :            : 
     124                 :       1332 :         Primitive2DSequence FillGradientPrimitive2D::createOverlappingFill(
     125                 :            :             const std::vector< basegfx::B2DHomMatrix >& rMatrices,
     126                 :            :             const std::vector< basegfx::BColor >& rColors,
     127                 :            :             const basegfx::B2DPolygon& rUnitPolygon) const
     128                 :            :         {
     129                 :            :             // prepare return value
     130         [ +  - ]:       1332 :             Primitive2DSequence aRetval(rColors.size() ? rMatrices.size() + 1 : rMatrices.size());
     131                 :            : 
     132                 :            :             // create solid fill with start color
     133         [ +  - ]:       1332 :             if(!rColors.empty())
     134                 :            :             {
     135                 :            :                 // create primitive
     136                 :            :                 const Primitive2DReference xRef(
     137                 :            :                     new PolyPolygonColorPrimitive2D(
     138                 :       1332 :                         basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())),
     139 [ +  - ][ +  - ]:       1332 :                         rColors[0]));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     140 [ +  - ][ +  - ]:       1332 :                 aRetval[0] = xRef;
     141                 :            :             }
     142                 :            : 
     143                 :            :             // create solid fill steps
     144         [ +  + ]:     170105 :             for(sal_uInt32 a(0); a < rMatrices.size(); a++)
     145                 :            :             {
     146                 :            :                 // create part polygon
     147         [ +  - ]:     168773 :                 basegfx::B2DPolygon aNewPoly(rUnitPolygon);
     148 [ +  - ][ +  - ]:     168773 :                 aNewPoly.transform(rMatrices[a]);
     149                 :            : 
     150                 :            :                 // create solid fill
     151                 :            :                 const Primitive2DReference xRef(
     152                 :            :                     new PolyPolygonColorPrimitive2D(
     153                 :            :                         basegfx::B2DPolyPolygon(aNewPoly),
     154 [ +  - ][ +  - ]:     168773 :                         rColors[a + 1]));
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     155 [ +  - ][ +  - ]:     168773 :                 aRetval[a + 1] = xRef;
     156         [ +  - ]:     168773 :             }
     157                 :            : 
     158                 :       1332 :             return aRetval;
     159                 :            :         }
     160                 :            : 
     161                 :          0 :         Primitive2DSequence FillGradientPrimitive2D::createNonOverlappingFill(
     162                 :            :             const std::vector< basegfx::B2DHomMatrix >& rMatrices,
     163                 :            :             const std::vector< basegfx::BColor >& rColors,
     164                 :            :             const basegfx::B2DPolygon& rUnitPolygon) const
     165                 :            :         {
     166                 :            :             // prepare return value
     167                 :          0 :             Primitive2DSequence aRetval;
     168                 :          0 :             const sal_uInt32 nMatricesSize(rMatrices.size());
     169                 :            : 
     170         [ #  # ]:          0 :             if(nMatricesSize)
     171                 :            :             {
     172         [ #  # ]:          0 :                 basegfx::B2DPolygon aOuterPoly(rUnitPolygon);
     173 [ #  # ][ #  # ]:          0 :                 aOuterPoly.transform(rMatrices[0]);
     174         [ #  # ]:          0 :                 basegfx::B2DPolyPolygon aCombinedPolyPoly(aOuterPoly);
     175         [ #  # ]:          0 :                 const sal_uInt32 nEntryCount(rColors.size() ? rMatrices.size() + 1 : rMatrices.size());
     176                 :          0 :                 sal_uInt32 nIndex(0);
     177                 :            : 
     178         [ #  # ]:          0 :                 aRetval.realloc(nEntryCount);
     179                 :            : 
     180         [ #  # ]:          0 :                 if(!rColors.empty())
     181                 :            :                 {
     182         [ #  # ]:          0 :                     basegfx::B2DRange aOuterPolyRange(aOuterPoly.getB2DRange());
     183         [ #  # ]:          0 :                     aOuterPolyRange.expand(getObjectRange());
     184 [ #  # ][ #  # ]:          0 :                     aCombinedPolyPoly.append(basegfx::tools::createPolygonFromRect(aOuterPolyRange));
                 [ #  # ]
     185 [ #  # ][ #  # ]:          0 :                     aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[0]));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     186 [ #  # ][ #  # ]:          0 :                     aCombinedPolyPoly = basegfx::B2DPolyPolygon(aOuterPoly);
                 [ #  # ]
     187                 :            :                 }
     188                 :            : 
     189         [ #  # ]:          0 :                 for(sal_uInt32 a(1); a < nMatricesSize - 1; a++)
     190                 :            :                 {
     191         [ #  # ]:          0 :                     basegfx::B2DPolygon aInnerPoly(rUnitPolygon);
     192 [ #  # ][ #  # ]:          0 :                     aInnerPoly.transform(rMatrices[a]);
     193         [ #  # ]:          0 :                     aCombinedPolyPoly.append(aInnerPoly);
     194 [ #  # ][ #  # ]:          0 :                     aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[a]));
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
     195 [ #  # ][ #  # ]:          0 :                     aCombinedPolyPoly = basegfx::B2DPolyPolygon(aInnerPoly);
                 [ #  # ]
     196         [ #  # ]:          0 :                 }
     197                 :            : 
     198         [ #  # ]:          0 :                 if(!rColors.empty())
     199                 :            :                 {
     200         [ #  # ]:          0 :                     aRetval[nIndex] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
     201 [ #  # ][ #  # ]:          0 :                         aCombinedPolyPoly, rColors[rColors.size() - 1]));
         [ #  # ][ #  # ]
                 [ #  # ]
     202 [ #  # ][ #  # ]:          0 :                 }
     203                 :            :             }
     204                 :            : 
     205                 :          0 :             return aRetval;
     206                 :            :         }
     207                 :            : 
     208                 :       1332 :         Primitive2DSequence FillGradientPrimitive2D::createFill(bool bOverlapping) const
     209                 :            :         {
     210                 :            :             // prepare shape of the Unit Polygon
     211         [ +  - ]:       1332 :             basegfx::B2DPolygon aUnitPolygon;
     212                 :            : 
     213 [ +  - ][ +  - ]:       2664 :             if(attribute::GRADIENTSTYLE_RADIAL == getFillGradient().getStyle()
         [ -  + ][ -  + ]
     214         [ +  - ]:       1332 :                 || attribute::GRADIENTSTYLE_ELLIPTICAL == getFillGradient().getStyle())
     215                 :            :             {
     216                 :            :                 aUnitPolygon = basegfx::tools::createPolygonFromCircle(
     217 [ #  # ][ #  # ]:          0 :                     basegfx::B2DPoint(0,0), 1);
                 [ #  # ]
     218                 :            :             }
     219 [ +  - ][ +  + ]:       1332 :             else if(attribute::GRADIENTSTYLE_LINEAR == maFillGradient.getStyle())
     220                 :            :             {
     221 [ +  - ][ +  - ]:       1008 :                 aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0, 0, 1, 1));
         [ +  - ][ +  - ]
     222                 :            :             }
     223                 :            :             else
     224                 :            :             {
     225 [ +  - ][ +  - ]:        324 :                 aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1, -1, 1, 1));
         [ +  - ][ +  - ]
     226                 :            :             }
     227                 :            : 
     228                 :            :             // get the transform matrices and colors (where colors
     229                 :            :             // will have one more entry that matrices)
     230         [ +  - ]:       1332 :             std::vector< basegfx::B2DHomMatrix > aMatrices;
     231         [ +  - ]:       1332 :             std::vector< basegfx::BColor > aColors;
     232         [ +  - ]:       1332 :             generateMatricesAndColors(aMatrices, aColors);
     233                 :            : 
     234         [ +  - ]:       1332 :             if(bOverlapping)
     235                 :            :             {
     236         [ +  - ]:       1332 :                 return createOverlappingFill(aMatrices, aColors, aUnitPolygon);
     237                 :            :             }
     238                 :            :             else
     239                 :            :             {
     240         [ #  # ]:          0 :                 return createNonOverlappingFill(aMatrices, aColors, aUnitPolygon);
     241         [ +  - ]:       1332 :             }
     242                 :            :         }
     243                 :            : 
     244                 :       1332 :         Primitive2DSequence FillGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
     245                 :            :         {
     246                 :            :             // default creates overlapping fill which works with AntiAliasing and without.
     247                 :            :             // The non-overlapping version does not create single filled polygons, but
     248                 :            :             // PolyPolygons where each one describes a 'ring' for the gradient such
     249                 :            :             // that the rings will not overlap. This is useful fir the old XOR-paint
     250                 :            :             // 'trick' of VCL which is recorded in Metafiles; so this version may be
     251                 :            :             // used from the MetafilePrimitive2D in it's decomposition.
     252                 :            : 
     253         [ +  - ]:       1332 :             if(!getFillGradient().isDefault())
     254                 :            :             {
     255                 :       1332 :                 return createFill(true);
     256                 :            :             }
     257                 :            :             else
     258                 :            :             {
     259                 :       1332 :                 return Primitive2DSequence();
     260                 :            :             }
     261                 :            :         }
     262                 :            : 
     263                 :       2654 :         FillGradientPrimitive2D::FillGradientPrimitive2D(
     264                 :            :             const basegfx::B2DRange& rObjectRange,
     265                 :            :             const attribute::FillGradientAttribute& rFillGradient)
     266                 :            :         :   BufferedDecompositionPrimitive2D(),
     267                 :            :             maObjectRange(rObjectRange),
     268         [ +  - ]:       2654 :             maFillGradient(rFillGradient)
     269                 :            :         {
     270                 :       2654 :         }
     271                 :            : 
     272                 :          0 :         bool FillGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
     273                 :            :         {
     274         [ #  # ]:          0 :             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
     275                 :            :             {
     276                 :          0 :                 const FillGradientPrimitive2D& rCompare = (FillGradientPrimitive2D&)rPrimitive;
     277                 :            : 
     278                 :          0 :                 return (getObjectRange() == rCompare.getObjectRange()
     279 [ #  # ][ #  # ]:          0 :                     && getFillGradient() == rCompare.getFillGradient());
     280                 :            :             }
     281                 :            : 
     282                 :          0 :             return false;
     283                 :            :         }
     284                 :            : 
     285                 :         90 :         basegfx::B2DRange FillGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
     286                 :            :         {
     287                 :            :             // return ObjectRange
     288                 :         90 :             return getObjectRange();
     289                 :            :         }
     290                 :            : 
     291                 :            :         // provide unique ID
     292                 :       1641 :         ImplPrimitrive2DIDBlock(FillGradientPrimitive2D, PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D)
     293                 :            : 
     294                 :            :     } // end of namespace primitive2d
     295                 :            : } // end of namespace drawinglayer
     296                 :            : 
     297                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10