You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@openoffice.apache.org by al...@apache.org on 2012/10/02 11:23:26 UTC

svn commit: r1392807 [1/2] - in /incubator/ooo/trunk/main: basegfx/inc/basegfx/tools/ basegfx/source/tools/ cppcanvas/source/mtfrenderer/ drawinglayer/inc/drawinglayer/primitive2d/ drawinglayer/inc/drawinglayer/texture/ drawinglayer/source/primitive2d/...

Author: alg
Date: Tue Oct  2 09:23:25 2012
New Revision: 1392807

URL: http://svn.apache.org/viewvc?rev=1392807&view=rev
Log:
#120604# unified and secured gradient tooling for primitives, adapted usages

Modified:
    incubator/ooo/trunk/main/basegfx/inc/basegfx/tools/gradienttools.hxx
    incubator/ooo/trunk/main/basegfx/source/tools/gradienttools.cxx
    incubator/ooo/trunk/main/cppcanvas/source/mtfrenderer/implrenderer.cxx
    incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx
    incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/texture/texture.hxx
    incubator/ooo/trunk/main/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
    incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelpergradient.cxx
    incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx
    incubator/ooo/trunk/main/drawinglayer/source/texture/texture.cxx

Modified: incubator/ooo/trunk/main/basegfx/inc/basegfx/tools/gradienttools.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/basegfx/inc/basegfx/tools/gradienttools.hxx?rev=1392807&r1=1392806&r2=1392807&view=diff
==============================================================================
--- incubator/ooo/trunk/main/basegfx/inc/basegfx/tools/gradienttools.hxx (original)
+++ incubator/ooo/trunk/main/basegfx/inc/basegfx/tools/gradienttools.hxx Tue Oct  2 09:23:25 2012
@@ -41,12 +41,13 @@ namespace basegfx
         1.2-compatible gradients. Use the createXXXODFGradientInfo()
         methods below for initializing from ODF attributes.
      */
-    struct ODFGradientInfo
+    class ODFGradientInfo
     {
+    private:
         /** transformation mapping from [0,1]^2 texture coordinate
            space to [0,1]^2 shape coordinate space
          */
-        B2DHomMatrix maTextureTransform;
+        B2DHomMatrix    maTextureTransform;
 
         /** transformation mapping from [0,1]^2 shape coordinate space
            to [0,1]^2 texture coordinate space. This is the
@@ -54,20 +55,72 @@ namespace basegfx
            scanline rasterizer (put shape u/v coordinates into it, get
            texture s/t coordinates out of it)
          */
-        B2DHomMatrix maBackTextureTransform;
+        B2DHomMatrix    maBackTextureTransform;
 
         /** Aspect ratio of the gradient. Only used in drawinglayer
            for generating nested gradient polygons currently. Already
            catered for in the transformations above.
          */
-        double       mfAspectRatio;
+        double          mfAspectRatio;
 
         /** Requested gradient steps to render. See the
            implementations of the getXXXGradientAlpha() methods below,
            the semantic differs slightly for the different gradient
            types.
          */
-        sal_uInt32   mnSteps;
+        sal_uInt32      mnSteps;
+
+    public:
+        ODFGradientInfo()
+        :   maTextureTransform(),
+            maBackTextureTransform(),
+            mfAspectRatio(1.0),
+            mnSteps(0)
+        {
+        }
+
+        ODFGradientInfo(
+            const B2DHomMatrix& rTextureTransform,
+            double fAspectRatio,
+            sal_uInt32 nSteps)
+        :   maTextureTransform(rTextureTransform),
+            maBackTextureTransform(),
+            mfAspectRatio(fAspectRatio),
+            mnSteps(nSteps)
+        {
+        }
+
+        ODFGradientInfo(const ODFGradientInfo& rODFGradientInfo)
+        :   maTextureTransform(rODFGradientInfo.getTextureTransform()),
+            maBackTextureTransform(rODFGradientInfo.maBackTextureTransform),
+            mfAspectRatio(rODFGradientInfo.getAspectRatio()),
+            mnSteps(rODFGradientInfo.getSteps())
+        {
+        }
+
+        ODFGradientInfo& operator=(const ODFGradientInfo& rODFGradientInfo)
+        {
+            maTextureTransform = rODFGradientInfo.getTextureTransform();
+            maBackTextureTransform = rODFGradientInfo.maBackTextureTransform;
+            mfAspectRatio = rODFGradientInfo.getAspectRatio();
+            mnSteps = rODFGradientInfo.getSteps();
+            
+            return *this;
+        }
+
+        // compare operator
+        bool operator==(const ODFGradientInfo& rGeoTexSvx) const;
+
+        const B2DHomMatrix& getTextureTransform() const { return maTextureTransform; }
+        const B2DHomMatrix& getBackTextureTransform() const;
+        double getAspectRatio() const { return mfAspectRatio; }
+        sal_uInt32 getSteps() const { return mnSteps; }
+
+        void setTextureTransform(const B2DHomMatrix& rNew)
+        {
+            maTextureTransform = rNew;
+            maBackTextureTransform.identity();
+        }
     };
 
     namespace tools
@@ -93,12 +146,12 @@ namespace basegfx
             @param fAngle
             Gradient angle (from ODF)
          */
-		ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                     const B2DRange&  rTargetArea, 
-                                                     sal_uInt32       nSteps, 
-                                                     double           fBorder, 
-                                                     double           fAngle);
-        
+        ODFGradientInfo createLinearODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle);
+
         /** Calculate linear gradient blend value
 
             This method generates you the lerp alpha value for
@@ -112,18 +165,7 @@ namespace basegfx
             @param rGradInfo
             Gradient info, for transformation and number of steps
          */
-		inline double getLinearGradientAlpha(const B2DPoint&        rUV,
-                                             const ODFGradientInfo& rGradInfo )
-        {
-			const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
-            const double t(clamp(aCoor.getY(), 0.0, 1.0));
-            const sal_uInt32 nSteps(rGradInfo.mnSteps);
-
-			if(nSteps > 2L && nSteps < 128L)
-				return floor(t * nSteps) / double(nSteps + 1L);
-
-            return t;
-        }
+        double getLinearGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo);
 
         /** Create matrix for ODF's axial gradient definition
 
@@ -152,11 +194,11 @@ namespace basegfx
             @param fAngle
             Gradient angle (from ODF)
          */
-		ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                    const B2DRange&  rTargetArea, 
-                                                    sal_uInt32       nSteps, 
-                                                    double           fBorder, 
-                                                    double           fAngle);
+        ODFGradientInfo createAxialODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle);
 
         /** Calculate axial gradient blend value
 
@@ -171,20 +213,8 @@ namespace basegfx
             @param rGradInfo
             Gradient info, for transformation and number of steps
          */
-		inline double getAxialGradientAlpha(const B2DPoint&        rUV,
-                                            const ODFGradientInfo& rGradInfo )
-        {
-			const B2DPoint   aCoor(rGradInfo.maBackTextureTransform * rUV);
-			const double     t(clamp(fabs(aCoor.getY()), 0.0, 1.0));
-            const sal_uInt32 nSteps(rGradInfo.mnSteps);
-			const double     fInternalSteps((nSteps * 2L) - 1L);
-
-			if(nSteps > 2L && nSteps < 128L)
-				return floor(((t * fInternalSteps) + 1.0) / 2.0) / double(nSteps - 1L);
+        double getAxialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo);
 
-            return t;
-        }
-        
         /** Create matrix for ODF's radial gradient definition
 
             @param o_rGradientInfo
@@ -207,11 +237,11 @@ namespace basegfx
             @param fAngle
             Gradient angle (from ODF)
          */
-		ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                     const B2DRange&  rTargetArea, 
-                                                     const B2DVector& rOffset,
-                                                     sal_uInt32       nSteps, 
-                                                     double           fBorder);
+        ODFGradientInfo createRadialODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            const B2DVector& rOffset,
+            sal_uInt32 nSteps, 
+            double fBorder);
         
         /** Calculate radial gradient blend value
 
@@ -226,23 +256,7 @@ namespace basegfx
             @param rGradInfo
             Gradient info, for transformation and number of steps
          */
-		inline double getRadialGradientAlpha(const B2DPoint&        rUV,
-                                             const ODFGradientInfo& rGradInfo )
-        {
-			const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
-			const double   fDist(
-                clamp(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY(),
-                      0.0,
-                      1.0));
-
-			const double t(1.0 - sqrt(fDist));
-            const sal_uInt32 nSteps(rGradInfo.mnSteps);
-
-			if(nSteps > 2L && nSteps < 128L)
-				return floor(t * nSteps) / double(nSteps - 1L);
-
-            return t;
-        }
+        double getRadialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo);
 
         /** Create matrix for ODF's elliptical gradient definition
 
@@ -266,12 +280,12 @@ namespace basegfx
             @param fAngle
             Gradient angle (from ODF)
          */
