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 2011/12/01 17:26:53 UTC

svn commit: r1209140 [2/11] - in /incubator/ooo/branches/alg/svgreplacement/main: ./ basegfx/inc/basegfx/matrix/ basegfx/inc/basegfx/polygon/ basegfx/source/polygon/ cppcanvas/source/mtfrenderer/ drawinglayer/ drawinglayer/inc/drawinglayer/primitive2d/...

Added: incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx?rev=1209140&view=auto
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx (added)
+++ incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/drawinglayeruno/xprimitive2drenderer.cxx Thu Dec  1 16:25:17 2011
@@ -0,0 +1,223 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http:\\www.apache.org\licenses\LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <com/sun/star/graphic/XPrimitive2DRenderer.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <cppuhelper/implbase2.hxx>
+#include <com/sun/star/xml/sax/XParser.hpp>
+#include <com/sun/star/xml/sax/InputSource.hpp>
+#include <comphelper/processfactory.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+#include <basegfx/numeric/ftools.hxx>
+#include <vcl/bitmapex.hxx>
+#include <drawinglayer/tools/converters.hxx>
+#include <vcl/canvastools.hxx>
+#include <com/sun/star/geometry/RealRectangle2D.hpp>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace ::com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+    namespace unorenderer
+    {
+        class XPrimitive2DRenderer : public ::cppu::WeakAggImplHelper2< graphic::XPrimitive2DRenderer, lang::XServiceInfo >
+        {
+        private:
+            XPrimitive2DRenderer(const XPrimitive2DRenderer&);
+            XPrimitive2DRenderer& operator=(const XPrimitive2DRenderer&);
+
+        protected:
+        public:
+            XPrimitive2DRenderer();
+            virtual ~XPrimitive2DRenderer();
+
+            // XPrimitive2DRenderer
+            virtual uno::Reference< rendering::XBitmap > SAL_CALL rasterize( 
+                const uno::Sequence< uno::Reference< graphic::XPrimitive2D > >& Primitive2DSequence, 
+                const uno::Sequence< beans::PropertyValue >& aViewInformationSequence, 
+                ::sal_uInt32 DPI_X, 
+                ::sal_uInt32 DPI_Y, 
+                const ::com::sun::star::geometry::RealRectangle2D& Range,
+                ::sal_uInt32 MaximumQuadraticPixels) throw (uno::RuntimeException);
+
+            // XServiceInfo
+            virtual rtl::OUString SAL_CALL getImplementationName() throw(uno::RuntimeException);
+            virtual ::sal_Bool SAL_CALL supportsService(const rtl::OUString&) throw(uno::RuntimeException);
+            virtual uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames() throw(uno::RuntimeException);
+        };
+	} // end of namespace unorenderer
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// uno functions
+
+namespace drawinglayer
+{
+    namespace unorenderer
+    {
+        uno::Sequence< rtl::OUString > XPrimitive2DRenderer_getSupportedServiceNames()
+        {
+	        static rtl::OUString aServiceName(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.graphic.Primitive2DTools" ) );
+	        static uno::Sequence< rtl::OUString > aServiceNames( &aServiceName, 1 );
+
+            return( aServiceNames );
+        }
+
+        rtl::OUString XPrimitive2DRenderer_getImplementationName()
+        {
+	        return rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "drawinglayer::unorenderer::XPrimitive2DRenderer" ) );
+        }
+
+        uno::Reference< uno::XInterface > SAL_CALL XPrimitive2DRenderer_createInstance(const uno::Reference< lang::XMultiServiceFactory >&)
+        {
+	        return static_cast< ::cppu::OWeakObject* >(new XPrimitive2DRenderer);
+        }
+	} // end of namespace unorenderer
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+    namespace unorenderer
+    {
+        XPrimitive2DRenderer::XPrimitive2DRenderer() 
+        {
+        }
+
+        XPrimitive2DRenderer::~XPrimitive2DRenderer()
+        {
+        }
+
+        uno::Reference< rendering::XBitmap > XPrimitive2DRenderer::rasterize( 
+            const uno::Sequence< uno::Reference< graphic::XPrimitive2D > >& Primitive2DSequence, 
+            const uno::Sequence< beans::PropertyValue >& aViewInformationSequence, 
+            ::sal_uInt32 DPI_X, 
+            ::sal_uInt32 DPI_Y, 
+            const ::com::sun::star::geometry::RealRectangle2D& Range,
+            ::sal_uInt32 MaximumQuadraticPixels) throw (uno::RuntimeException)
+        {
+            uno::Reference< rendering::XBitmap > XBitmap;
+            
+            if(Primitive2DSequence.hasElements())
+            {
+                const basegfx::B2DRange aRange(Range.X1, Range.Y1, Range.X2, Range.Y2);
+                const double fWidth(aRange.getWidth());
+                const double fHeight(aRange.getHeight());
+
+                if(basegfx::fTools::more(fWidth, 0.0) && basegfx::fTools::more(fHeight, 0.0))
+                {
+                    if(0 == DPI_X)
+                    {
+                        DPI_X = 75;
+                    }
+
+                    if(0 == DPI_Y)
+                    {
+                        DPI_Y = 75;
+                    }
+
+                    if(0 == MaximumQuadraticPixels)
+                    {
+                        MaximumQuadraticPixels = 500000;
+                    }
+
+                    const geometry::ViewInformation2D aViewInformation2D(aViewInformationSequence);
+                    const double fFactor100th_mmToInch(2.54/1000.0);
+                    const sal_uInt32 nDiscreteWidth(basegfx::fround((fWidth * fFactor100th_mmToInch) * DPI_X));
+                    const sal_uInt32 nDiscreteHeight(basegfx::fround((fHeight * fFactor100th_mmToInch) * DPI_Y));
+
+                    basegfx::B2DHomMatrix aEmbedding(
+                        basegfx::tools::createTranslateB2DHomMatrix(
+                            -aRange.getMinX(),
+                            -aRange.getMinY()));
+                    
+                    aEmbedding.scale(
+                        nDiscreteWidth / fWidth,
+                        nDiscreteHeight / fHeight);
+
+                    const primitive2d::Primitive2DReference xEmbedRef(
+                        new primitive2d::TransformPrimitive2D(
+                            aEmbedding,
+                            Primitive2DSequence));
+                    const primitive2d::Primitive2DSequence xEmbedSeq(&xEmbedRef, 1);
+
+                    BitmapEx aBitmapEx(
+                        tools::convertToBitmapEx(
+                            xEmbedSeq, 
+                            aViewInformation2D,
+                            nDiscreteWidth,
+                            nDiscreteHeight,
+                            MaximumQuadraticPixels));
+
+                    if(!aBitmapEx.IsEmpty())
+                    {
+                        const uno::Reference< rendering::XGraphicDevice > xGraphicDevice;
+                    
+                        aBitmapEx.SetPrefMapMode(MapMode(MAP_100TH_MM));
+                        aBitmapEx.SetPrefSize(Size(basegfx::fround(fWidth), basegfx::fround(fHeight)));
+                        XBitmap = vcl::unotools::xBitmapFromBitmapEx(xGraphicDevice, aBitmapEx);
+                    }
+                }
+            }
+
+            return XBitmap;
+        }
+
+        rtl::OUString SAL_CALL XPrimitive2DRenderer::getImplementationName() throw(uno::RuntimeException)
+        {
+	        return(XPrimitive2DRenderer_getImplementationName());
+        }
+
+        sal_Bool SAL_CALL XPrimitive2DRenderer::supportsService(const rtl::OUString& rServiceName) throw(uno::RuntimeException)
+        {
+	        const uno::Sequence< rtl::OUString > aServices(XPrimitive2DRenderer_getSupportedServiceNames());
+
+            for(sal_Int32 nService(0); nService < aServices.getLength(); nService++)
+	        {
+		        if(rServiceName == aServices[nService])
+                {
+			        return sal_True;
+                }
+	        }
+
+            return sal_False;
+        }
+
+        uno::Sequence< rtl::OUString > SAL_CALL XPrimitive2DRenderer::getSupportedServiceNames() throw(uno::RuntimeException)
+        {
+	        return XPrimitive2DRenderer_getSupportedServiceNames();
+        }
+
+	} // end of namespace unorenderer
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof

