LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/drawinglayer/source/primitive2d - fillgradientprimitive2d.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 52 101 51.5 %
Date: 2013-07-09 Functions: 7 9 77.8 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <drawinglayer/primitive2d/fillgradientprimitive2d.hxx>
      21             : #include <basegfx/polygon/b2dpolygon.hxx>
      22             : #include <basegfx/polygon/b2dpolygontools.hxx>
      23             : #include <drawinglayer/texture/texture.hxx>
      24             : #include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
      25             : #include <basegfx/tools/canvastools.hxx>
      26             : #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
      27             : 
      28             : //////////////////////////////////////////////////////////////////////////////
      29             : 
      30             : using namespace com::sun::star;
      31             : 
      32             : //////////////////////////////////////////////////////////////////////////////
      33             : 
      34             : namespace drawinglayer
      35             : {
      36             :     namespace primitive2d
      37             :     {
      38         686 :         void FillGradientPrimitive2D::generateMatricesAndColors(
      39             :             std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries,
      40             :             basegfx::BColor& rOutmostColor) const
      41             :         {
      42         686 :             rEntries.clear();
      43             : 
      44             :             // make sure steps is not too high/low
      45         686 :             const basegfx::BColor aStart(getFillGradient().getStartColor());
      46        1372 :             const basegfx::BColor aEnd(getFillGradient().getEndColor());
      47         686 :             const sal_uInt32 nMaxSteps(sal_uInt32((aStart.getMaximumDistance(aEnd) * 127.5) + 0.5));
      48         686 :             sal_uInt32 nSteps(getFillGradient().getSteps());
      49             : 
      50         686 :             if(nSteps == 0)
      51             :             {
      52         686 :                 nSteps = nMaxSteps;
      53             :             }
      54             : 
      55         686 :             if(nSteps < 2)
      56             :             {
      57           0 :                 nSteps = 2;
      58             :             }
      59             : 
      60         686 :             if(nSteps > nMaxSteps)
      61             :             {
      62           0 :                 nSteps = nMaxSteps;
      63             :             }
      64             : 
      65         686 :             nSteps = std::max(sal_uInt32(1), nSteps);
      66             : 
      67         686 :             switch(getFillGradient().getStyle())
      68             :             {
      69             :                 case attribute::GRADIENTSTYLE_LINEAR:
      70             :                 {
      71         536 :                     texture::GeoTexSvxGradientLinear aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
      72         536 :                     aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
      73         536 :                     break;
      74             :                 }
      75             :                 case attribute::GRADIENTSTYLE_AXIAL:
      76             :                 {
      77         150 :                     texture::GeoTexSvxGradientAxial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
      78         150 :                     aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
      79         150 :                     break;
      80             :                 }
      81             :                 case attribute::GRADIENTSTYLE_RADIAL:
      82             :                 {
      83           0 :                     texture::GeoTexSvxGradientRadial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY());
      84           0 :                     aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
      85           0 :                     break;
      86             :                 }
      87             :                 case attribute::GRADIENTSTYLE_ELLIPTICAL:
      88             :                 {
      89           0 :                     texture::GeoTexSvxGradientElliptical aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
      90           0 :                     aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
      91           0 :                     break;
      92             :                 }
      93             :                 case attribute::GRADIENTSTYLE_SQUARE:
      94             :                 {
      95           0 :                     texture::GeoTexSvxGradientSquare aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
      96           0 :                     aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
      97           0 :                     break;
      98             :                 }
      99             :                 case attribute::GRADIENTSTYLE_RECT:
     100             :                 {
     101           0 :                     texture::GeoTexSvxGradientRect aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
     102           0 :                     aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
     103           0 :                     break;
     104             :                 }
     105         686 :             }
     106         686 :         }
     107             : 
     108         686 :         Primitive2DSequence FillGradientPrimitive2D::createOverlappingFill(
     109             :             const std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries,
     110             :             const basegfx::BColor& rOutmostColor,
     111             :             const basegfx::B2DPolygon& rUnitPolygon) const
     112             :         {
     113             :             // prepare return value
     114         686 :             Primitive2DSequence aRetval(rEntries.size() + 1);
     115             : 
     116             :             // create solid fill with outmost color
     117        1372 :             aRetval[0] = Primitive2DReference(
     118             :                 new PolyPolygonColorPrimitive2D(
     119         686 :                     basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())),
     120        2058 :                     rOutmostColor));
     121             : 
     122             :             // create solid fill steps
     123       87680 :             for(sal_uInt32 a(0); a < rEntries.size(); a++)
     124             :             {
     125             :                 // create part polygon
     126       86994 :                 basegfx::B2DPolygon aNewPoly(rUnitPolygon);
     127             : 
     128       86994 :                 aNewPoly.transform(rEntries[a].maB2DHomMatrix);
     129             : 
     130             :                 // create solid fill
     131      173988 :                 aRetval[a + 1] = Primitive2DReference(
     132             :                     new PolyPolygonColorPrimitive2D(
     133             :                         basegfx::B2DPolyPolygon(aNewPoly),
     134      260982 :                         rEntries[a].maBColor));
     135       86994 :             }
     136             : 
     137         686 :             return aRetval;
     138             :         }
     139             : 
     140           0 :         Primitive2DSequence FillGradientPrimitive2D::createNonOverlappingFill(
     141             :             const std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries,
     142             :             const basegfx::BColor& rOutmostColor,
     143             :             const basegfx::B2DPolygon& rUnitPolygon) const
     144             :         {
     145             :             // prepare return value
     146           0 :             Primitive2DSequence aRetval(rEntries.size() + 1);
     147             : 
     148             :             // get outmost range from object
     149           0 :             basegfx::B2DRange aOutmostRange(getObjectRange());
     150           0 :             basegfx::B2DPolyPolygon aCombinedPolyPoly;
     151             : 
     152           0 :             if(rEntries.size())
     153             :             {
     154             :                 // extend aOutmostRange with first polygon
     155           0 :                 basegfx::B2DPolygon aFirstPoly(rUnitPolygon);
     156             : 
     157           0 :                 aFirstPoly.transform(rEntries[0].maB2DHomMatrix);
     158           0 :                 aCombinedPolyPoly.append(aFirstPoly);
     159           0 :                 aOutmostRange.expand(aFirstPoly.getB2DRange());
     160             :             }
     161             : 
     162             :             // add outmost range to combined polypolygon (in 1st place), create first primitive
     163           0 :             aCombinedPolyPoly.insert(0, basegfx::tools::createPolygonFromRect(aOutmostRange));
     164           0 :             aRetval[0] = Primitive2DReference(
     165             :                 new PolyPolygonColorPrimitive2D(
     166             :                     aCombinedPolyPoly,
     167           0 :                     rOutmostColor));
     168             : 
     169           0 :             if(rEntries.size())
     170             :             {
     171             :                 // reuse first polygon, it's the second one
     172           0 :                 aCombinedPolyPoly.remove(0);
     173             : 
     174           0 :                 for(sal_uInt32 a(0); a < rEntries.size() - 1; a++)
     175             :                 {
     176             :                     // create next inner polygon, combinbe with last one
     177           0 :                     basegfx::B2DPolygon aNextPoly(rUnitPolygon);
     178             : 
     179           0 :                     aNextPoly.transform(rEntries[a + 1].maB2DHomMatrix);
     180           0 :                     aCombinedPolyPoly.append(aNextPoly);
     181             : 
     182             :                     // create primitive with correct color
     183           0 :                     aRetval[a + 1] = Primitive2DReference(
     184             :                         new PolyPolygonColorPrimitive2D(
     185             :                             aCombinedPolyPoly,
     186           0 :                             rEntries[a].maBColor));
     187             : 
     188             :                     // reuse inner polygon, it's the 2nd one
     189           0 :                     aCombinedPolyPoly.remove(0);
     190           0 :                 }
     191             : 
     192             :                 // add last inner polygon with last color
     193           0 :                 aRetval[rEntries.size()] = Primitive2DReference(
     194             :                     new PolyPolygonColorPrimitive2D(
     195             :                         aCombinedPolyPoly,
     196           0 :                         rEntries[rEntries.size() - 1].maBColor));
     197             :             }
     198             : 
     199           0 :             return aRetval;
     200             :         }
     201             : 
     202         686 :         Primitive2DSequence FillGradientPrimitive2D::createFill(bool bOverlapping) const
     203             :         {
     204             :             // prepare shape of the Unit Polygon
     205         686 :             basegfx::B2DPolygon aUnitPolygon;
     206             : 
     207         686 :             switch(getFillGradient().getStyle())
     208             :             {
     209             :                 case attribute::GRADIENTSTYLE_RADIAL:
     210             :                 case attribute::GRADIENTSTYLE_ELLIPTICAL:
     211             :                 {
     212           0 :                     aUnitPolygon = basegfx::tools::createPolygonFromCircle(basegfx::B2DPoint(0.0, 0.0), 1.0);
     213           0 :                     break;
     214             :                 }
     215             :                 default: // GRADIENTSTYLE_LINEAR, attribute::GRADIENTSTYLE_AXIAL, attribute::GRADIENTSTYLE_SQUARE, attribute::GRADIENTSTYLE_RECT
     216             :                 {
     217         686 :                     aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1.0, -1.0, 1.0, 1.0));
     218         686 :                     break;
     219             :                 }
     220             :             }
     221             : 
     222             :             // get the transform matrices and colors (where colors
     223             :             // will have one more entry that matrices)
     224         686 :             std::vector< drawinglayer::texture::B2DHomMatrixAndBColor > aEntries;
     225        1372 :             basegfx::BColor aOutmostColor;
     226             : 
     227         686 :             generateMatricesAndColors(aEntries, aOutmostColor);
     228             : 
     229         686 :             if(bOverlapping)
     230             :             {
     231         686 :                 return createOverlappingFill(aEntries, aOutmostColor, aUnitPolygon);
     232             :             }
     233             :             else
     234             :             {
     235           0 :                 return createNonOverlappingFill(aEntries, aOutmostColor, aUnitPolygon);
     236         686 :             }
     237             :         }
     238             : 
     239         686 :         Primitive2DSequence FillGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
     240             :         {
     241             :             // default creates overlapping fill which works with AntiAliasing and without.
     242             :             // The non-overlapping version does not create single filled polygons, but
     243             :             // PolyPolygons where each one describes a 'ring' for the gradient such
     244             :             // that the rings will not overlap. This is useful fir the old XOR-paint
     245             :             // 'trick' of VCL which is recorded in Metafiles; so this version may be
     246             :             // used from the MetafilePrimitive2D in it's decomposition.
     247             : 
     248         686 :             if(!getFillGradient().isDefault())
     249             :             {
     250             :                 static bool bOverlapping(true); // allow to test non-overlapping in the debugger
     251             : 
     252         686 :                 return createFill(bOverlapping);
     253             :             }
     254             :             else
     255             :             {
     256           0 :                 return Primitive2DSequence();
     257             :             }
     258             :         }
     259             : 
     260        1207 :         FillGradientPrimitive2D::FillGradientPrimitive2D(
     261             :             const basegfx::B2DRange& rObjectRange,
     262             :             const attribute::FillGradientAttribute& rFillGradient)
     263             :         :   BufferedDecompositionPrimitive2D(),
     264             :             maObjectRange(rObjectRange),
     265        1207 :             maFillGradient(rFillGradient)
     266             :         {
     267        1207 :         }
     268             : 
     269           0 :         bool FillGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
     270             :         {
     271           0 :             if(BufferedDecompositionPrimitive2D::operator==(rPrimitive))
     272             :             {
     273           0 :                 const FillGradientPrimitive2D& rCompare = (FillGradientPrimitive2D&)rPrimitive;
     274             : 
     275           0 :                 return (getObjectRange() == rCompare.getObjectRange()
     276           0 :                     && getFillGradient() == rCompare.getFillGradient());
     277             :             }
     278             : 
     279           0 :             return false;
     280             :         }
     281             : 
     282          47 :         basegfx::B2DRange FillGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
     283             :         {
     284             :             // return ObjectRange
     285          47 :             return getObjectRange();
     286             :         }
     287             : 
     288             :         // provide unique ID
     289         722 :         ImplPrimitive2DIDBlock(FillGradientPrimitive2D, PRIMITIVE2D_ID_FILLGRADIENTPRIMITIVE2D)
     290             : 
     291             :     } // end of namespace primitive2d
     292             : } // end of namespace drawinglayer
     293             : 
     294             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10