-		ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                         const B2DRange&  rTargetArea, 
-                                                         const B2DVector& rOffset,
-                                                         sal_uInt32       nSteps, 
-                                                         double           fBorder, 
-                                                         double           fAngle);
+        ODFGradientInfo createEllipticalODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            const B2DVector& rOffset,
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle);
 
         /** Calculate elliptical gradient blend value
 
@@ -286,11 +300,7 @@ namespace basegfx
             @param rGradInfo
             Gradient info, for transformation and number of steps
          */
-		inline double getEllipticalGradientAlpha(const B2DPoint&        rUV,
-                                                 const ODFGradientInfo& rGradInfo )
-        {
-            return getRadialGradientAlpha(rUV,rGradInfo); // only matrix setup differs
-        }
+        double getEllipticalGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo);
 
         /** Create matrix for ODF's square gradient definition
 
@@ -314,12 +324,12 @@ namespace basegfx
             @param fAngle
             Gradient angle (from ODF)
          */
-		ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                     const B2DRange&  rTargetArea, 
-                                                     const B2DVector& rOffset,
-                                                     sal_uInt32       nSteps, 
-                                                     double           fBorder, 
-                                                     double           fAngle);
+        ODFGradientInfo createSquareODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            const B2DVector& rOffset,
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle);
 
         /** Calculate square gradient blend value
 
@@ -334,24 +344,7 @@ namespace basegfx
             @param rGradInfo
             Gradient info, for transformation and number of steps
          */
-		inline double getSquareGradientAlpha(const B2DPoint&        rUV,
-                                             const ODFGradientInfo& rGradInfo )
-        {
-			const B2DPoint aCoor(rGradInfo.maBackTextureTransform * rUV);
-			const double   fAbsX(fabs(aCoor.getX()));
-			const double   fAbsY(fabs(aCoor.getY()));
-
-			if(fTools::moreOrEqual(fAbsX, 1.0) || fTools::moreOrEqual(fAbsY, 1.0))
-                return 0.0;
-
-			const double t(1.0 - (fAbsX > fAbsY ? fAbsX : fAbsY));
-            const sal_uInt32 nSteps(rGradInfo.mnSteps);
-
-			if(nSteps > 2L && nSteps < 128L)
-				return floor(t * nSteps) / double(nSteps - 1L);
-
-            return t;
-        }
+        double getSquareGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo);
 
         /** Create matrix for ODF's rectangular gradient definition
 
@@ -375,12 +368,12 @@ namespace basegfx
             @param fAngle
             Gradient angle (from ODF)
          */
-		ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                          const B2DRange&  rTargetArea, 
-                                                          const B2DVector& rOffset,
-                                                          sal_uInt32       nSteps, 
-                                                          double           fBorder, 
-                                                          double           fAngle);
+        ODFGradientInfo createRectangularODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            const B2DVector& rOffset,
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle);
 
         /** Calculate rectangular gradient blend value
 
@@ -395,12 +388,10 @@ namespace basegfx
             @param rGradInfo
             Gradient info, for transformation and number of steps
          */
-		inline double getRectangularGradientAlpha(const B2DPoint&        rUV,
-                                                  const ODFGradientInfo& rGradInfo )
-        {
-            return getSquareGradientAlpha(rUV, rGradInfo); // only matrix setup differs
-        }
+        double getRectangularGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo);
     }
 }
 
 #endif
+
+// eof

Modified: incubator/ooo/trunk/main/basegfx/source/tools/gradienttools.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/basegfx/source/tools/gradienttools.cxx?rev=1392807&r1=1392806&r2=1392807&view=diff
==============================================================================
--- incubator/ooo/trunk/main/basegfx/source/tools/gradienttools.cxx (original)
+++ incubator/ooo/trunk/main/basegfx/source/tools/gradienttools.cxx Tue Oct  2 09:23:25 2012
@@ -31,19 +31,35 @@
 
 namespace basegfx
 {
+    bool ODFGradientInfo::operator==(const ODFGradientInfo& rODFGradientInfo) const
+    {
+        return getTextureTransform() == rODFGradientInfo.getTextureTransform()
+            && getAspectRatio() == rODFGradientInfo.getAspectRatio()
+            && getSteps() == rODFGradientInfo.getSteps();
+    }
+
+    const B2DHomMatrix& ODFGradientInfo::getBackTextureTransform() const
+    {
+        if(maBackTextureTransform.isIdentity())
+        {
+            const_cast< ODFGradientInfo* >(this)->maBackTextureTransform = getTextureTransform();
+            const_cast< ODFGradientInfo* >(this)->maBackTextureTransform.invert();
+        }
+
+        return maBackTextureTransform;
+    }
+
     /** Most of the setup for linear & axial gradient is the same, except
         for the border treatment. Factored out here.
     */
-    static void init1DGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                   const B2DRange&  rTargetRange, 
-                                   sal_uInt32       nSteps,
-                                   double           fBorder, 
-                                   double           fAngle,
-                                   bool             bAxial)
+    ODFGradientInfo init1DGradientInfo(
+        const B2DRange& rTargetRange, 
+        sal_uInt32 nSteps,
+        double fBorder, 
+        double fAngle,
+        bool bAxial)
     {
-        o_rGradientInfo.maTextureTransform.identity();
-        o_rGradientInfo.maBackTextureTransform.identity();
-        o_rGradientInfo.mnSteps = nSteps;
+        B2DHomMatrix aTextureTransform;
 
         fAngle = -fAngle;
 
@@ -53,70 +69,69 @@ namespace basegfx
         double fTargetOffsetY(rTargetRange.getMinY());
 
         // add object expansion
-        if(0.0 != fAngle)
+        const bool bAngleUsed(!fTools::equalZero(fAngle));
+        
+        if(bAngleUsed)
         {
             const double fAbsCos(fabs(cos(fAngle)));
             const double fAbsSin(fabs(sin(fAngle)));
             const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
             const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+            
             fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
             fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
             fTargetSizeX = fNewX;
             fTargetSizeY = fNewY;
         }
 
-        const double fSizeWithoutBorder=1.0 - fBorder;
-        if( bAxial )
+        const double fSizeWithoutBorder(1.0 - fBorder);
+
+        if(bAxial)
         {
-            o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder * .5);
-            o_rGradientInfo.maTextureTransform.translate(0.0, 0.5);
+            aTextureTransform.scale(1.0, fSizeWithoutBorder * 0.5);
+            aTextureTransform.translate(0.0, 0.5);
         }
         else 
         {
             if(!fTools::equal(fSizeWithoutBorder, 1.0))
             {
-                o_rGradientInfo.maTextureTransform.scale(1.0, fSizeWithoutBorder);
-                o_rGradientInfo.maTextureTransform.translate(0.0, fBorder);
+                aTextureTransform.scale(1.0, fSizeWithoutBorder);
+                aTextureTransform.translate(0.0, fBorder);
             }
         }
 
-        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+        aTextureTransform.scale(fTargetSizeX, fTargetSizeY);
 
         // add texture rotate after scale to keep perpendicular angles
-        if(0.0 != fAngle)
+        if(bAngleUsed)
         {
-            const B2DPoint aCenter(0.5*fTargetSizeX,
-                                   0.5*fTargetSizeY);
-            o_rGradientInfo.maTextureTransform *= 
-                basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
+            const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY);
+
+            aTextureTransform *= basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
         }
 
         // add object translate
-        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+        aTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
 
         // prepare aspect for texture
-        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;
+        const double fAspectRatio(fTools::equalZero(fTargetSizeY) ?  1.0 : fTargetSizeX / fTargetSizeY);
 
-        // build transform from u,v to [0.0 .. 1.0].
-        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
-        o_rGradientInfo.maBackTextureTransform.invert();
+        return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps);
     }
 
     /** Most of the setup for radial & ellipsoidal gradient is the same,
         except for the border treatment. Factored out here.
     */
-    static void initEllipticalGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                           const B2DRange&  rTargetRange, 
-                                           const B2DVector& rOffset,
-                                           sal_uInt32       nSteps,
-                                           double           fBorder, 
-                                           double           fAngle,
-                                           bool             bCircular)
+    ODFGradientInfo initEllipticalGradientInfo(
+        const B2DRange& rTargetRange, 
+        const B2DVector& rOffset,
+        sal_uInt32 nSteps,
+        double fBorder, 
+        double fAngle,
+        bool bCircular)
     {
-        o_rGradientInfo.maTextureTransform.identity();
-        o_rGradientInfo.maBackTextureTransform.identity();
-        o_rGradientInfo.mnSteps = nSteps;
-    
+        B2DHomMatrix aTextureTransform;
+
         fAngle = -fAngle;
 
         double fTargetSizeX(rTargetRange.getWidth());
@@ -125,9 +140,10 @@ namespace basegfx
         double fTargetOffsetY(rTargetRange.getMinY());
 
         // add object expansion
-        if( bCircular )
+        if(bCircular)
         {
             const double fOriginalDiag(sqrt((fTargetSizeX * fTargetSizeX) + (fTargetSizeY * fTargetSizeY)));
+
             fTargetOffsetX -= (fOriginalDiag - fTargetSizeX) / 2.0;
             fTargetOffsetY -= (fOriginalDiag - fTargetSizeY) / 2.0;
             fTargetSizeX = fOriginalDiag;
@@ -142,22 +158,21 @@ namespace basegfx
         }
 
         const double fHalfBorder((1.0 - fBorder) * 0.5);
-        o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder);
 