Modified: incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/baseprimitive2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/baseprimitive2d.cxx?rev=1209140&r1=1209139&r2=1209140&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/baseprimitive2d.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/baseprimitive2d.cxx Thu Dec  1 16:25:17 2011
@@ -115,6 +115,27 @@ namespace drawinglayer
 {
 	namespace primitive2d
 	{
+        // convert helper stl vector of primitives to Primitive2DSequence
+        Primitive2DSequence Primitive2DVectorToPrimitive2DSequence(const Primitive2DVector& rSource, bool bInvert)
+        {
+            const sal_uInt32 nSize(rSource.size());
+            Primitive2DSequence aRetval;
+        
+            aRetval.realloc(nSize);
+
+            for(sal_uInt32 a(0); a < nSize; a++)
+            {
+                aRetval[bInvert ? nSize - 1 - a : a] = rSource[a];
+            }
+
+            // all entries taken over to Uno References as owners. To avoid
+            // errors with users of this mechanism to delete pointers to BasePrimitive2D
+            // itself, clear given vector
+            const_cast< Primitive2DVector& >(rSource).clear();
+
+            return aRetval;
+        }
+
 		// get B2DRange from a given Primitive2DReference
 		basegfx::B2DRange getB2DRangeFromPrimitive2DReference(const Primitive2DReference& rCandidate, const geometry::ViewInformation2D& aViewInformation)
 		{

Modified: incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/graphicprimitive2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/graphicprimitive2d.cxx?rev=1209140&r1=1209139&r2=1209140&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/graphicprimitive2d.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/graphicprimitive2d.cxx Thu Dec  1 16:25:17 2011
@@ -27,7 +27,6 @@
 #include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
 #include <drawinglayer/animation/animationtiming.hxx>
 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
-#include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
 #include <drawinglayer/primitive2d/animatedprimitive2d.hxx>
 #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
@@ -258,9 +257,9 @@ namespace drawinglayer
 		        aSuppressGraphicAttr.SetCrop(0, 0, 0, 0);
 		        aSuppressGraphicAttr.SetRotation(0);
 		        aSuppressGraphicAttr.SetMirrorFlags(0);
-		        
-                const GraphicObject&    rGraphicObject = getGraphicObject();
-                const Graphic           aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr));
+
+                const GraphicObject& rGraphicObject = getGraphicObject();
+                const Graphic aTransformedGraphic(rGraphicObject.GetTransformedGraphic(&aSuppressGraphicAttr));
 
                 switch(aTransformedGraphic.GetType())
 				{
@@ -742,44 +741,34 @@ namespace drawinglayer
                         else
                         {
 #endif // USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
-	                        // create MetafilePrimitive2D
+                            // create MetafilePrimitive2D
                             const GDIMetaFile& rMetafile = aTransformedGraphic.GetGDIMetaFile();
+      
+                            xPrimitive = Primitive2DReference(
+                                new MetafilePrimitive2D(
+                                    aTransform,
+                                    rMetafile));
+
+                            // #i100357# find out if clipping is needed for this primitive. Unfortunately,
+                            // there exist Metafiles who's content is bigger than the proposed PrefSize set
+                            // at them. This is an error, but we need to work around this
+                            const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
+                            const Size aMetaFileRealSize(
+                                const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
+                                    *Application::GetDefaultDevice()).GetSize());
+
+                            if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
+                                || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
+                            {
+                                // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
+                                const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1);
+                                basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
+                                aMaskPolygon.transform(aTransform);
 
-                            if( aTransformedGraphic.IsRenderGraphic() )
-                            {
-                                xPrimitive = Primitive2DReference(
-                                    new RenderGraphicPrimitive2D(                                        
-                                        static_cast< MetaRenderGraphicAction* >(rMetafile.GetAction(0))->GetRenderGraphic(),
-                                        aTransform));
-                            }
-                            else
-                            {
                                 xPrimitive = Primitive2DReference(
-                                    new MetafilePrimitive2D(
-                                        aTransform,
-                                        rMetafile));
-
-                                // #i100357# find out if clipping is needed for this primitive. Unfortunately,
-                                // there exist Metafiles who's content is bigger than the proposed PrefSize set
-                                // at them. This is an error, but we need to work around this
-                                const Size aMetaFilePrefSize(rMetafile.GetPrefSize());
-                                const Size aMetaFileRealSize(
-                                    const_cast< GDIMetaFile& >(rMetafile).GetBoundRect(
-                                        *Application::GetDefaultDevice()).GetSize());
-
-                                if(aMetaFileRealSize.getWidth() > aMetaFilePrefSize.getWidth()
-                                    || aMetaFileRealSize.getHeight() > aMetaFilePrefSize.getHeight())
-                                {
-                                    // clipping needed. Embed to MaskPrimitive2D. Create childs and mask polygon
-                                    const primitive2d::Primitive2DSequence aChildContent(&xPrimitive, 1);
-                                    basegfx::B2DPolygon aMaskPolygon(basegfx::tools::createUnitPolygon());
-                                    aMaskPolygon.transform(aTransform);
-
-                                    xPrimitive = Primitive2DReference(
-                                        new MaskPrimitive2D(
-                                            basegfx::B2DPolyPolygon(aMaskPolygon),
-                                            aChildContent));
-                                }
+                                    new MaskPrimitive2D(
+                                        basegfx::B2DPolyPolygon(aMaskPolygon),
+                                        aChildContent));
                             }
 #ifdef USE_DEBUG_CODE_TO_TEST_METAFILE_DECOMPOSE
                         }

Modified: incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/metafileprimitive2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/metafileprimitive2d.cxx?rev=1209140&r1=1209139&r2=1209140&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/metafileprimitive2d.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/metafileprimitive2d.cxx Thu Dec  1 16:25:17 2011
@@ -59,7 +59,6 @@
 #include <drawinglayer/primitive2d/textlineprimitive2d.hxx>
 #include <drawinglayer/primitive2d/textstrikeoutprimitive2d.hxx>
 #include <drawinglayer/primitive2d/epsprimitive2d.hxx>
-#include <drawinglayer/primitive2d/rendergraphicprimitive2d.hxx>
 #include <numeric>
 
 //////////////////////////////////////////////////////////////////////////////
@@ -3065,33 +3064,6 @@ namespace
 
                     break;
                 }