-        o_rGradientInfo.maTextureTransform.translate(0.5, 0.5);
-        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+        aTextureTransform.scale(fHalfBorder, fHalfBorder);
+        aTextureTransform.translate(0.5, 0.5);
+        aTextureTransform.scale(fTargetSizeX, fTargetSizeY);
 
         // add texture rotate after scale to keep perpendicular angles
-        if( !bCircular && 0.0 != fAngle)
+        if(!bCircular && !fTools::equalZero(fAngle))
         {
-            const B2DPoint aCenter(0.5*fTargetSizeX,
-                                   0.5*fTargetSizeY);
-            o_rGradientInfo.maTextureTransform *=
-                basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
+            const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY);
+
+            aTextureTransform *= basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
         }
 
         // add defined offsets after rotation
-        if(0.5 != rOffset.getX() || 0.5 != rOffset.getY())
+        if(!fTools::equal(0.5, rOffset.getX()) || !fTools::equal(0.5, rOffset.getY()))
         {
             // use original target size
             fTargetOffsetX += (rOffset.getX() - 0.5) * rTargetRange.getWidth();
@@ -165,30 +180,26 @@ namespace basegfx
         }
 
         // add object translate
-        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+        aTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
 
         // prepare aspect for texture
-        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;
+        const double fAspectRatio((0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0);
 
-        // build transform from u,v to [0.0 .. 1.0].
-        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
-        o_rGradientInfo.maBackTextureTransform.invert();
+        return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps);
     }
 
     /** Setup for rect & square gradient is exactly the same. Factored out
         here.
     */
-    static void initRectGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                     const B2DRange&  rTargetRange, 
-                                     const B2DVector& rOffset,
-                                     sal_uInt32       nSteps,
-                                     double           fBorder, 
-                                     double           fAngle,
-                                     bool             bSquare)
+    ODFGradientInfo initRectGradientInfo(
+        const B2DRange& rTargetRange, 
+        const B2DVector& rOffset,
+        sal_uInt32 nSteps,
+        double fBorder, 
+        double fAngle,
+        bool bSquare)
     {
-        o_rGradientInfo.maTextureTransform.identity();
-        o_rGradientInfo.maBackTextureTransform.identity();
-        o_rGradientInfo.mnSteps = nSteps;
+        B2DHomMatrix aTextureTransform;
 
         fAngle = -fAngle;
 
@@ -201,18 +212,22 @@ namespace basegfx
         if(bSquare)
         {
             const double fSquareWidth(std::max(fTargetSizeX, fTargetSizeY));
+            
             fTargetOffsetX -= (fSquareWidth - fTargetSizeX) / 2.0;
             fTargetOffsetY -= (fSquareWidth - fTargetSizeY) / 2.0;
             fTargetSizeX = fTargetSizeY = fSquareWidth;
         }    
 
         // add object expansion
-        if(0.0 != fAngle)
+        const bool bAngleUsed(!fTools::equalZero(fAngle));
+
+        if(bAngleUsed)
         {
             const double fAbsCos(fabs(cos(fAngle)));
             const double fAbsSin(fabs(sin(fAngle)));
             const double fNewX(fTargetSizeX * fAbsCos + fTargetSizeY * fAbsSin);
             const double fNewY(fTargetSizeY * fAbsCos + fTargetSizeX * fAbsSin);
+
             fTargetOffsetX -= (fNewX - fTargetSizeX) / 2.0;
             fTargetOffsetY -= (fNewY - fTargetSizeY) / 2.0;
             fTargetSizeX = fNewX;
@@ -220,22 +235,21 @@ namespace basegfx
         }
 
         const double fHalfBorder((1.0 - fBorder) * 0.5);
-        o_rGradientInfo.maTextureTransform.scale(fHalfBorder, fHalfBorder);
-
-        o_rGradientInfo.maTextureTransform.translate(0.5, 0.5);
-        o_rGradientInfo.maTextureTransform.scale(fTargetSizeX, fTargetSizeY);
+        
+        aTextureTransform.scale(fHalfBorder, fHalfBorder);
+        aTextureTransform.translate(0.5, 0.5);
+        aTextureTransform.scale(fTargetSizeX, fTargetSizeY);
 
         // add texture rotate after scale to keep perpendicular angles
-        if(0.0 != fAngle)
+        if(bAngleUsed)
         {
-            const B2DPoint aCenter(0.5*fTargetSizeX, 
-                                   0.5*fTargetSizeY);
-            o_rGradientInfo.maTextureTransform *= 
-                basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
+            const B2DPoint aCenter(0.5 * fTargetSizeX, 0.5 * fTargetSizeY);
+
+            aTextureTransform *= basegfx::tools::createRotateAroundPoint(aCenter, fAngle);
         }
 
         // add defined offsets after rotation
-        if(0.5 != rOffset.getX() || 0.5 != rOffset.getY())
+        if(!fTools::equal(0.5, rOffset.getX()) || !fTools::equal(0.5, rOffset.getY()))
         {
             // use scaled target size
             fTargetOffsetX += (rOffset.getX() - 0.5) * fTargetSizeX;
@@ -243,115 +257,183 @@ namespace basegfx
         }
 
         // add object translate
-        o_rGradientInfo.maTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
+        aTextureTransform.translate(fTargetOffsetX, fTargetOffsetY);
 
         // prepare aspect for texture
-        o_rGradientInfo.mfAspectRatio = (0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0;
+        const double fAspectRatio((0.0 != fTargetSizeY) ?  fTargetSizeX / fTargetSizeY : 1.0);
 
-        // build transform from u,v to [0.0 .. 1.0]. As base, use inverse texture transform
-        o_rGradientInfo.maBackTextureTransform = o_rGradientInfo.maTextureTransform;
-        o_rGradientInfo.maBackTextureTransform.invert();
+        return ODFGradientInfo(aTextureTransform, fAspectRatio, nSteps);
     }
 
     namespace tools
     {
-		ODFGradientInfo& createLinearODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                     const B2DRange&  rTargetArea, 
-                                                     sal_uInt32       nSteps, 
-                                                     double           fBorder, 
-                                                     double           fAngle)
-        {
-            init1DGradientInfo(o_rGradientInfo,
-                               rTargetArea, 
-                               nSteps,
-                               fBorder, 
-                               fAngle,
-                               false);
-            return o_rGradientInfo;
-        }
-
-		ODFGradientInfo& createAxialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                    const B2DRange&  rTargetArea, 
-                                                    sal_uInt32       nSteps, 
-                                                    double           fBorder, 
-                                                    double           fAngle)
-        {
-            init1DGradientInfo(o_rGradientInfo,
-                               rTargetArea, 
-                               nSteps,
-                               fBorder, 
-                               fAngle,
-                               true);
-            return o_rGradientInfo;
-        }
-
-		ODFGradientInfo& createRadialODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                     const B2DRange&  rTargetArea, 
-                                                     const B2DVector& rOffset,
-                                                     sal_uInt32       nSteps, 
-                                                     double           fBorder)
-        {
-            initEllipticalGradientInfo(o_rGradientInfo,
-                                       rTargetArea, 
-                                       rOffset,
-                                       nSteps,
-                                       fBorder, 
-                                       0.0,
-                                       true);
-            return o_rGradientInfo;
-        }
-
-		ODFGradientInfo& createEllipticalODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                         const B2DRange&  rTargetArea, 
-                                                         const B2DVector& rOffset,
-                                                         sal_uInt32       nSteps, 
-                                                         double           fBorder, 
-                                                         double           fAngle)
-        {
-            initEllipticalGradientInfo(o_rGradientInfo,
-                                       rTargetArea, 
-                                       rOffset,
-                                       nSteps,
-                                       fBorder, 
-                                       fAngle,
-                                       false);
-            return o_rGradientInfo;
-        }
-
-		ODFGradientInfo& createSquareODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                     const B2DRange&  rTargetArea, 
-                                                     const B2DVector& rOffset,
-                                                     sal_uInt32       nSteps, 
-                                                     double           fBorder, 
-                                                     double           fAngle)
-        {
-            initRectGradientInfo(o_rGradientInfo,
-                                 rTargetArea, 
-                                 rOffset,
-                                 nSteps,
-                                 fBorder, 
-                                 fAngle,
-                                 true);
-            return o_rGradientInfo;
-        }
-
-		ODFGradientInfo& createRectangularODFGradientInfo(ODFGradientInfo& o_rGradientInfo,
-                                                          const B2DRange&  rTargetArea, 
-                                                          const B2DVector& rOffset,
-                                                          sal_uInt32       nSteps, 
-                                                          double           fBorder, 
-                                                          double           fAngle)
-        {
-            initRectGradientInfo(o_rGradientInfo,
-                                 rTargetArea, 
-                                 rOffset,
-                                 nSteps,
-                                 fBorder, 
-                                 fAngle,
-                                 false);
-            return o_rGradientInfo;
+        ODFGradientInfo createLinearODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle)
+        {
+            return init1DGradientInfo(
+                rTargetArea, 
+                nSteps,
+                fBorder, 
+                fAngle,
+                false);
+        }
+
+        ODFGradientInfo createAxialODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle)
+        {
+            return init1DGradientInfo(
+                rTargetArea, 
+                nSteps,
+                fBorder, 
+                fAngle,
+                true);
+        }
+
+        ODFGradientInfo createRadialODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            const B2DVector& rOffset,
+            sal_uInt32 nSteps, 
+            double fBorder)
+        {
+            return initEllipticalGradientInfo(
+                rTargetArea, 
+                rOffset,
+                nSteps,
+                fBorder, 
+                0.0,
+                true);
+        }
+
+        ODFGradientInfo createEllipticalODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            const B2DVector& rOffset,
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle)
+        {
+            return initEllipticalGradientInfo(
+                rTargetArea, 
+                rOffset,
+                nSteps,
+                fBorder, 
+                fAngle,
+                false);
+        }
+
+        ODFGradientInfo createSquareODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            const B2DVector& rOffset,
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle)
+        {
+            return initRectGradientInfo(
+                rTargetArea, 
+                rOffset,
+                nSteps,
+                fBorder, 
+                fAngle,
+                true);
+        }
+
+        ODFGradientInfo createRectangularODFGradientInfo(
+            const B2DRange& rTargetArea, 
+            const B2DVector& rOffset,
+            sal_uInt32 nSteps, 
+            double fBorder, 
+            double fAngle)
+        {
+            return initRectGradientInfo(
+                rTargetArea, 
+                rOffset,
+                nSteps,
+                fBorder, 
+                fAngle,
+                false);
+        }
+
+        double getLinearGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+        {
+            const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
+            const double t(clamp(aCoor.getY(), 0.0, 1.0));
+            const sal_uInt32 nSteps(rGradInfo.getSteps());
+
+            if(nSteps)
+            {
+                return floor(t * nSteps) / double(nSteps + 1L);
+            }
+
+            return t;
+        }
+
+        double getAxialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+        {
+            const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
+            const double t(clamp(fabs(aCoor.getY()), 0.0, 1.0));
+            const sal_uInt32 nSteps(rGradInfo.getSteps());
+            const double fInternalSteps((nSteps * 2) - 1);
+
+            if(nSteps)
+            {
+                return floor(((t * fInternalSteps) + 1.0) / 2.0) / double(nSteps - 1L);
+            }
+
+            return t;
         }
-        
-    } // namespace tools
 
+        double getRadialGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+        {
+            const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
+            const double fDist(clamp(aCoor.getX() * aCoor.getX() + aCoor.getY() * aCoor.getY(), 0.0, 1.0));
+            const double t(1.0 - sqrt(fDist));
+            const sal_uInt32 nSteps(rGradInfo.getSteps());
+
+            if(nSteps)
+            {
+                return floor(t * nSteps) / double(nSteps - 1L);
+            }
+
+            return t;
+        }
+
+        double getEllipticalGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+        {
+            return getRadialGradientAlpha(rUV, rGradInfo); // only matrix setup differs
+        }
+
+        double getSquareGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+        {
+            const B2DPoint aCoor(rGradInfo.getBackTextureTransform() * rUV);
+            const double fAbsX(fabs(aCoor.getX()));
+            const double fAbsY(fabs(aCoor.getY()));
+
+            if(fTools::moreOrEqual(fAbsX, 1.0) || fTools::moreOrEqual(fAbsY, 1.0))
+            {
+                return 0.0;
+            }
+
+            const double t(1.0 - std::max(fAbsX, fAbsY));
+            const sal_uInt32 nSteps(rGradInfo.getSteps());
+
+            if(nSteps)
+            {
+                return floor(t * nSteps) / double(nSteps - 1L);
+            }
+
+            return t;
+        }
+
+        double getRectangularGradientAlpha(const B2DPoint& rUV, const ODFGradientInfo& rGradInfo)
+        {
+            return getSquareGradientAlpha(rUV, rGradInfo); // only matrix setup differs
+        }
+    } // namespace tools
 } // namespace basegfx
+
+// eof