-                case META_RENDERGRAPHIC_ACTION :
-                {
-                    const MetaRenderGraphicAction* pA = (const MetaRenderGraphicAction*)pAction;
-					const Rectangle aRectangle(pA->GetPoint(), pA->GetSize());
-
-					if(!aRectangle.IsEmpty())
-                    {
-						// create object transform
-						basegfx::B2DHomMatrix aObjectTransform;
-
-						aObjectTransform.set(0, 0, aRectangle.GetWidth());
-						aObjectTransform.set(1, 1, aRectangle.GetHeight());
-						aObjectTransform.set(0, 2, aRectangle.Left());
-						aObjectTransform.set(1, 2, aRectangle.Top());
-
-						// add current transformation
-						aObjectTransform = rPropertyHolders.Current().getTransformation() * aObjectTransform;
-
-						// embed using EpsPrimitive
-						rTargetHolders.Current().append(
-							new drawinglayer::primitive2d::RenderGraphicPrimitive2D(
-								pA->GetRenderGraphic(),
-								aObjectTransform ) );
-					}
-
-					break;
-                }
                 case META_COMMENT_ACTION :
                 {
 					/** CHECKED, WORKS WELL */

Added: incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx?rev=1209140&view=auto
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx (added)
+++ incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/svggradientprimitive2d.cxx Thu Dec  1 16:25:17 2011
@@ -0,0 +1,1249 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http:\\www.apache.org\licenses\LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/svggradientprimitive2d.hxx>
+#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
+#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx>
+#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
+#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
+#include <basegfx/matrix/b2dhommatrixtools.hxx>
+#include <basegfx/polygon/b2dpolygontools.hxx>
+#include <basegfx/polygon/b2dpolygon.hxx>
+#include <drawinglayer/primitive2d/transparenceprimitive2d.hxx>
+#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
+#include <drawinglayer/primitive2d/maskprimitive2d.hxx>
+#include <drawinglayer/geometry/viewinformation2d.hxx>
+
+//////////////////////////////////////////////////////////////////////////////
+
+using namespace com::sun::star;
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+	namespace primitive2d
+	{
+		Primitive2DSequence SvgGradientHelper::createSingleGradientEntryFill() const
+		{
+            const SvgGradientEntryVector& rEntries = getGradientEntries();
+            const sal_uInt32 nCount(rEntries.size());
+            Primitive2DSequence xRetval;
+
+            if(nCount)
+            {
+                const SvgGradientEntry& rSingleEntry = rEntries[nCount - 1];
+                const double fOpacity(rSingleEntry.getOpacity());
+
+                if(fOpacity > 0.0)
+                {
+    			    Primitive2DReference xRef(
+                        new PolyPolygonColorPrimitive2D(
+                            getPolyPolygon(), 
+                            rSingleEntry.getColor()));
+
+                    if(fOpacity < 1.0)
+                    {
+            		    const Primitive2DSequence aContent(&xRef, 1);
+    				    
+                        xRef = Primitive2DReference(
+                            new UnifiedTransparencePrimitive2D(
+                                aContent, 
+                                1.0 - fOpacity));
+                    }
+
+                    xRetval = Primitive2DSequence(&xRef, 1);
+                }
+            }
+            else
+            {
+                OSL_ENSURE(false, "Single gradient entry construction without entry (!)");
+            }
+
+            return xRetval;
+        }
+
+        void SvgGradientHelper::checkPreconditions()
+        {
+            mbPreconditionsChecked = true;
+            const SvgGradientEntryVector& rEntries = getGradientEntries();
+
+            if(rEntries.empty())
+            {
+                // no fill at all
+            }
+            else
+            {
+                const sal_uInt32 nCount(rEntries.size());
+
+                if(1 == nCount)
+                {
+                    // fill with single existing color
+                    setSingleEntry();
+                }
+                else
+                {
+                    // sort maGradientEntries when more than one
+                    std::sort(maGradientEntries.begin(), maGradientEntries.end());
+                    
+                    // gradient with at least two colors
+                    bool bAllInvisible(true);
+
+                    for(sal_uInt32 a(0); a < nCount; a++)
+                    {
+                        const SvgGradientEntry& rCandidate = rEntries[a];
+
+                        if(basegfx::fTools::equalZero(rCandidate.getOpacity()))
+                        {
+                            // invisible
+                            mbFullyOpaque = false;
+                        }
+                        else if(basegfx::fTools::equal(rCandidate.getOpacity(), 1.0))
+                        {
+                            // completely opaque
+                            bAllInvisible = false;
+                        }
+                        else
+                        {
+                            // opacity
+                            bAllInvisible = false;
+                            mbFullyOpaque = false;
+                        }
+                    }
+
+                    if(bAllInvisible)
+                    {
+                        // all invisible, nothing to do
+                    }
+                    else
+                    {
+                        const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+
+                        if(aPolyRange.isEmpty())
+                        {
+                            // no range to fill, nothing to do
+                        }
+                        else
+                        {
+                            const double fPolyWidth(aPolyRange.getWidth());
+                            const double fPolyHeight(aPolyRange.getHeight());
+
+                            if(basegfx::fTools::equalZero(fPolyWidth) || basegfx::fTools::equalZero(fPolyHeight))
+                            {
+                                // no width/height to fill, nothing to do
+                            }
+                            else
+                            {
+                                mbCreatesContent = true;
+                            }
+                        }
+                    }
+                }
+            }
+        }
+
+        double SvgGradientHelper::createRun(
+            Primitive2DVector& rTargetColor,
+            Primitive2DVector& rTargetOpacity, 
+            double fPos,
+            double fMax,
+            const SvgGradientEntryVector& rEntries,
+            sal_Int32 nOffset) const
+        {
+            const sal_uInt32 nCount(rEntries.size());
+
+            if(nCount)
+            {
+                const SvgGradientEntry& rStart = rEntries[0];
+                const bool bCreateStartPad(fPos < 0.0 && Spread_pad == getSpreadMethod());
+                const bool bCreateStartFill(rStart.getOffset() > 0.0);
+                sal_uInt32 nIndex(0);
+
+                if(bCreateStartPad || bCreateStartFill)
+                {
+                    const SvgGradientEntry aTemp(bCreateStartPad ? fPos : 0.0, rStart.getColor(), rStart.getOpacity());
+                
+                    createAtom(rTargetColor, rTargetOpacity, aTemp, rStart, nOffset);
+                    fPos = rStart.getOffset();
+                }
+
+                while(fPos < 1.0 && nIndex + 1 < nCount)
+                {
+                    const SvgGradientEntry& rCandidateA = rEntries[nIndex++];
+                    const SvgGradientEntry& rCandidateB = rEntries[nIndex];
+                        
+                    createAtom(rTargetColor, rTargetOpacity, rCandidateA, rCandidateB, nOffset);
+                    fPos = rCandidateB.getOffset();
+                }
+
+                const SvgGradientEntry& rEnd = rEntries[nCount - 1];
+                const bool bCreateEndPad(fPos < fMax && Spread_pad == getSpreadMethod());
+                const bool bCreateEndFill(rEnd.getOffset() < 1.0);
+
+                if(bCreateEndPad || bCreateEndFill)
+                {
+                    fPos = bCreateEndPad ? fMax : 1.0;
+                    const SvgGradientEntry aTemp(fPos, rEnd.getColor(), rEnd.getOpacity());
+                
+                    createAtom(rTargetColor, rTargetOpacity, rEnd, aTemp, nOffset);
+                }
+            }
+            else
+            {
+                OSL_ENSURE(false, "GradientAtom creation without ColorStops (!)");
+                fPos = fMax;
+            }
+
+            return fPos;
+        }
+
+        Primitive2DSequence SvgGradientHelper::createResult(
+            const Primitive2DVector& rTargetColor,
+            const Primitive2DVector& rTargetOpacity,
+            const basegfx::B2DHomMatrix& rUnitGradientToObject,
+            bool bInvert) const
+        {
+            Primitive2DSequence xRetval;
+            const Primitive2DSequence aTargetColorEntries(Primitive2DVectorToPrimitive2DSequence(rTargetColor, bInvert));
+            const Primitive2DSequence aTargetOpacityEntries(Primitive2DVectorToPrimitive2DSequence(rTargetOpacity, bInvert));
+
+            if(aTargetColorEntries.hasElements())
+            {
+    			Primitive2DReference xRefContent;
+                    
+                if(aTargetOpacityEntries.hasElements())
+                {
+        			const Primitive2DReference xRefOpacity = new TransparencePrimitive2D(
+                        aTargetColorEntries, 
+                        aTargetOpacityEntries);
+                        
+                    xRefContent = new TransformPrimitive2D(
+                        rUnitGradientToObject, 
+                        Primitive2DSequence(&xRefOpacity, 1));
+                }
+                else
+                {
+                    xRefContent = new TransformPrimitive2D(
+                        rUnitGradientToObject, 
+                        aTargetColorEntries);
+                }
+
+                xRefContent = new MaskPrimitive2D(
+                    getPolyPolygon(), 
+                    Primitive2DSequence(&xRefContent, 1));
+
+                xRetval = Primitive2DSequence(&xRefContent, 1);
+            }
+
+            return xRetval;
+        }
+
+		SvgGradientHelper::SvgGradientHelper(
+			const basegfx::B2DPolyPolygon& rPolyPolygon,
+            const SvgGradientEntryVector& rGradientEntries,
+            const basegfx::B2DPoint& rStart,
+            SpreadMethod aSpreadMethod,
+            double fOverlapping)
+		:	maPolyPolygon(rPolyPolygon),
+            maGradientEntries(rGradientEntries),
+            maStart(rStart),
+            maSpreadMethod(aSpreadMethod),
+            mfOverlapping(fOverlapping),
+            mbPreconditionsChecked(false),
+            mbCreatesContent(false),
+            mbSingleEntry(false),
+            mbFullyOpaque(true)
+		{
+		}
+
+		bool SvgGradientHelper::operator==(const SvgGradientHelper& rSvgGradientHelper) const
+		{
+			const SvgGradientHelper& rCompare = static_cast< const SvgGradientHelper& >(rSvgGradientHelper);
+
+			return (getPolyPolygon() == rCompare.getPolyPolygon()
+                && getGradientEntries() == rCompare.getGradientEntries()
+                && getStart() == rCompare.getStart()
+                && getSpreadMethod() == rCompare.getSpreadMethod()
+                && getOverlapping() == rCompare.getOverlapping());
+		}
+
+    } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+	namespace primitive2d
+	{
+        void SvgLinearGradientPrimitive2D::checkPreconditions()
+        {
+            // call parent
+            SvgGradientHelper::checkPreconditions();
+
+            if(getCreatesContent())
+            {
+                // Check Vector
+                const basegfx::B2DVector aVector(getEnd() - getStart());
+
+                if(basegfx::fTools::equalZero(aVector.getX()) && basegfx::fTools::equalZero(aVector.getY()))
+                {
+                    // fill with single color using last stop color
+                    setSingleEntry();
+                }
+            }
+        }
+
+        void SvgLinearGradientPrimitive2D::ensureGeometry(
+            basegfx::B2DPolyPolygon& rPolyPolygon,
+            const SvgGradientEntry& rFrom, 
+            const SvgGradientEntry& rTo,
+            sal_Int32 nOffset) const
+        {
+            if(!rPolyPolygon.count())
+            {
+                rPolyPolygon.append(
+                    basegfx::tools::createPolygonFromRect(
+                        basegfx::B2DRange(
+                            rFrom.getOffset() - getOverlapping() + nOffset, 
+                            0.0, 
+                            rTo.getOffset() + getOverlapping() + nOffset, 
+                            1.0)));
+            }
+        }
+
+        void SvgLinearGradientPrimitive2D::createAtom(
+            Primitive2DVector& rTargetColor,
+            Primitive2DVector& rTargetOpacity, 
+            const SvgGradientEntry& rFrom, 
+            const SvgGradientEntry& rTo,
+            sal_Int32 nOffset) const
+        {
+            // create gradient atom [rFrom.getOffset() .. rTo.getOffset()] with (rFrom.getOffset() > rTo.getOffset())
+            if(rFrom.getOffset() == rTo.getOffset())
+            {
+                OSL_ENSURE(false, "SvgGradient Atom creation with no step width (!)");
+            }
+            else
+            {
+                const bool bColorChange(rFrom.getColor() != rTo.getColor());
+                const bool bOpacityChange(rFrom.getOpacity() != rTo.getOpacity());
+                basegfx::B2DPolyPolygon aPolyPolygon;
+                                            
+                if(bColorChange)
+                {
+    		        rTargetColor.push_back(
+                        new SvgLinearAtomPrimitive2D(
+                            rFrom.getColor(), rFrom.getOffset() + nOffset,
+                            rTo.getColor(), rTo.getOffset() + nOffset,
+                            getOverlapping()));
+                }
+                else
+                {
+                    ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
+                    rTargetColor.push_back(
+                        new PolyPolygonColorPrimitive2D(
+                            aPolyPolygon, 
+                            rFrom.getColor()));
+                }
+
+                if(bOpacityChange)
+                {
+                    const double fTransFrom(1.0 - rFrom.getOpacity());
+                    const double fTransTo(1.0 - rTo.getOpacity());
+
+                    rTargetOpacity.push_back(
+                        new SvgLinearAtomPrimitive2D(
+                            basegfx::BColor(fTransFrom, fTransFrom, fTransFrom), rFrom.getOffset() + nOffset,
+                            basegfx::BColor(fTransTo,fTransTo, fTransTo), rTo.getOffset() + nOffset,
+                            getOverlapping()));
+                }
+                else if(!getFullyOpaque())
+                {
+                    const double fTransparence(1.0 - rFrom.getOpacity());
+
+                    ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
+                    rTargetOpacity.push_back(
+                        new PolyPolygonColorPrimitive2D(
+                            aPolyPolygon, 
+                            basegfx::BColor(fTransparence, fTransparence, fTransparence)));
+                }
+            }
+        }
+
+		Primitive2DSequence SvgLinearGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+		{
+            Primitive2DSequence xRetval;
+
+            if(!getPreconditionsChecked())
+            {
+                const_cast< SvgLinearGradientPrimitive2D* >(this)->checkPreconditions();
+            }
+
+            if(getSingleEntry())
+            {
+                // fill with last existing color
+                xRetval = createSingleGradientEntryFill();
+            }
+            else if(getCreatesContent())
+            {
+                // at least two color stops in range [0.0 .. 1.0], sorted, non-null vector, not completely
+                // invisible, width and height to fill are not empty
+                const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+                const double fPolyWidth(aPolyRange.getWidth());
+                const double fPolyHeight(aPolyRange.getHeight());
+
+                // create ObjectTransform based on polygon range
+                const basegfx::B2DHomMatrix aObjectTransform(
+                    basegfx::tools::createScaleTranslateB2DHomMatrix(
+                        fPolyWidth, fPolyHeight, 
+                        aPolyRange.getMinX(), aPolyRange.getMinY()));
+
+                // create unit transform from unit vector [0.0 .. 1.0] along the X-Axis to given 
+                // gradient vector defined by Start,End
+                const basegfx::B2DVector aVector(getEnd() - getStart());
+                const double fVectorLength(aVector.getLength());
+                basegfx::B2DHomMatrix aUnitGradientToGradient;
+
+                aUnitGradientToGradient.scale(fVectorLength, 1.0);
+                aUnitGradientToGradient.rotate(atan2(aVector.getY(), aVector.getX()));
+                aUnitGradientToGradient.translate(getStart().getX(), getStart().getY());
+
+                // create full transform from unit gradient coordinates to object coordinates
+                // including the SvgGradient transformation
+                basegfx::B2DHomMatrix aUnitGradientToObject(aObjectTransform * aUnitGradientToGradient);
+
+                // create inverse from it
+                basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject);
+                aObjectToUnitGradient.invert();
+
+                // back-transform polygon to unit gradient coordinates and get
+                // UnitRage. This is the range the gradient has to cover
+                basegfx::B2DPolyPolygon aUnitPoly(getPolyPolygon());
+                aUnitPoly.transform(aObjectToUnitGradient);
+                const basegfx::B2DRange aUnitRange(aUnitPoly.getB2DRange());
+
+                // prepare result vectors
+                Primitive2DVector aTargetColor;
+                Primitive2DVector aTargetOpacity;
+
+                if(basegfx::fTools::more(aUnitRange.getWidth(), 0.0))
+                {
+                    // add a pre-multiply to aUnitGradientToObject to allow
+                    // multiplication of the polygon(xl, 0.0, xr, 1.0)
+                    const basegfx::B2DHomMatrix aPreMultiply(
+                        basegfx::tools::createScaleTranslateB2DHomMatrix(
+                            1.0, aUnitRange.getHeight(), 0.0, aUnitRange.getMinY()));
+                    aUnitGradientToObject = aUnitGradientToObject * aPreMultiply;
+
+                    // create central run, may also already do all necessary when
+                    // Spread_pad is set as SpreadMethod and/or the range is smaller
+                    double fPos(createRun(aTargetColor, aTargetOpacity, aUnitRange.getMinX(), aUnitRange.getMaxX(), getGradientEntries(), 0));
+
+                    if(fPos < aUnitRange.getMaxX())
+                    {
+                        // can only happen when SpreadMethod is Spread_reflect or Spread_repeat,
+                        // else the start and end pads are already created and fPos == aUnitRange.getMaxX().
+                        // Its possible to express the repeated linear gradient by adding the
+                        // transformed central run. Crete it this way
+                        Primitive2DSequence aTargetColorEntries(Primitive2DVectorToPrimitive2DSequence(aTargetColor));
+                        Primitive2DSequence aTargetOpacityEntries(Primitive2DVectorToPrimitive2DSequence(aTargetOpacity));
+                        aTargetColor.clear();
+                        aTargetOpacity.clear();
+
+                        if(aTargetColorEntries.hasElements())
+                        {
+                            // add original central run as group primitive
+                            aTargetColor.push_back(new GroupPrimitive2D(aTargetColorEntries));
+                                
+                            if(aTargetOpacityEntries.hasElements())
+                            {
+                                aTargetOpacity.push_back(new GroupPrimitive2D(aTargetOpacityEntries));
+                            }
+
+                            // add negative runs
+                            fPos = 0.0;
+                            sal_Int32 nOffset(0);
+
+                            while(fPos > aUnitRange.getMinX())
+                            {
+                                fPos -= 1.0;
+                                nOffset++;
+
+                                basegfx::B2DHomMatrix aTransform;
+                                const bool bMirror(Spread_reflect == getSpreadMethod() && (nOffset % 2));
+
+                                if(bMirror)
+                                {
+                                    aTransform.scale(-1.0, 1.0);
+                                    aTransform.translate(fPos + 1.0, 0.0);
+                                }
+                                else
+                                {
+                                    aTransform.translate(fPos, 0.0);
+                                }
+
+                                aTargetColor.push_back(new TransformPrimitive2D(aTransform, aTargetColorEntries));
+                                
+                                if(aTargetOpacityEntries.hasElements())
+                                {
+                                    aTargetOpacity.push_back(new TransformPrimitive2D(aTransform, aTargetOpacityEntries));
+                                }
+                            }
+
+                            // add positive runs
+                            fPos = 1.0;
+                            nOffset = 1;
+
+                            while(fPos < aUnitRange.getMaxX())
+                            {
+                                basegfx::B2DHomMatrix aTransform;
+                                const bool bMirror(Spread_reflect == getSpreadMethod() && (nOffset % 2));
+
+                                if(bMirror)
+                                {
+                                    aTransform.scale(-1.0, 1.0);
+                                    aTransform.translate(fPos + 1.0, 0.0);
+                                }
+                                else
+                                {
+                                    aTransform.translate(fPos, 0.0);
+                                }
+
+                                aTargetColor.push_back(new TransformPrimitive2D(aTransform, aTargetColorEntries));
+                                
+                                if(aTargetOpacityEntries.hasElements())
+                                {
+                                    aTargetOpacity.push_back(new TransformPrimitive2D(aTransform, aTargetOpacityEntries));
+                                }
+
+                                fPos += 1.0;
+                                nOffset++;
+                            }
+                        }
+                    }
+                }
+
+                xRetval = createResult(aTargetColor, aTargetOpacity, aUnitGradientToObject);
+            }
+
+            return xRetval;
+		}
+
+		SvgLinearGradientPrimitive2D::SvgLinearGradientPrimitive2D(
+			const basegfx::B2DPolyPolygon& rPolyPolygon,
+            const SvgGradientEntryVector& rGradientEntries,
+            const basegfx::B2DPoint& rStart,
+            const basegfx::B2DPoint& rEnd,
+            SpreadMethod aSpreadMethod,
+            double fOverlapping)
+		:	BufferedDecompositionPrimitive2D(),
+            SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod, fOverlapping),
+            maEnd(rEnd)
+		{
+		}
+
+		bool SvgLinearGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+		{
+            const SvgGradientHelper* pSvgGradientHelper = dynamic_cast< const SvgGradientHelper* >(&rPrimitive);
+
+            if(pSvgGradientHelper && SvgGradientHelper::operator==(*pSvgGradientHelper))
+			{
+				const SvgLinearGradientPrimitive2D& rCompare = static_cast< const SvgLinearGradientPrimitive2D& >(rPrimitive);
+
+				return (getEnd() == rCompare.getEnd());
+			}
+
+			return false;
+		}
+
+		basegfx::B2DRange SvgLinearGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+		{
+			// return ObjectRange
+			return getPolyPolygon().getB2DRange();
+		}
+
+		// provide unique ID
+		ImplPrimitrive2DIDBlock(SvgLinearGradientPrimitive2D, PRIMITIVE2D_ID_SVGLINEARGRADIENTPRIMITIVE2D)
+
+	} // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+	namespace primitive2d
+	{
+        void SvgRadialGradientPrimitive2D::checkPreconditions()
+        {
+            // call parent
+            SvgGradientHelper::checkPreconditions();
+
+            if(getCreatesContent())
+            {
+                // Check Radius
+                if(basegfx::fTools::equalZero(getRadius()))
+                {
+                    // fill with single color using last stop color
+                    setSingleEntry();
+                }
+            }
+        }
+
+        void SvgRadialGradientPrimitive2D::ensureGeometry(
+            basegfx::B2DPolyPolygon& rPolyPolygon,
+            const SvgGradientEntry& rFrom, 
+            const SvgGradientEntry& rTo,
+            sal_Int32 nOffset) const
+        {
+            if(!rPolyPolygon.count())
+            {
+                basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
+                basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
+                double fScaleFrom(rFrom.getOffset() + nOffset);
+                const double fScaleTo(rTo.getOffset() + nOffset);
+
+                if(fScaleFrom > getOverlapping())
+                {
+                    fScaleFrom -= getOverlapping();
+                }
+
+                if(isFocalSet())
+                {
+                    const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
+                    const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+
+                    aPolygonA.transform(
+                        basegfx::tools::createScaleTranslateB2DHomMatrix(
+                            fScaleFrom,
+                            fScaleFrom,
+                            aTranslateFrom.getX(),
+                            aTranslateFrom.getY()));
+                    aPolygonB.transform(
+                        basegfx::tools::createScaleTranslateB2DHomMatrix(
+                            fScaleTo,
+                            fScaleTo,
+                            aTranslateTo.getX(),
+                            aTranslateTo.getY()));
+                }
+                else
+                {
+                    aPolygonA.transform(
+                        basegfx::tools::createScaleB2DHomMatrix(
+                            fScaleFrom,
+                            fScaleFrom));
+                    aPolygonB.transform(
+                        basegfx::tools::createScaleB2DHomMatrix(
+                            fScaleTo,
+                            fScaleTo));
+                }
+
+                // add the outer polygon first
+                rPolyPolygon.append(aPolygonB);
+                rPolyPolygon.append(aPolygonA);
+            }
+        }
+
+        void SvgRadialGradientPrimitive2D::createAtom(
+            Primitive2DVector& rTargetColor,
+            Primitive2DVector& rTargetOpacity, 
+            const SvgGradientEntry& rFrom, 
+            const SvgGradientEntry& rTo,
+            sal_Int32 nOffset) const
+        {
+            // create gradient atom [rFrom.getOffset() .. rTo.getOffset()] with (rFrom.getOffset() > rTo.getOffset())
+            if(rFrom.getOffset() == rTo.getOffset())
+            {
+                OSL_ENSURE(false, "SvgGradient Atom creation with no step width (!)");
+            }
+            else
+            {
+                const bool bColorChange(rFrom.getColor() != rTo.getColor());
+                const bool bOpacityChange(rFrom.getOpacity() != rTo.getOpacity());
+                basegfx::B2DPolyPolygon aPolyPolygon;
+
+                if(bColorChange)
+                {
+                    const double fScaleFrom(rFrom.getOffset() + nOffset);
+                    const double fScaleTo(rTo.getOffset() + nOffset);
+
+                    if(isFocalSet())
+                    {
+                        const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
+                        const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+                        
+                        rTargetColor.push_back(
+                            new SvgRadialAtomPrimitive2D(
+                                rFrom.getColor(), fScaleFrom, aTranslateFrom,
+                                rTo.getColor(), fScaleTo, aTranslateTo,
+                                getOverlapping()));
+                    }
+                    else
+                    {
+                        rTargetColor.push_back(
+                            new SvgRadialAtomPrimitive2D(
+                                rFrom.getColor(), fScaleFrom,
+                                rTo.getColor(), fScaleTo,
+                                getOverlapping()));
+                    }
+                }
+                else
+                {
+                    ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
+                    rTargetColor.push_back(
+                        new PolyPolygonColorPrimitive2D(
+                            aPolyPolygon, 
+                            rFrom.getColor()));
+                }
+
+                if(bOpacityChange)
+                {
+                    const double fTransFrom(1.0 - rFrom.getOpacity());
+                    const double fTransTo(1.0 - rTo.getOpacity());
+                    const basegfx::BColor aColorFrom(fTransFrom, fTransFrom, fTransFrom);
+                    const basegfx::BColor aColorTo(fTransTo, fTransTo, fTransTo);
+                    const double fScaleFrom(rFrom.getOffset() + nOffset);
+                    const double fScaleTo(rTo.getOffset() + nOffset);
+
+                    if(isFocalSet())
+                    {
+                        const basegfx::B2DVector aTranslateFrom(maFocalVector * (maFocalLength - fScaleFrom));
+                        const basegfx::B2DVector aTranslateTo(maFocalVector * (maFocalLength - fScaleTo));
+                        
+                        rTargetOpacity.push_back(
+                            new SvgRadialAtomPrimitive2D(
+                                aColorFrom, fScaleFrom, aTranslateFrom,
+                                aColorTo, fScaleTo, aTranslateTo,
+                                getOverlapping()));
+                    }
+                    else
+                    {
+                        rTargetOpacity.push_back(
+                            new SvgRadialAtomPrimitive2D(
+                                aColorFrom, fScaleFrom,
+                                aColorTo, fScaleTo,
+                                getOverlapping()));
+                    }
+                }
+                else if(!getFullyOpaque())
+                {
+                    const double fTransparence(1.0 - rFrom.getOpacity());
+
+                    ensureGeometry(aPolyPolygon, rFrom, rTo, nOffset);
+                    rTargetOpacity.push_back(
+                        new PolyPolygonColorPrimitive2D(
+                            aPolyPolygon, 
+                            basegfx::BColor(fTransparence, fTransparence, fTransparence)));
+                }
+            }
+        }
+
+        const SvgGradientEntryVector& SvgRadialGradientPrimitive2D::getMirroredGradientEntries() const
+        {
+            if(maMirroredGradientEntries.empty() && !getGradientEntries().empty())
+            {
+                const_cast< SvgRadialGradientPrimitive2D* >(this)->createMirroredGradientEntries();
+            }
+
+            return maMirroredGradientEntries;
+        }
+            
+        void SvgRadialGradientPrimitive2D::createMirroredGradientEntries()
+        {
+            if(maMirroredGradientEntries.empty() && !getGradientEntries().empty())
+            {
+                const sal_uInt32 nCount(getGradientEntries().size());
+                maMirroredGradientEntries.clear();
+                maMirroredGradientEntries.reserve(nCount);
+
+                for(sal_uInt32 a(0); a < nCount; a++)
+                {
+                    const SvgGradientEntry& rCandidate = getGradientEntries()[nCount - 1 - a];
+
+                    maMirroredGradientEntries.push_back(
+                        SvgGradientEntry(
+                            1.0 - rCandidate.getOffset(),
+                            rCandidate.getColor(),
+                            rCandidate.getOpacity()));
+                }
+            }
+        }
+
+		Primitive2DSequence SvgRadialGradientPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+		{
+            Primitive2DSequence xRetval;
+
+            if(!getPreconditionsChecked())
+            {
+                const_cast< SvgRadialGradientPrimitive2D* >(this)->checkPreconditions();
+            }
+
+            if(getSingleEntry())
+            {
+                // fill with last existing color
+                xRetval = createSingleGradientEntryFill();
+            }
+            else if(getCreatesContent())
+            {
+                // at least two color stops in range [0.0 .. 1.0], sorted, non-null vector, not completely
+                // invisible, width and height to fill are not empty
+                const SvgGradientEntryVector& rEntries = getGradientEntries();
+                const basegfx::B2DRange aPolyRange(getPolyPolygon().getB2DRange());
+                const double fPolyWidth(aPolyRange.getWidth());
+                const double fPolyHeight(aPolyRange.getHeight());
+
+                // create ObjectTransform based on polygon range
+                const basegfx::B2DHomMatrix aObjectTransform(
+                    basegfx::tools::createScaleTranslateB2DHomMatrix(
+                        fPolyWidth, fPolyHeight, 
+                        aPolyRange.getMinX(), aPolyRange.getMinY()));
+
+                // create unit transform from unit vector to given linear gradient vector
+                basegfx::B2DHomMatrix aUnitGradientToGradient;
+
+                aUnitGradientToGradient.scale(getRadius(), getRadius());
+                aUnitGradientToGradient.translate(getStart().getX(), getStart().getY());
+
+                // create full transform from unit gradient coordinates to object coordinates
+                // including the SvgGradient transformation
+                basegfx::B2DHomMatrix aUnitGradientToObject(aObjectTransform * aUnitGradientToGradient);
+
+                // create inverse from it
+                basegfx::B2DHomMatrix aObjectToUnitGradient(aUnitGradientToObject);
+                aObjectToUnitGradient.invert();
+
+                // back-transform polygon to unit gradient coordinates and get
+                // UnitRage. This is the range the gradient has to cover
+                basegfx::B2DPolyPolygon aUnitPoly(getPolyPolygon());
+                aUnitPoly.transform(aObjectToUnitGradient);
+                const basegfx::B2DRange aUnitRange(aUnitPoly.getB2DRange());
+
+                // create range which the gradient has to cover to cover the whole given geometry.
+                // For circle, go from 0.0 to max radius in all directions (the corners)
+                double fMax(basegfx::B2DVector(aUnitRange.getMinimum()).getLength());
+                fMax = std::max(fMax, basegfx::B2DVector(aUnitRange.getMaximum()).getLength());
+                fMax = std::max(fMax, basegfx::B2DVector(aUnitRange.getMinX(), aUnitRange.getMaxY()).getLength());
+                fMax = std::max(fMax, basegfx::B2DVector(aUnitRange.getMaxX(), aUnitRange.getMinY()).getLength());
+
+                // prepare result vectors
+                Primitive2DVector aTargetColor;
+                Primitive2DVector aTargetOpacity;
+
+                if(0.0 < fMax)
+                {
+                    // prepare maFocalVector
+                    if(isFocalSet())
+                    {
+                        const_cast< SvgRadialGradientPrimitive2D* >(this)->maFocalLength = fMax;
+                    }
+
+                    // create central run, may also already do all necessary when
+                    // Spread_pad is set as SpreadMethod and/or the range is smaller
+                    double fPos(createRun(aTargetColor, aTargetOpacity, 0.0, fMax, getGradientEntries(), 0));
+
+                    if(fPos < fMax)
+                    {
+                        // can only happen when SpreadMethod is Spread_reflect or Spread_repeat,
+                        // else the start and end pads are already created and fPos == fMax.
+                        // For radial there is no way to transform the already created
+                        // central run, it needs to be created from 1.0 to fMax
+                        sal_Int32 nOffset(1);
+
+                        while(fPos < fMax)
+                        {
+                            const bool bMirror(Spread_reflect == getSpreadMethod() && (nOffset % 2));
+
+                            if(bMirror)
+                            {
+                                createRun(aTargetColor, aTargetOpacity, 0.0, fMax, getMirroredGradientEntries(), nOffset);
+                            }
+                            else
+                            {
+                                createRun(aTargetColor, aTargetOpacity, 0.0, fMax, getGradientEntries(), nOffset);
+                            }
+
+                            nOffset++;
+                            fPos += 1.0;
+                        }
+                    }
+                }
+
+                xRetval = createResult(aTargetColor, aTargetOpacity, aUnitGradientToObject, true);
+            }
+
+            return xRetval;
+		}
+
+		SvgRadialGradientPrimitive2D::SvgRadialGradientPrimitive2D(
+			const basegfx::B2DPolyPolygon& rPolyPolygon,
+            const SvgGradientEntryVector& rGradientEntries,
+            const basegfx::B2DPoint& rStart,
+            double fRadius,
+            SpreadMethod aSpreadMethod,
+            const basegfx::B2DPoint* pFocal,
+            double fOverlapping)
+		:	BufferedDecompositionPrimitive2D(),
+            SvgGradientHelper(rPolyPolygon, rGradientEntries, rStart, aSpreadMethod, fOverlapping),
+            mfRadius(fRadius),
+            maFocal(rStart),
+            maFocalVector(0.0, 0.0),
+            maFocalLength(0.0),
+            maMirroredGradientEntries(),
+            mbFocalSet(false)
+		{
+            if(pFocal)
+            {
+                maFocal = *pFocal;
+                maFocalVector = maFocal - getStart();
+                mbFocalSet = true;
+            }
+		}
+
+		bool SvgRadialGradientPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+		{
+            const SvgGradientHelper* pSvgGradientHelper = dynamic_cast< const SvgGradientHelper* >(&rPrimitive);
+
+            if(pSvgGradientHelper && SvgGradientHelper::operator==(*pSvgGradientHelper))
+			{
+				const SvgRadialGradientPrimitive2D& rCompare = static_cast< const SvgRadialGradientPrimitive2D& >(rPrimitive);
+
+				if(getRadius() == rCompare.getRadius())
+                {
+                    if(isFocalSet() == rCompare.isFocalSet())
+                    {
+                        if(isFocalSet())
+                        {
+                            return getFocal() == rCompare.getFocal();
+                        }
+                        else
+                        {
+                            return true;
+                        }
+                    }
+                }
+			}
+
+			return false;
+		}
+
+		basegfx::B2DRange SvgRadialGradientPrimitive2D::getB2DRange(const geometry::ViewInformation2D& /*rViewInformation*/) const
+		{
+			// return ObjectRange
+			return getPolyPolygon().getB2DRange();
+		}
+
+		// provide unique ID
+		ImplPrimitrive2DIDBlock(SvgRadialGradientPrimitive2D, PRIMITIVE2D_ID_SVGRADIALGRADIENTPRIMITIVE2D)
+
+	} // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgLinearAtomPrimitive2D class
+
+namespace drawinglayer
+{
+	namespace primitive2d
+	{
+        Primitive2DSequence SvgLinearAtomPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
+        {
+            Primitive2DSequence xRetval;
+            const double fDelta(getOffsetB() - getOffsetA());
+
+            if(!basegfx::fTools::equalZero(fDelta))
+            {
+                if(getColorA() == getColorB())
+                {
+                    const basegfx::B2DPolygon aPolygon(
+                        basegfx::tools::createPolygonFromRect(
+                            basegfx::B2DRange(
+                                getOffsetA() - getOverlapping(), 
+                                0.0, 
+                                getOffsetB() + getOverlapping(), 
+                                1.0)));
+
+                    xRetval.realloc(1);
+                    xRetval[0] = new PolyPolygonColorPrimitive2D(
+                        basegfx::B2DPolyPolygon(aPolygon), 
+                        getColorA());
+                }
+                else
+                {
+                    // calc discrete length to change color all 2.5 pixels
+                    sal_uInt32 nSteps(basegfx::fround(fDelta / (getDiscreteUnit() * 2.5)));
+
+                    // use color distance, assume to do every 3rd
+                    const double fColorDistance(getColorA().getDistance(getColorB()));
+                    const sal_uInt32 nColorSteps(basegfx::fround(fColorDistance * (255.0 * 0.3)));
+                    nSteps = std::min(nSteps, nColorSteps);
+
+                    // roughly cut when too big
+                    nSteps = std::min(nSteps, sal_uInt32(100));
+                    nSteps = std::max(nSteps, sal_uInt32(1));
+
+                    // preapare iteration
+                    double fStart(0.0);
+                    double fStep(fDelta / nSteps);
+
+                    xRetval.realloc(nSteps);
+
+                    for(sal_uInt32 a(0); a < nSteps; a++, fStart += fStep)
+                    {
+                        const double fLeft(getOffsetA() + fStart);
+                        const double fRight(fLeft + fStep);
+                        const basegfx::B2DPolygon aPolygon(
+                            basegfx::tools::createPolygonFromRect(
+                                basegfx::B2DRange(
+                                    fLeft - getOverlapping(), 
+                                    0.0, 
+                                    fRight + getOverlapping(), 
+                                    1.0)));
+
+                        xRetval[a] = new PolyPolygonColorPrimitive2D(
+                            basegfx::B2DPolyPolygon(aPolygon), 
+                            basegfx::interpolate(getColorA(), getColorB(), fStart/fDelta));
+                    }
+                }
+            }
+
+            return xRetval;
+        }
+
+        bool SvgLinearAtomPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+        {
+			if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+			{
+				const SvgLinearAtomPrimitive2D& rCompare = static_cast< const SvgLinearAtomPrimitive2D& >(rPrimitive);
+
+				return (getColorA() == rCompare.getColorA()
+                    && getColorB() == rCompare.getColorB()
+                    && getOffsetA() == rCompare.getOffsetA()
+                    && getOffsetB() == rCompare.getOffsetB()
+                    && getOverlapping() == rCompare.getOverlapping());
+			}
+
+			return false;
+        }
+
+		// provide unique ID
+		ImplPrimitrive2DIDBlock(SvgLinearAtomPrimitive2D, PRIMITIVE2D_ID_SVGLINEARATOMPRIMITIVE2D)
+
+    } // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// SvgRadialAtomPrimitive2D class
+
+namespace drawinglayer
+{
+	namespace primitive2d
+	{
+        Primitive2DSequence SvgRadialAtomPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
+        {
+            Primitive2DSequence xRetval;
+            const double fDeltaScale(getScaleB() - getScaleA());
+
+            if(!basegfx::fTools::equalZero(fDeltaScale))
+            {
+                if(getColorA() == getColorB())
+                {
+                    basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
+                    basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
+                    double fScaleA(getScaleA());
+                    const double fScaleB(getScaleB());
+
+                    if(fScaleA > getOverlapping())
+                    {
+                        fScaleA -= getOverlapping();
+                    }
+
+                    const bool bUseA(basegfx::fTools::equalZero(fScaleA));
+
+                    if(getTranslateSet())
+                    {
+                        if(bUseA)
+                        {
+                            aPolygonA.transform(
+                                basegfx::tools::createScaleTranslateB2DHomMatrix(
+                                    fScaleA,
+                                    fScaleA,
+                                    getTranslateA().getX(),
+                                    getTranslateA().getY()));
+                        }
+
+                        aPolygonB.transform(
+                            basegfx::tools::createScaleTranslateB2DHomMatrix(
+                                fScaleB,
+                                fScaleB,
+                                getTranslateB().getX(),
+                                getTranslateB().getY()));
+                    }
+                    else
+                    {
+                        if(bUseA)
+                        {
+                            aPolygonA.transform(
+                                basegfx::tools::createScaleB2DHomMatrix(
+                                    fScaleA,
+                                    fScaleA));
+                        }
+
+                        aPolygonB.transform(
+                            basegfx::tools::createScaleB2DHomMatrix(
+                                fScaleB,
+                                fScaleB));
+                    }
+
+                    basegfx::B2DPolyPolygon aPolyPolygon(aPolygonB);
+                    
+                    if(bUseA)
+                    {
+                        aPolyPolygon.append(aPolygonA);
+                    }
+
+                    xRetval.realloc(1);
+                    
+                    xRetval[0] = new PolyPolygonColorPrimitive2D(
+                        aPolyPolygon, 
+                        getColorA());
+                }
+                else
+                {
+                    // calc discrete length to change color all 2.5 pixels
+                    sal_uInt32 nSteps(basegfx::fround(fDeltaScale / (getDiscreteUnit() * 2.5)));
+
+                    // use color distance, assume to do every 3rd
+                    const double fColorDistance(getColorA().getDistance(getColorB()));
+                    const sal_uInt32 nColorSteps(basegfx::fround(fColorDistance * (255.0 * 0.3)));
+                    nSteps = std::min(nSteps, nColorSteps);
+
+                    // roughly cut when too big
+                    nSteps = std::min(nSteps, sal_uInt32(100));
+                    nSteps = std::max(nSteps, sal_uInt32(1));
+
+                    // preapare iteration
+                    double fStartScale(0.0);
+                    double fStepScale(fDeltaScale / nSteps);
+
+                    xRetval.realloc(nSteps);
+
+                    for(sal_uInt32 a(0); a < nSteps; a++, fStartScale += fStepScale)
+                    {
+                        double fScaleA(getScaleA() + fStartScale);
+                        const double fScaleB(fScaleA + fStepScale);
+                        const double fUnitScale(fStartScale/fDeltaScale);
+                        basegfx::B2DPolygon aPolygonA(basegfx::tools::createPolygonFromUnitCircle());
+                        basegfx::B2DPolygon aPolygonB(basegfx::tools::createPolygonFromUnitCircle());
+
+                        if(fScaleA > getOverlapping())
+                        {
+                            fScaleA -= getOverlapping();
+                        }
+                        
+                        const bool bUseA(basegfx::fTools::equalZero(fScaleA));
+
+                        if(getTranslateSet())
+                        {
+                            const double fUnitScaleEnd((fStartScale + fStepScale)/fDeltaScale);
+                            const basegfx::B2DVector aTranslateB(basegfx::interpolate(getTranslateA(), getTranslateB(), fUnitScaleEnd));
+
+                            if(bUseA)
+                            {
+                                const basegfx::B2DVector aTranslateA(basegfx::interpolate(getTranslateA(), getTranslateB(), fUnitScale));
+                                
+                                aPolygonA.transform(
+                                    basegfx::tools::createScaleTranslateB2DHomMatrix(
+                                        fScaleA,
+                                        fScaleA,
+                                        aTranslateA.getX(),
+                                        aTranslateA.getY()));
+                            }
+
+                            aPolygonB.transform(
+                                basegfx::tools::createScaleTranslateB2DHomMatrix(
+                                    fScaleB,
+                                    fScaleB,
+                                    aTranslateB.getX(),
+                                    aTranslateB.getY()));
+                        }
+                        else
+                        {
+                            if(bUseA)
+                            {
+                                aPolygonA.transform(
+                                    basegfx::tools::createScaleB2DHomMatrix(
+                                        fScaleA,
+                                        fScaleA));
+                            }
+
+                            aPolygonB.transform(
+                                basegfx::tools::createScaleB2DHomMatrix(
+                                    fScaleB,
+                                    fScaleB));
+                        }
+
+                        basegfx::B2DPolyPolygon aPolyPolygon(aPolygonB);
+                        
+                        if(bUseA)
+                        {
+                            aPolyPolygon.append(aPolygonA);
+                        }
+
+                        xRetval[nSteps - 1 - a] = new PolyPolygonColorPrimitive2D(
+                            aPolyPolygon, 
+                            basegfx::interpolate(getColorA(), getColorB(), fUnitScale));
+                    }
+                }
+            }
+
+            return xRetval;
+        }
+
+        bool SvgRadialAtomPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
+        {
+			if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
+			{
+				const SvgRadialAtomPrimitive2D& rCompare = static_cast< const SvgRadialAtomPrimitive2D& >(rPrimitive);
+
+				return (getColorA() == rCompare.getColorA()
+                    && getColorB() == rCompare.getColorB()
+                    && getScaleA() == rCompare.getScaleA()
+                    && getScaleB() == rCompare.getScaleB()
+                    && getTranslateA() == rCompare.getTranslateA()
+                    && getTranslateB() == rCompare.getTranslateB()
+                    && getOverlapping() == rCompare.getOverlapping());
+			}
+
+			return false;
+        }
+
+		// provide unique ID
+		ImplPrimitrive2DIDBlock(SvgRadialAtomPrimitive2D, PRIMITIVE2D_ID_SVGRADIALATOMPRIMITIVE2D)
+
+	} // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof

Added: incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/textbreakuphelper.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/textbreakuphelper.cxx?rev=1209140&view=auto
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/textbreakuphelper.cxx (added)
+++ incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/primitive2d/textbreakuphelper.cxx Thu Dec  1 16:25:17 2011
@@ -0,0 +1,294 @@
+/**************************************************************
+ * 
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http:\\www.apache.org\licenses\LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ * 
+ *************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_drawinglayer.hxx"
+
+#include <drawinglayer/primitive2d/textbreakuphelper.hxx>
+#include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <comphelper/processfactory.hxx>
+#include <com/sun/star/i18n/CharacterIteratorMode.hdl>
+#include <com/sun/star/i18n/WordType.hpp>
+
+//////////////////////////////////////////////////////////////////////////////
+
+namespace drawinglayer
+{
+	namespace primitive2d
+	{
+        TextBreakupHelper::TextBreakupHelper(const Primitive2DReference& rxSource)
+        :   mxSource(rxSource),
+            mxResult(),
+            mpSource(dynamic_cast< const TextSimplePortionPrimitive2D* >(rxSource.get())),
+            maTextLayouter(),
+            maDecTrans(),
+            mbNoDXArray()
+        {
+            if(mpSource)
+            {
+                maDecTrans = mpSource->getTextTransform();
+                mbNoDXArray = mpSource->getDXArray().empty();
+
+                if(mbNoDXArray)
+                {
+                    // init TextLayouter when no dxarray
+				    maTextLayouter.setFontAttribute(
+                        mpSource->getFontAttribute(), 
+                        maDecTrans.getScale().getX(), 
+                        maDecTrans.getScale().getY(),
+                        mpSource->getLocale());
+                }
+            }
+        }
+
+        TextBreakupHelper::~TextBreakupHelper()
+        {
+        }
+
+        void TextBreakupHelper::breakupPortion(Primitive2DVector& rTempResult, sal_uInt32 nIndex, sal_uInt32 nLength)
+        {
+            if(mpSource && nLength && !(nIndex == mpSource->getTextPosition() && nLength == mpSource->getTextLength()))
+            {
+ 				// prepare values for new portion
+				basegfx::B2DHomMatrix aNewTransform;
+				::std::vector< double > aNewDXArray;
+				const bool bNewStartIsNotOldStart(nIndex > mpSource->getTextPosition());
+
+				if(!mbNoDXArray)
+				{
+					// prepare new DXArray for the single word
+					aNewDXArray = ::std::vector< double >(
+						mpSource->getDXArray().begin() + (nIndex - mpSource->getTextPosition()), 
+						mpSource->getDXArray().begin() + ((nIndex + nLength) - mpSource->getTextPosition()));
+				}
+
+				if(bNewStartIsNotOldStart)
+				{
+					// needs to be moved to a new start position
+					double fOffset(0.0);
+							
+					if(mbNoDXArray)
+					{
+						// evaluate using TextLayouter
+						fOffset = maTextLayouter.getTextWidth(mpSource->getText(), mpSource->getTextPosition(), nIndex);
+					}
+					else
+					{
+						// get from DXArray
+						const sal_uInt32 nIndex(static_cast< sal_uInt32 >(nIndex - mpSource->getTextPosition()));
+						fOffset = mpSource->getDXArray()[nIndex - 1];
+					}
+
+                    // need offset without FontScale for building the new transformation. The
+                    // new transformation will be multiplied with the current text transformation
+                    // so FontScale would be double
+					double fOffsetNoScale(fOffset);
+                    const double fFontScaleX(maDecTrans.getScale().getX());
+                            
+                    if(!basegfx::fTools::equal(fFontScaleX, 1.0) 
+                        && !basegfx::fTools::equalZero(fFontScaleX))
+                    {
+                        fOffsetNoScale /= fFontScaleX;
+                    }
+
+					// apply needed offset to transformation
+                    aNewTransform.translate(fOffsetNoScale, 0.0);
+
+					if(!mbNoDXArray)
+					{
+						// DXArray values need to be corrected with the offset, too. Here,
+                        // take the scaled offset since the DXArray is scaled
+						const sal_uInt32 nArraySize(aNewDXArray.size());
+
+						for(sal_uInt32 a(0); a < nArraySize; a++)
+						{
+							aNewDXArray[a] -= fOffset;
+						}
+					}
+				}
+
+				// add text transformation to new transformation
+				aNewTransform = maDecTrans.getB2DHomMatrix() * aNewTransform;
+
+                // callback to allow evtl. changes
+                const bool bCreate(allowChange(rTempResult.size(), aNewTransform, nIndex, nLength));
+
+                if(bCreate)
+                {
+                    // check if we have a decorated primitive as source
+                    const TextDecoratedPortionPrimitive2D* pTextDecoratedPortionPrimitive2D = 
+                        dynamic_cast< const TextDecoratedPortionPrimitive2D* >(mpSource);
+
+                    if(pTextDecoratedPortionPrimitive2D)
+                    {
+                        // create a TextDecoratedPortionPrimitive2D
+	                    rTempResult.push_back(
+                            new TextDecoratedPortionPrimitive2D(
+                                aNewTransform,
+                                mpSource->getText(),
+				                nIndex,
+				                nLength,
+                                aNewDXArray,
+                                mpSource->getFontAttribute(),
+                                mpSource->getLocale(),
+                                mpSource->getFontColor(),
+                            
+                                pTextDecoratedPortionPrimitive2D->getOverlineColor(),
+                                pTextDecoratedPortionPrimitive2D->getTextlineColor(),
+                                pTextDecoratedPortionPrimitive2D->getFontOverline(),
+                                pTextDecoratedPortionPrimitive2D->getFontUnderline(),
+                                pTextDecoratedPortionPrimitive2D->getUnderlineAbove(),
+                                pTextDecoratedPortionPrimitive2D->getTextStrikeout(),
+                                pTextDecoratedPortionPrimitive2D->getWordLineMode(),
+                                pTextDecoratedPortionPrimitive2D->getTextEmphasisMark(),
+                                pTextDecoratedPortionPrimitive2D->getEmphasisMarkAbove(),
+                                pTextDecoratedPortionPrimitive2D->getEmphasisMarkBelow(),
+                                pTextDecoratedPortionPrimitive2D->getTextRelief(),
+                                pTextDecoratedPortionPrimitive2D->getShadow()));
+                    }
+                    else
+                    {
+                        // create a SimpleTextPrimitive
+	                    rTempResult.push_back(
+                            new TextSimplePortionPrimitive2D(
+                                aNewTransform,
+                                mpSource->getText(),
+				                nIndex,
+				                nLength,
+                                aNewDXArray,
+                                mpSource->getFontAttribute(),
+                                mpSource->getLocale(),
+                                mpSource->getFontColor()));
+                    }
+                }
+            }
+        }
+
+        bool TextBreakupHelper::allowChange(sal_uInt32 nCount, basegfx::B2DHomMatrix& rNewTransform, sal_uInt32 nIndex, sal_uInt32 nLength)
+        {
+            return true;
+        }
+
+        void TextBreakupHelper::breakup(BreakupUnit aBreakupUnit)
+        {
+            if(mpSource && mpSource->getTextLength())
+            {
+                Primitive2DVector aTempResult;
+                static ::com::sun::star::uno::Reference< ::com::sun::star::i18n::XBreakIterator > xBreakIterator;
+
+                if(!xBreakIterator.is())
+                {
+                    ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xMSF(::comphelper::getProcessServiceFactory());
+                    xBreakIterator.set(xMSF->createInstance(rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator")), ::com::sun::star::uno::UNO_QUERY);
+                }
+
+                if(xBreakIterator.is())
+                {
+                    const rtl::OUString& rTxt = mpSource->getText();
+                    const sal_Int32 nTextLength(mpSource->getTextLength());
+                    const ::com::sun::star::lang::Locale& rLocale = mpSource->getLocale();
+                    const sal_Int32 nTextPosition(mpSource->getTextPosition());
+                    sal_Int32 nCurrent(nTextPosition);
+                    
+                    switch(aBreakupUnit)
+                    {
+                        case BreakupUnit_character:
+                        {
+                            sal_Int32 nDone;
+                            sal_Int32 nNextCellBreak(xBreakIterator->nextCharacters(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 0, nDone));
+                            sal_Int32 a(nTextPosition);
+
+                            for(; a < nTextPosition + nTextLength; a++)
+                            {
+                                if(a == nNextCellBreak)
+                                {
+                                    breakupPortion(aTempResult, nCurrent, a - nCurrent);
+                                    nCurrent = a;
+                                    nNextCellBreak = xBreakIterator->nextCharacters(rTxt, a, rLocale, ::com::sun::star::i18n::CharacterIteratorMode::SKIPCELL, 1, nDone);
+                                }
+                            }
+
+                            breakupPortion(aTempResult, nCurrent, a - nCurrent);
+                            break;
+                        }
+                        case BreakupUnit_word:
+                        {
+                            ::com::sun::star::i18n::Boundary nNextWordBoundary(xBreakIterator->getWordBoundary(rTxt, nTextPosition, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True));
+                            sal_Int32 a(nTextPosition);
+                            
+                            for(; a < nTextPosition + nTextLength; a++)
+                            {
+                                if(a == nNextWordBoundary.endPos)
+                                {
+                                    breakupPortion(aTempResult, nCurrent, a - nCurrent);
+                                    nCurrent = a;
+                                    nNextWordBoundary = xBreakIterator->getWordBoundary(rTxt, a + 1, rLocale, ::com::sun::star::i18n::WordType::ANY_WORD, sal_True);
+                                }
+                            }
+
+                            breakupPortion(aTempResult, nCurrent, a - nCurrent);
+                            break;
+                        }
+                        case BreakupUnit_sentence:
+                        {
+                            sal_Int32 nNextSentenceBreak(xBreakIterator->endOfSentence(rTxt, nTextPosition, rLocale));
+                            sal_Int32 a(nTextPosition);
+                            
+                            for(; a < nTextPosition + nTextLength; a++)
+                            {
+                                if(a == nNextSentenceBreak)
+                                {
+                                    breakupPortion(aTempResult, nCurrent, a - nCurrent);
+                                    nCurrent = a;
+                                    nNextSentenceBreak = xBreakIterator->endOfSentence(rTxt, a + 1, rLocale);
+                                }
+                            }
+
+                            breakupPortion(aTempResult, nCurrent, a - nCurrent);
+                            break;
+                        }
+                    }
+                }
+                
+                mxResult = Primitive2DVectorToPrimitive2DSequence(aTempResult);
+            }
+        }
+
+        const Primitive2DSequence& TextBreakupHelper::getResult(BreakupUnit aBreakupUnit) const
+        {
+            if(mxResult.hasElements())
+            {
+                return mxResult;
+            }
+            else if(mpSource)
+            {
+                const_cast< TextBreakupHelper* >(this)->breakup(aBreakupUnit);
+            }
+
+            return mxResult;
+        }
+
+	} // end of namespace primitive2d
+} // end of namespace drawinglayer
+
+//////////////////////////////////////////////////////////////////////////////
+// eof

Modified: incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/processor2d/hittestprocessor2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/processor2d/hittestprocessor2d.cxx?rev=1209140&r1=1209139&r2=1209140&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/processor2d/hittestprocessor2d.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/processor2d/hittestprocessor2d.cxx Thu Dec  1 16:25:17 2011
@@ -525,7 +525,6 @@ namespace drawinglayer
 				case PRIMITIVE2D_ID_FILLHATCHPRIMITIVE2D :
 				case PRIMITIVE2D_ID_PAGEPREVIEWPRIMITIVE2D :
                 case PRIMITIVE2D_ID_MEDIAPRIMITIVE2D:
-                case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D:
                 {
                     if(!getHitTextOnly())
                     {

Modified: incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/processor2d/linegeometryextractor2d.cxx
URL: http://svn.apache.org/viewvc/incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/processor2d/linegeometryextractor2d.cxx?rev=1209140&r1=1209139&r2=1209140&view=diff
==============================================================================
--- incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/processor2d/linegeometryextractor2d.cxx (original)
+++ incubator/ooo/branches/alg/svgreplacement/main/drawinglayer/source/processor2d/linegeometryextractor2d.cxx Thu Dec  1 16:25:17 2011
@@ -119,7 +119,6 @@ namespace drawinglayer
 				case PRIMITIVE2D_ID_MARKERARRAYPRIMITIVE2D :
 				case PRIMITIVE2D_ID_POINTARRAYPRIMITIVE2D :
 				case PRIMITIVE2D_ID_BITMAPPRIMITIVE2D :
-				case PRIMITIVE2D_ID_RENDERGRAPHICPRIMITIVE2D :
 				case PRIMITIVE2D_ID_METAFILEPRIMITIVE2D :
 				case PRIMITIVE2D_ID_MASKPRIMITIVE2D :
                 {