Modified: incubator/ooo/trunk/main/cppcanvas/source/mtfrenderer/implrenderer.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/cppcanvas/source/mtfrenderer/implrenderer.cxx?rev=1392807&r1=1392806&r2=1392807&view=diff
==============================================================================
--- incubator/ooo/trunk/main/cppcanvas/source/mtfrenderer/implrenderer.cxx (original)
+++ incubator/ooo/trunk/main/cppcanvas/source/mtfrenderer/implrenderer.cxx Tue Oct  2 09:23:25 2012
@@ -688,14 +688,14 @@ namespace cppcanvas
                     switch( rGradient.GetStyle() )
                     {
                         case GRADIENT_LINEAR:
-                            basegfx::tools::createLinearODFGradientInfo(aGradInfo,
+                            aGradInfo = basegfx::tools::createLinearODFGradientInfo(
                                                                         aBounds,
                                                                         nSteps,
                                                                         fBorder,
                                                                         fRotation);
                             // map odf to svg gradient orientation - x
                             // instead of y direction
-                            aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aRot90;
+                            aGradInfo.setTextureTransform(aGradInfo.getTextureTransform() * aRot90);
                             aGradientService = rtl::OUString::createFromAscii("LinearGradient");
                             break;
 
@@ -714,27 +714,27 @@ namespace cppcanvas
                             // border value, hence the second (left
                             // most 1-...
                             const double fAxialBorder (1-2*(1-fBorder));
-                            basegfx::tools::createAxialODFGradientInfo(aGradInfo,
+                            aGradInfo = basegfx::tools::createAxialODFGradientInfo(
                                                                         aBounds,
                                                                         nSteps,
                                                                         fAxialBorder,
                                                                         fRotation);
                             // map odf to svg gradient orientation - x
                             // instead of y direction
-                            aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aRot90;
+                            aGradInfo.setTextureTransform(aGradInfo.getTextureTransform() * aRot90);
 
                             // map odf axial gradient to 3-stop linear
                             // gradient - shift left by 0.5
                             basegfx::B2DHomMatrix aShift;
+                            
                             aShift.translate(-0.5,0);
-                            aGradInfo.maTextureTransform = aGradInfo.maTextureTransform * aShift;
-
+                            aGradInfo.setTextureTransform(aGradInfo.getTextureTransform() * aShift);
                             aGradientService = rtl::OUString::createFromAscii("LinearGradient");
                             break;
                         }
 
                         case GRADIENT_RADIAL:
-                            basegfx::tools::createRadialODFGradientInfo(aGradInfo,
+                            aGradInfo = basegfx::tools::createRadialODFGradientInfo(
                                                                         aBounds,
                                                                         aOffset,
                                                                         nSteps,
@@ -743,7 +743,7 @@ namespace cppcanvas
                             break;
 
                         case GRADIENT_ELLIPTICAL:
-                            basegfx::tools::createEllipticalODFGradientInfo(aGradInfo,
+                            aGradInfo = basegfx::tools::createEllipticalODFGradientInfo(
                                                                             aBounds,
                                                                             aOffset,
                                                                             nSteps,
@@ -753,7 +753,7 @@ namespace cppcanvas
                             break;
 
                         case GRADIENT_SQUARE:
-                            basegfx::tools::createSquareODFGradientInfo(aGradInfo,
+                            aGradInfo = basegfx::tools::createSquareODFGradientInfo(
                                                                         aBounds,
                                                                         aOffset,
                                                                         nSteps,
@@ -763,7 +763,7 @@ namespace cppcanvas
                             break;
 
                         case GRADIENT_RECT:
-                            basegfx::tools::createRectangularODFGradientInfo(aGradInfo,
+                            aGradInfo = basegfx::tools::createRectangularODFGradientInfo(
                                                                              aBounds,
                                                                              aOffset,
                                                                              nSteps,
@@ -785,10 +785,12 @@ namespace cppcanvas
                     // gradient will always display at the origin, and
                     // not within the polygon bound (which might be
                     // miles away from the origin).
-                    aGradInfo.maTextureTransform.translate( aBounds.getMinX(),
-                                                            aBounds.getMinY() );
+                    aGradInfo.setTextureTransform(
+                        basegfx::tools::createTranslateB2DHomMatrix(
+                            aBounds.getMinX(), 
+                            aBounds.getMinY()) * aGradInfo.getTextureTransform());
                     ::basegfx::unotools::affineMatrixFromHomMatrix( aTexture.AffineTransform,
-                                                                    aGradInfo.maTextureTransform );
+                                                                    aGradInfo.getTextureTransform() );
 
                     uno::Sequence<uno::Any> args(3);
                     beans::PropertyValue aProp;
@@ -799,7 +801,7 @@ namespace cppcanvas
                     aProp.Value <<= aStops;
                     args[1] <<= aProp;
                     aProp.Name = rtl::OUString::createFromAscii("AspectRatio");
-                    aProp.Value <<= aGradInfo.mfAspectRatio;
+                    aProp.Value <<= aGradInfo.getAspectRatio();
                     args[2] <<= aProp;
 
                     aTexture.Gradient.set(

Modified: incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx?rev=1392807&r1=1392806&r2=1392807&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/primitive2d/fillgradientprimitive2d.hxx Tue Oct  2 09:23:25 2012
@@ -27,6 +27,7 @@
 #include <drawinglayer/drawinglayerdllapi.h>
 #include <drawinglayer/primitive2d/baseprimitive2d.hxx>
 #include <drawinglayer/attribute/fillgradientattribute.hxx>
+#include <drawinglayer/texture/texture.hxx>
 
 //////////////////////////////////////////////////////////////////////////////
 // predefines
@@ -65,15 +66,15 @@ namespace drawinglayer
 
             /// local helpers
             void generateMatricesAndColors(
-                std::vector< basegfx::B2DHomMatrix >& rMatrices,
-                std::vector< basegfx::BColor >& rColors) const;
+                std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries, 
+                basegfx::BColor& rOutmostColor) const;
             Primitive2DSequence createOverlappingFill(
-                const std::vector< basegfx::B2DHomMatrix >& rMatrices,
-                const std::vector< basegfx::BColor >& rColors,
+                const std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries, 
+                const basegfx::BColor& rOutmostColor,
                 const basegfx::B2DPolygon& rUnitPolygon) const;
             Primitive2DSequence createNonOverlappingFill(
-                const std::vector< basegfx::B2DHomMatrix >& rMatrices,
-                const std::vector< basegfx::BColor >& rColors,
+                const std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries, 
+                const basegfx::BColor& rOutmostColor,
                 const basegfx::B2DPolygon& rUnitPolygon) const;
 
 		protected:

Modified: incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/texture/texture.hxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/texture/texture.hxx?rev=1392807&r1=1392806&r2=1392807&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/texture/texture.hxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/inc/drawinglayer/texture/texture.hxx Tue Oct  2 09:23:25 2012
@@ -47,7 +47,6 @@ namespace drawinglayer
 			bool operator!=(const GeoTexSvx& rGeoTexSvx) const { return !operator==(rGeoTexSvx); }
 
 			// virtual base methods
-			virtual void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices);
 			virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
 			virtual void modifyOpacity(const basegfx::B2DPoint& rUV, double& rfOpacity) const;
 		};
@@ -58,6 +57,22 @@ namespace drawinglayer
 
 namespace drawinglayer
 {
+    namespace texture
+    {
+        /// helper class for processing equal number of matrices and colors
+        /// for texture processing
+        struct B2DHomMatrixAndBColor
+        {
+            basegfx::B2DHomMatrix   maB2DHomMatrix;
+            basegfx::BColor         maBColor;
+        };
+	} // end of namespace texture
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
 	namespace texture
 	{
 		class DRAWINGLAYER_DLLPUBLIC GeoTexSvxGradient : public GeoTexSvx
@@ -69,19 +84,22 @@ namespace drawinglayer
 			basegfx::BColor						maEnd;
 			double								mfBorder;
 
-			// helpers
-			void impAppendMatrix(::std::vector< basegfx::B2DHomMatrix >& rMatrices, const basegfx::B2DRange& rRange);
-			void impAppendColorsRadial(::std::vector< basegfx::BColor >& rColors);
-
 		public:
-			GeoTexSvxGradient(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder);
+			GeoTexSvxGradient(
+                const basegfx::B2DRange& rTargetRange, 
+                const basegfx::BColor& rStart, 
+                const basegfx::BColor& rEnd, 
+                sal_uInt32 nSteps, 
+                double fBorder);
 			virtual ~GeoTexSvxGradient();
 
 			// compare operator
 			virtual bool operator==(const GeoTexSvx& rGeoTexSvx) const;
 
 			// virtual base methods
-			virtual void appendColors(::std::vector< basegfx::BColor >& rColors) = 0;
+			virtual void appendTransformationsAndColors(
+                std::vector< B2DHomMatrixAndBColor >& rEntries, 
+                basegfx::BColor& rOutmostColor) = 0;
 
 			// data access
 			const basegfx::BColor& getStart() const { return maStart; }
@@ -99,11 +117,18 @@ namespace drawinglayer
 		class DRAWINGLAYER_DLLPUBLIC GeoTexSvxGradientLinear : public GeoTexSvxGradient
 		{
 		public:
-			GeoTexSvxGradientLinear(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fAngle);
+			GeoTexSvxGradientLinear(
+                const basegfx::B2DRange& rTargetRange, 
+                const basegfx::BColor& rStart, 
+                const basegfx::BColor& rEnd, 
+                sal_uInt32 nSteps, 
+                double fBorder, 
+                double fAngle);
 			virtual ~GeoTexSvxGradientLinear();
 
-			virtual void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices);
-			virtual void appendColors(::std::vector< basegfx::BColor >& rColors);
+			virtual void appendTransformationsAndColors(
+                std::vector< B2DHomMatrixAndBColor >& rEntries, 
+                basegfx::BColor& rOutmostColor);
 			virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
 		};
 	} // end of namespace texture
@@ -118,11 +143,18 @@ namespace drawinglayer
 		class DRAWINGLAYER_DLLPUBLIC GeoTexSvxGradientAxial : public GeoTexSvxGradient
 		{
 		public:
-			GeoTexSvxGradientAxial(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fAngle);
+			GeoTexSvxGradientAxial(
+                const basegfx::B2DRange& rTargetRange, 
+                const basegfx::BColor& rStart, 
+                const basegfx::BColor& rEnd, 
+                sal_uInt32 nSteps, 
+                double fBorder, 
+                double fAngle);
 			virtual ~GeoTexSvxGradientAxial();
 
-			virtual void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices);
-			virtual void appendColors(::std::vector< basegfx::BColor >& rColors);
+			virtual void appendTransformationsAndColors(
+                std::vector< B2DHomMatrixAndBColor >& rEntries, 
+                basegfx::BColor& rOutmostColor);
 			virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
 		};
 	} // end of namespace texture
@@ -137,11 +169,19 @@ namespace drawinglayer
 		class DRAWINGLAYER_DLLPUBLIC GeoTexSvxGradientRadial : public GeoTexSvxGradient
 		{
 		public:
-			GeoTexSvxGradientRadial(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY);
+			GeoTexSvxGradientRadial(
+                const basegfx::B2DRange& rTargetRange, 
+                const basegfx::BColor& rStart, 
+                const basegfx::BColor& rEnd, 
+                sal_uInt32 nSteps, 
+                double fBorder, 
+                double fOffsetX, 
+                double fOffsetY);
 			virtual ~GeoTexSvxGradientRadial();
 
-			virtual void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices);
-			virtual void appendColors(::std::vector< basegfx::BColor >& rColors);
+			virtual void appendTransformationsAndColors(
+                std::vector< B2DHomMatrixAndBColor >& rEntries, 
+                basegfx::BColor& rOutmostColor);
 			virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
 		};
 	} // end of namespace texture
@@ -156,11 +196,20 @@ namespace drawinglayer
 		class DRAWINGLAYER_DLLPUBLIC GeoTexSvxGradientElliptical : public GeoTexSvxGradient
 		{
 		public:
-			GeoTexSvxGradientElliptical(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle);
+			GeoTexSvxGradientElliptical(
+                const basegfx::B2DRange& rTargetRange, 
+                const basegfx::BColor& rStart, 
+                const basegfx::BColor& rEnd, 
+                sal_uInt32 nSteps, 
+                double fBorder, 
+                double fOffsetX, 
+                double fOffsetY, 
+                double fAngle);
 			virtual ~GeoTexSvxGradientElliptical();
 
-			virtual void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices);
-			virtual void appendColors(::std::vector< basegfx::BColor >& rColors);
+			virtual void appendTransformationsAndColors(
+                std::vector< B2DHomMatrixAndBColor >& rEntries, 
+                basegfx::BColor& rOutmostColor);
 			virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
 		};
 	} // end of namespace texture
@@ -175,11 +224,20 @@ namespace drawinglayer
 		class DRAWINGLAYER_DLLPUBLIC GeoTexSvxGradientSquare : public GeoTexSvxGradient
 		{
 		public:
-			GeoTexSvxGradientSquare(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle);
+			GeoTexSvxGradientSquare(
+                const basegfx::B2DRange& rTargetRange, 
+                const basegfx::BColor& rStart, 
+                const basegfx::BColor& rEnd, 
+                sal_uInt32 nSteps, 
+                double fBorder, 
+                double fOffsetX, 
+                double fOffsetY, 
+                double fAngle);
 			virtual ~GeoTexSvxGradientSquare();
 
-			virtual void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices);
-			virtual void appendColors(::std::vector< basegfx::BColor >& rColors);
+			virtual void appendTransformationsAndColors(
+                std::vector< B2DHomMatrixAndBColor >& rEntries, 
+                basegfx::BColor& rOutmostColor);
 			virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
 		};
 	} // end of namespace texture
@@ -194,11 +252,20 @@ namespace drawinglayer
 		class DRAWINGLAYER_DLLPUBLIC GeoTexSvxGradientRect : public GeoTexSvxGradient
 		{
 		public:
-			GeoTexSvxGradientRect(const basegfx::B2DRange& rTargetRange, const basegfx::BColor& rStart, const basegfx::BColor& rEnd, sal_uInt32 nSteps, double fBorder, double fOffsetX, double fOffsetY, double fAngle);
+			GeoTexSvxGradientRect(
+                const basegfx::B2DRange& rTargetRange, 
+                const basegfx::BColor& rStart, 
+                const basegfx::BColor& rEnd, 
+                sal_uInt32 nSteps, 
+                double fBorder, 
+                double fOffsetX, 
+                double fOffsetY, 
+                double fAngle);
 			virtual ~GeoTexSvxGradientRect();
 
-			virtual void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices);
-			virtual void appendColors(::std::vector< basegfx::BColor >& rColors);
+			virtual void appendTransformationsAndColors(
+                std::vector< B2DHomMatrixAndBColor >& rEntries, 
+                basegfx::BColor& rOutmostColor);
 			virtual void modifyBColor(const basegfx::B2DPoint& rUV, basegfx::BColor& rBColor, double& rfOpacity) const;
 		};
 	} // end of namespace texture
@@ -220,7 +287,10 @@ namespace drawinglayer
 			sal_uInt32							mnSteps;
 
 		public:
-			GeoTexSvxHatch(const basegfx::B2DRange& rTargetRange, double fDistance, double fAngle);
+			GeoTexSvxHatch(
+                const basegfx::B2DRange& rTargetRange, 
+                double fDistance, 
+                double fAngle);
 			virtual ~GeoTexSvxHatch();
 
 			// compare operator
@@ -228,6 +298,7 @@ namespace drawinglayer
 
 			virtual void appendTransformations(::std::vector< basegfx::B2DHomMatrix >& rMatrices);
 			double getDistanceToHatch(const basegfx::B2DPoint& rUV) const;
+			const basegfx::B2DHomMatrix& getBackTextureTransform() const;
 		};
 	} // end of namespace texture
 } // end of namespace drawinglayer
@@ -245,7 +316,9 @@ namespace drawinglayer
 			basegfx::B2DVector							maSize;
 
 		public:
-			GeoTexSvxTiled(const basegfx::B2DPoint& rTopLeft, const basegfx::B2DVector& rSize);
+			GeoTexSvxTiled(
+                const basegfx::B2DPoint& rTopLeft, 
+                const basegfx::B2DVector& rSize);
 			virtual ~GeoTexSvxTiled();
 
 			// compare operator

Modified: incubator/ooo/trunk/main/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx?rev=1392807&r1=1392806&r2=1392807&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/primitive2d/fillgradientprimitive2d.cxx Tue Oct  2 09:23:25 2012
@@ -43,11 +43,10 @@ namespace drawinglayer
 	namespace primitive2d
 	{
         void FillGradientPrimitive2D::generateMatricesAndColors(
-            std::vector< basegfx::B2DHomMatrix >& rMatrices,
-            std::vector< basegfx::BColor >& rColors) const
+            std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries, 
+            basegfx::BColor& rOutmostColor) const
         {
-            rMatrices.clear();
-            rColors.clear();
+            rEntries.clear();
 
 			// make sure steps is not too high/low
 			const basegfx::BColor aStart(getFillGradient().getStartColor());
@@ -75,127 +74,131 @@ namespace drawinglayer
 				case attribute::GRADIENTSTYLE_LINEAR:
 				{
 					texture::GeoTexSvxGradientLinear aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
-					aGradient.appendTransformations(rMatrices);
-					aGradient.appendColors(rColors);
+					aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
 					break;
 				}
 				case attribute::GRADIENTSTYLE_AXIAL:
 				{
 					texture::GeoTexSvxGradientAxial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getAngle());
-					aGradient.appendTransformations(rMatrices);
-					aGradient.appendColors(rColors);
+					aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
 					break;
 				}
 				case attribute::GRADIENTSTYLE_RADIAL:
 				{
 					texture::GeoTexSvxGradientRadial aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY());
-					aGradient.appendTransformations(rMatrices);
-					aGradient.appendColors(rColors);
+					aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
 					break;
 				}
 				case attribute::GRADIENTSTYLE_ELLIPTICAL:
 				{
 					texture::GeoTexSvxGradientElliptical aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
-					aGradient.appendTransformations(rMatrices);
-					aGradient.appendColors(rColors);
+					aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
 					break;
 				}
 				case attribute::GRADIENTSTYLE_SQUARE:
 				{
 					texture::GeoTexSvxGradientSquare aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
-					aGradient.appendTransformations(rMatrices);
-					aGradient.appendColors(rColors);
+					aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
 					break;
 				}
 				case attribute::GRADIENTSTYLE_RECT:
 				{
 					texture::GeoTexSvxGradientRect aGradient(getObjectRange(), aStart, aEnd, nSteps, getFillGradient().getBorder(), getFillGradient().getOffsetX(), getFillGradient().getOffsetY(), getFillGradient().getAngle());
-					aGradient.appendTransformations(rMatrices);
-					aGradient.appendColors(rColors);
+					aGradient.appendTransformationsAndColors(rEntries, rOutmostColor);
 					break;
 				}
 			}
         }
 
         Primitive2DSequence FillGradientPrimitive2D::createOverlappingFill(
-            const std::vector< basegfx::B2DHomMatrix >& rMatrices,
-            const std::vector< basegfx::BColor >& rColors,
+            const std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries,
+            const basegfx::BColor& rOutmostColor,
             const basegfx::B2DPolygon& rUnitPolygon) const
         {
-			// prepare return value
-			Primitive2DSequence aRetval(rColors.size() ? rMatrices.size() + 1 : rMatrices.size());
+            // prepare return value
+            Primitive2DSequence aRetval(rEntries.size() + 1);
 
-            // create solid fill with start color
-		    if(rColors.size())
-		    {
-			    // create primitive
-			    const Primitive2DReference xRef(
-                    new PolyPolygonColorPrimitive2D(
-                        basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())), 
-                        rColors[0]));
-			    aRetval[0] = xRef;
-		    }
-
-		    // create solid fill steps
-		    for(sal_uInt32 a(0); a < rMatrices.size(); a++)
-		    {
-			    // create part polygon
-			    basegfx::B2DPolygon aNewPoly(rUnitPolygon);
-			    aNewPoly.transform(rMatrices[a]);
+            // create solid fill with outmost color
+            aRetval[0] = Primitive2DReference(
+                new PolyPolygonColorPrimitive2D(
+                    basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(getObjectRange())), 
+                    rOutmostColor));
+
+            // create solid fill steps
+            for(sal_uInt32 a(0); a < rEntries.size(); a++)
+            {
+                // create part polygon
+                basegfx::B2DPolygon aNewPoly(rUnitPolygon);
+
+                aNewPoly.transform(rEntries[a].maB2DHomMatrix);
 
-			    // create solid fill
-			    const Primitive2DReference xRef(
+                // create solid fill
+                aRetval[a + 1] = Primitive2DReference(
                     new PolyPolygonColorPrimitive2D(
                         basegfx::B2DPolyPolygon(aNewPoly), 
-                        rColors[a + 1]));
-			    aRetval[a + 1] = xRef;
-		    }
+                        rEntries[a].maBColor));
+            }
 
             return aRetval;
         }
 
         Primitive2DSequence FillGradientPrimitive2D::createNonOverlappingFill(
-            const std::vector< basegfx::B2DHomMatrix >& rMatrices,
-            const std::vector< basegfx::BColor >& rColors,
+            const std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries, 
+            const basegfx::BColor& rOutmostColor,
             const basegfx::B2DPolygon& rUnitPolygon) const
         {
-			// prepare return value
-			Primitive2DSequence aRetval;
-            const sal_uInt32 nMatricesSize(rMatrices.size());
-
-            if(nMatricesSize)
-            {
-			    basegfx::B2DPolygon aOuterPoly(rUnitPolygon);
-			    aOuterPoly.transform(rMatrices[0]);
-                basegfx::B2DPolyPolygon aCombinedPolyPoly(aOuterPoly);
-    			const sal_uInt32 nEntryCount(rColors.size() ? rMatrices.size() + 1 : rMatrices.size());
-                sal_uInt32 nIndex(0);
-
-                aRetval.realloc(nEntryCount);
-			    
-		        if(rColors.size())
-		        {
-                    basegfx::B2DRange aOuterPolyRange(aOuterPoly.getB2DRange());
-                    aOuterPolyRange.expand(getObjectRange());
-                    aCombinedPolyPoly.append(basegfx::tools::createPolygonFromRect(aOuterPolyRange));
-                    aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[0]));
-                    aCombinedPolyPoly = basegfx::B2DPolyPolygon(aOuterPoly);
-                }
+            // prepare return value
+            Primitive2DSequence aRetval(rEntries.size() + 1);
 
-                for(sal_uInt32 a(1); a < nMatricesSize - 1; a++)
-		        {
-                    basegfx::B2DPolygon aInnerPoly(rUnitPolygon);
-			        aInnerPoly.transform(rMatrices[a]);
-                    aCombinedPolyPoly.append(aInnerPoly);
-			        aRetval[nIndex++] = Primitive2DReference(new PolyPolygonColorPrimitive2D(aCombinedPolyPoly, rColors[a]));
-                    aCombinedPolyPoly = basegfx::B2DPolyPolygon(aInnerPoly);
-                }
+            // get outmost range from object
+            basegfx::B2DRange aOutmostRange(getObjectRange());
+            basegfx::B2DPolyPolygon aCombinedPolyPoly;
+
+            if(rEntries.size())
+            {
+                // extend aOutmostRange with first polygon
+                basegfx::B2DPolygon aFirstPoly(rUnitPolygon);
+
+                aFirstPoly.transform(rEntries[0].maB2DHomMatrix);
+                aCombinedPolyPoly.append(aFirstPoly);
+                aOutmostRange.expand(aFirstPoly.getB2DRange());
+            }
+
+            // add outmost range to combined polypolygon (in 1st place), create first primitive
+            aCombinedPolyPoly.insert(0, basegfx::tools::createPolygonFromRect(aOutmostRange));
+            aRetval[0] = Primitive2DReference(
+                new PolyPolygonColorPrimitive2D(
+                    aCombinedPolyPoly, 
+                    rOutmostColor));
+
+            if(rEntries.size())
+            {
+                // reuse first polygon, it's the second one
+                aCombinedPolyPoly.remove(0);
+
+                for(sal_uInt32 a(0); a < rEntries.size() - 1; a++)
+                {
+                    // create next inner polygon, combinbe with last one
+                    basegfx::B2DPolygon aNextPoly(rUnitPolygon);
+
+                    aNextPoly.transform(rEntries[a + 1].maB2DHomMatrix);
+                    aCombinedPolyPoly.append(aNextPoly);
+
+                    // create primitive with correct color
+                    aRetval[a + 1] = Primitive2DReference(
+                        new PolyPolygonColorPrimitive2D(
+                            aCombinedPolyPoly, 
+                            rEntries[a].maBColor));
 
-		        if(rColors.size())
-		        {
-                    aRetval[nIndex] = Primitive2DReference(new PolyPolygonColorPrimitive2D(
-                        aCombinedPolyPoly, rColors[rColors.size() - 1]));
+                    // reuse inner polygon, it's the 2nd one
+                    aCombinedPolyPoly.remove(0);
                 }
+
+                // add last inner polygon with last color
+                aRetval[rEntries.size()] = Primitive2DReference(
+                    new PolyPolygonColorPrimitive2D(
+                        aCombinedPolyPoly, 
+                        rEntries[rEntries.size() - 1].maBColor));
             }
 
             return aRetval;
@@ -206,34 +209,35 @@ namespace drawinglayer
             // prepare shape of the Unit Polygon
 			basegfx::B2DPolygon aUnitPolygon;
 
-			if(attribute::GRADIENTSTYLE_RADIAL == getFillGradient().getStyle() 
-                || attribute::GRADIENTSTYLE_ELLIPTICAL == getFillGradient().getStyle())
-			{
-				aUnitPolygon = basegfx::tools::createPolygonFromCircle(
-                    basegfx::B2DPoint(0,0), 1);
-			}
-			else if(attribute::GRADIENTSTYLE_LINEAR == maFillGradient.getStyle())
-			{
-				aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(0, 0, 1, 1));
-			}
-			else
-			{
-				aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1, -1, 1, 1));
-			}
+            switch(getFillGradient().getStyle())
+            {
+                case attribute::GRADIENTSTYLE_RADIAL:
+                case attribute::GRADIENTSTYLE_ELLIPTICAL:
+                {
+                    aUnitPolygon = basegfx::tools::createPolygonFromCircle(basegfx::B2DPoint(0.0, 0.0), 1.0);
+                    break;
+                }
+                default: // GRADIENTSTYLE_LINEAR, attribute::GRADIENTSTYLE_AXIAL, attribute::GRADIENTSTYLE_SQUARE, attribute::GRADIENTSTYLE_RECT
+                {
+                    aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1.0, -1.0, 1.0, 1.0));
+                    break;
+                }
+            }
 
             // get the transform matrices and colors (where colors
             // will have one more entry that matrices)
-			std::vector< basegfx::B2DHomMatrix > aMatrices;
-			std::vector< basegfx::BColor > aColors;
-            generateMatricesAndColors(aMatrices, aColors);
+            std::vector< drawinglayer::texture::B2DHomMatrixAndBColor > aEntries;
+            basegfx::BColor aOutmostColor;
+
+            generateMatricesAndColors(aEntries, aOutmostColor);
 
             if(bOverlapping)
             {
-                return createOverlappingFill(aMatrices, aColors, aUnitPolygon);
+                return createOverlappingFill(aEntries, aOutmostColor, aUnitPolygon);
             }
             else
             {
-                return createNonOverlappingFill(aMatrices, aColors, aUnitPolygon);
+                return createNonOverlappingFill(aEntries, aOutmostColor, aUnitPolygon);
             }
         }
 
@@ -248,7 +252,9 @@ namespace drawinglayer
 
             if(!getFillGradient().isDefault())
             {
-        		return createFill(true);
+                static bool bOverlapping(true); // allow to test non-overlapping in the debugger
+
+        		return createFill(bOverlapping);
             }
             else
             {

Modified: incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelpergradient.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelpergradient.cxx?rev=1392807&r1=1392806&r2=1392807&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelpergradient.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclhelpergradient.cxx Tue Oct  2 09:23:25 2012
@@ -63,86 +63,78 @@ namespace drawinglayer
 		void impDrawGradientToOutDevSimple(
 			OutputDevice& rOutDev,
 			const basegfx::B2DPolyPolygon& rTargetForm,
-			const ::std::vector< basegfx::B2DHomMatrix >& rMatrices,
-			const ::std::vector< basegfx::BColor >& rColors,
-			const basegfx::B2DPolygon& rUnitPolygon)
+            const std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries,
+            const basegfx::BColor& rOutmostColor,
+            const basegfx::B2DPolygon& rUnitPolygon)
 		{
 			rOutDev.SetLineColor();
-
-			for(sal_uInt32 a(0L); a < rColors.size(); a++)
-			{
-				// set correct color
-				const basegfx::BColor aFillColor(rColors[a]);
-				rOutDev.SetFillColor(Color(aFillColor));
-
-				if(a)
-				{
-					if(a - 1L < static_cast< sal_uInt32 >(rMatrices.size()))
-					{
-						basegfx::B2DPolygon aNewPoly(rUnitPolygon);
-						aNewPoly.transform(rMatrices[a - 1L]);
-						rOutDev.DrawPolygon(aNewPoly);
-					}
-				}
-				else
-				{
-					rOutDev.DrawPolyPolygon(rTargetForm);
-				}
-			}
+			rOutDev.SetFillColor(Color(rOutmostColor));
+			rOutDev.DrawPolyPolygon(rTargetForm);
+            const sal_uInt32 nCount(rEntries.size());
+
+            for(sal_uInt32 a(0); a < nCount; a++)
+            {
+                // create part polygon
+                basegfx::B2DPolygon aNewPoly(rUnitPolygon);
+
+                aNewPoly.transform(rEntries[a].maB2DHomMatrix);
+
+                // create solid fill
+                rOutDev.SetFillColor(Color(rEntries[a].maBColor));
+                rOutDev.DrawPolygon(aNewPoly);
+            }
 		}
 
 		void impDrawGradientToOutDevComplex(
 			OutputDevice& rOutDev,
 			const basegfx::B2DPolyPolygon& rTargetForm,
-			const ::std::vector< basegfx::B2DHomMatrix >& rMatrices,
-			const ::std::vector< basegfx::BColor >& rColors,
+            const std::vector< drawinglayer::texture::B2DHomMatrixAndBColor >& rEntries,
+            const basegfx::BColor& rOutmostColor,
 			const basegfx::B2DPolygon& rUnitPolygon)
 		{
 			PolyPolygon aVclTargetForm(rTargetForm);
 			::std::vector< Polygon > aVclPolygons;
+            const sal_uInt32 nCount(rEntries.size());
 			sal_uInt32 a;
 
+            // reserve when possible
+            aVclPolygons.reserve(nCount);
+
 			// remember and set to XOR
 			rOutDev.SetLineColor();
 			rOutDev.Push(PUSH_RASTEROP);
 			rOutDev.SetRasterOp(ROP_XOR);
 
 			// draw gradient PolyPolygons
-			for(a = 0L; a < rMatrices.size(); a++)
+			for(a = 0; a < nCount; a++)
 			{
 				// create polygon and remember
 				basegfx::B2DPolygon aNewPoly(rUnitPolygon);
-				aNewPoly.transform(rMatrices[a]);
+				aNewPoly.transform(rEntries[a].maB2DHomMatrix);
 				aVclPolygons.push_back(Polygon(aNewPoly));
 
-				// set correct color
-				if(rColors.size() > a)
-				{
-					const basegfx::BColor aFillColor(rColors[a]);
-					rOutDev.SetFillColor(Color(aFillColor));
-				}
-
 				// create vcl PolyPolygon and draw it
 				if(a)
 				{
-					PolyPolygon aVclPolyPoly(aVclPolygons[a - 1L]);
+					rOutDev.SetFillColor(Color(rEntries[a - 1].maBColor));
+					PolyPolygon aVclPolyPoly(aVclPolygons[a - 1]);
 					aVclPolyPoly.Insert(aVclPolygons[a]);
 					rOutDev.DrawPolyPolygon(aVclPolyPoly);
 				}
 				else
 				{
+					rOutDev.SetFillColor(Color(rOutmostColor));
 					PolyPolygon aVclPolyPoly(aVclTargetForm);
-					aVclPolyPoly.Insert(aVclPolygons[0L]);
+					aVclPolyPoly.Insert(aVclPolygons[0]);
 					rOutDev.DrawPolyPolygon(aVclPolyPoly);
 				}
 			}
 
 			// draw last poly in last color
-			if(rColors.size())
+			if(nCount)
 			{
-				const basegfx::BColor aFillColor(rColors[rColors.size() - 1L]);
-				rOutDev.SetFillColor(Color(aFillColor));
-				rOutDev.DrawPolygon(aVclPolygons[aVclPolygons.size() - 1L]);
+				rOutDev.SetFillColor(Color(rEntries[nCount - 1].maBColor));
+				rOutDev.DrawPolygon(aVclPolygons[aVclPolygons.size() - 1]);
 			}
 
 			// draw object form in black and go back to XOR
@@ -152,36 +144,30 @@ namespace drawinglayer
 			rOutDev.SetRasterOp(ROP_XOR);
 
 			// draw gradient PolyPolygons again
-			for(a = 0L; a < rMatrices.size(); a++)
+			for(a = 0; a < nCount; a++)
 			{
-				// set correct color
-				if(rColors.size() > a)
-				{
-					const basegfx::BColor aFillColor(rColors[a]);
-					rOutDev.SetFillColor(Color(aFillColor));
-				}
-
 				// create vcl PolyPolygon and draw it
 				if(a)
 				{
-					PolyPolygon aVclPolyPoly(aVclPolygons[a - 1L]);
+					rOutDev.SetFillColor(Color(rEntries[a - 1].maBColor));
+					PolyPolygon aVclPolyPoly(aVclPolygons[a - 1]);
 					aVclPolyPoly.Insert(aVclPolygons[a]);
 					rOutDev.DrawPolyPolygon(aVclPolyPoly);
 				}
 				else
 				{
+					rOutDev.SetFillColor(Color(rOutmostColor));
 					PolyPolygon aVclPolyPoly(aVclTargetForm);
-					aVclPolyPoly.Insert(aVclPolygons[0L]);
+					aVclPolyPoly.Insert(aVclPolygons[0]);
 					rOutDev.DrawPolyPolygon(aVclPolyPoly);
 				}
 			}
 
 			// draw last poly in last color
-			if(rColors.size())
+			if(nCount)
 			{
-				const basegfx::BColor aFillColor(rColors[rColors.size() - 1L]);
-				rOutDev.SetFillColor(Color(aFillColor));
-				rOutDev.DrawPolygon(aVclPolygons[aVclPolygons.size() - 1L]);
+				rOutDev.SetFillColor(Color(rEntries[nCount - 1].maBColor));
+				rOutDev.DrawPolygon(aVclPolygons[aVclPolygons.size() - 1]);
 			}
 
 			// reset drawmode
@@ -202,8 +188,8 @@ namespace drawinglayer
 		double fBorder, double fAngle, double fOffsetX, double fOffsetY, bool bSimple)
 	{
 		const basegfx::B2DRange aOutlineRange(basegfx::tools::getRange(rTargetForm));
-		::std::vector< basegfx::B2DHomMatrix > aMatrices;
-		::std::vector< basegfx::BColor > aColors;
+        std::vector< drawinglayer::texture::B2DHomMatrixAndBColor > aEntries;
+        basegfx::BColor aOutmostColor;
 		basegfx::B2DPolygon aUnitPolygon;
 
 		// make sure steps is not too high/low
@@ -215,63 +201,57 @@ namespace drawinglayer
 			case attribute::GRADIENTSTYLE_LINEAR:
 			{
 				texture::GeoTexSvxGradientLinear aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fAngle);
-				aGradient.appendTransformations(aMatrices);
-				aGradient.appendColors(aColors);
-                aUnitPolygon = basegfx::tools::createUnitPolygon();
+				aGradient.appendTransformationsAndColors(aEntries, aOutmostColor);
+                aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1, -1, 1, 1));
 				break;
 			}
 			case attribute::GRADIENTSTYLE_AXIAL:
 			{
 				texture::GeoTexSvxGradientAxial aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fAngle);
-				aGradient.appendTransformations(aMatrices);
-				aGradient.appendColors(aColors);
+				aGradient.appendTransformationsAndColors(aEntries, aOutmostColor);
                 aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1, -1, 1, 1));
 				break;
 			}
 			case attribute::GRADIENTSTYLE_RADIAL:
 			{
 				texture::GeoTexSvxGradientRadial aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetY);
-				aGradient.appendTransformations(aMatrices);
-				aGradient.appendColors(aColors);
+				aGradient.appendTransformationsAndColors(aEntries, aOutmostColor);
                 aUnitPolygon = basegfx::tools::createPolygonFromCircle(basegfx::B2DPoint(0,0), 1);
 				break;
 			}
 			case attribute::GRADIENTSTYLE_ELLIPTICAL:
 			{
 				texture::GeoTexSvxGradientElliptical aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetX, fAngle);
-				aGradient.appendTransformations(aMatrices);
-				aGradient.appendColors(aColors);
+				aGradient.appendTransformationsAndColors(aEntries, aOutmostColor);
                 aUnitPolygon = basegfx::tools::createPolygonFromCircle(basegfx::B2DPoint(0,0), 1);
 				break;
 			}
 			case attribute::GRADIENTSTYLE_SQUARE:
 			{
 				texture::GeoTexSvxGradientSquare aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetX, fAngle);
-				aGradient.appendTransformations(aMatrices);
-				aGradient.appendColors(aColors);
+				aGradient.appendTransformationsAndColors(aEntries, aOutmostColor);
                 aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1, -1, 1, 1));
 				break;
 			}
 			case attribute::GRADIENTSTYLE_RECT:
 			{
 				texture::GeoTexSvxGradientRect aGradient(aOutlineRange, rStart, rEnd, nSteps, fBorder, fOffsetX, fOffsetX, fAngle);
-				aGradient.appendTransformations(aMatrices);
-				aGradient.appendColors(aColors);
+				aGradient.appendTransformationsAndColors(aEntries, aOutmostColor);
                 aUnitPolygon = basegfx::tools::createPolygonFromRect(basegfx::B2DRange(-1, -1, 1, 1));
 				break;
 			}
 		}
 
 		// paint them with mask using the XOR method
-		if(aMatrices.size())
+		if(aEntries.size())
 		{
 			if(bSimple)
 			{
-				impDrawGradientToOutDevSimple(rOutDev, rTargetForm, aMatrices, aColors, aUnitPolygon);
+				impDrawGradientToOutDevSimple(rOutDev, rTargetForm, aEntries, aOutmostColor, aUnitPolygon);
 			}
 			else
 			{
-				impDrawGradientToOutDevComplex(rOutDev, rTargetForm, aMatrices, aColors, aUnitPolygon);
+				impDrawGradientToOutDevComplex(rOutDev, rTargetForm, aEntries, aOutmostColor, aUnitPolygon);
 			}
 		}
 	}

Modified: incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx?rev=1392807&r1=1392806&r2=1392807&view=diff
==============================================================================
--- incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx (original)
+++ incubator/ooo/trunk/main/drawinglayer/source/processor2d/vclprocessor2d.cxx Tue Oct  2 09:23:25 2012
@@ -605,10 +605,12 @@ namespace drawinglayer
 				}
 				else
 				{
-					impDrawGradientToOutDev(
+                    static bool bSimple = false; // allow testing simple paint in debugger
+					
+                    impDrawGradientToOutDev(
 						*mpOutputDevice, aLocalPolyPolygon, rGradient.getStyle(), rGradient.getSteps(),
 						aStartColor, aEndColor, rGradient.getBorder(),
-						rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), false);
+						rGradient.getAngle(), rGradient.getOffsetX(), rGradient.getOffsetY(), bSimple);
 				}
 			}
 		}