/**************************************************************
 * 
 * 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_svx.hxx"

#include <svx/svdotext.hxx>
#include <svx/svdoutl.hxx>
#include <basegfx/vector/b2dvector.hxx>
#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx>
#include <basegfx/range/b2drange.hxx>
#include <vcl/salbtype.hxx>
#include <svl/itemset.hxx>
#include <basegfx/polygon/b2dpolygontools.hxx>
#include <basegfx/polygon/b2dpolygon.hxx>
#include <algorithm>
#include <svx/xtextit.hxx>
#include <svx/xftshtit.hxx>
#include <vcl/virdev.hxx>
#include <com/sun/star/lang/XMultiServiceFactory.hpp>
#include <com/sun/star/i18n/ScriptType.hdl>
#include <com/sun/star/i18n/XBreakIterator.hpp>
#include <comphelper/processfactory.hxx>
#include <com/sun/star/i18n/CharacterIteratorMode.hdl>
#include <editeng/unolingu.hxx>
#include <drawinglayer/primitive2d/textlayoutdevice.hxx>
#include <drawinglayer/primitive2d/textprimitive2d.hxx>
#include <basegfx/color/bcolor.hxx>

//////////////////////////////////////////////////////////////////////////////
// primitive decomposition helpers

#include <basegfx/polygon/b2dlinegeometry.hxx>
#include <drawinglayer/attribute/strokeattribute.hxx>
#include <svx/xlnclit.hxx>
#include <svx/xlntrit.hxx>
#include <svx/xlnwtit.hxx>
#include <svx/xlinjoit.hxx>
#include <svx/xlndsit.hxx>
#include <drawinglayer/primitive2d/polygonprimitive2d.hxx>
#include <drawinglayer/primitive2d/unifiedtransparenceprimitive2d.hxx>
#include <editeng/editstat.hxx>
#include <svx/unoapi.hxx>
#include <drawinglayer/geometry/viewinformation2d.hxx>
#include <svx/sdr/attribute/sdrformtextoutlineattribute.hxx>

//////////////////////////////////////////////////////////////////////////////

using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::i18n;

//////////////////////////////////////////////////////////////////////////////
// PathTextPortion helper

namespace
{
	class impPathTextPortion
	{
		basegfx::B2DVector							maOffset;
		String										maText;
		xub_StrLen									mnTextStart;
		xub_StrLen									mnTextLength;
		sal_uInt16									mnParagraph;
		xub_StrLen									mnIndex;
		SvxFont										maFont;
		::std::vector< double >						maDblDXArray;	// double DXArray, font size independent -> unit coordinate system
        ::com::sun::star::lang::Locale				maLocale;

		// bitfield
		unsigned									mbRTL : 1;

	public:
		impPathTextPortion(DrawPortionInfo& rInfo)
		:	maOffset(rInfo.mrStartPos.X(), rInfo.mrStartPos.Y()),
			maText(rInfo.mrText),
			mnTextStart(rInfo.mnTextStart),
			mnTextLength(rInfo.mnTextLen),
			mnParagraph(rInfo.mnPara),
			mnIndex(rInfo.mnIndex),
			maFont(rInfo.mrFont),
            maDblDXArray(),
			maLocale(rInfo.mpLocale ? *rInfo.mpLocale : ::com::sun::star::lang::Locale()),
			mbRTL(rInfo.mrFont.IsVertical() ? false : rInfo.IsRTL())
		{
			if(mnTextLength && rInfo.mpDXArray)
			{
				maDblDXArray.reserve(mnTextLength);
				
				for(xub_StrLen a(0); a < mnTextLength; a++)
				{
					maDblDXArray.push_back((double)rInfo.mpDXArray[a]);
				}
			}
		}

		// for ::std::sort
		bool operator<(const impPathTextPortion& rComp) const
		{
			if(mnParagraph < rComp.mnParagraph)
			{
				return true;
			}

			if(maOffset.getX() < rComp.maOffset.getX())
			{
				return true;
			}

			return (maOffset.getY() < rComp.maOffset.getY());
		}

		const basegfx::B2DVector& getOffset() const { return maOffset; }
		const String& getText() const { return maText; }
		xub_StrLen getTextStart() const { return mnTextStart; }
		xub_StrLen getTextLength() const { return mnTextLength; }
		sal_uInt16 getParagraph() const { return mnParagraph; }
		xub_StrLen getIndex() const { return mnIndex; }
		const SvxFont& getFont() const { return maFont; }
		bool isRTL() const { return mbRTL; }
		const ::std::vector< double >& getDoubleDXArray() const { return maDblDXArray; }
        const ::com::sun::star::lang::Locale& getLocale() const { return maLocale; }

		xub_StrLen getPortionIndex(xub_StrLen nIndex, xub_StrLen nLength) const
		{
			if(mbRTL)
			{
				return (mnTextStart + (mnTextLength - (nIndex + nLength)));
			}
			else
			{
				return (mnTextStart + nIndex);
			}
		}

		double getDisplayLength(xub_StrLen nIndex, xub_StrLen nLength) const
		{
			drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
			double fRetval(0.0);

			if(maFont.IsVertical())
			{
				fRetval = aTextLayouter.getTextHeight() * (double)nLength;
			}
			else
			{
				fRetval = aTextLayouter.getTextWidth(maText, getPortionIndex(nIndex, nLength), nLength);
			}

			return fRetval;
		}
	};
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////
// TextBreakup helper

namespace
{
	class impTextBreakupHandler
	{
		SdrOutliner&								mrOutliner;
		::std::vector< impPathTextPortion >			maPathTextPortions;

		DECL_LINK(decompositionPathTextPrimitive, DrawPortionInfo* );

	public:
		impTextBreakupHandler(SdrOutliner& rOutliner)
		:	mrOutliner(rOutliner)
		{
		}

		const ::std::vector< impPathTextPortion >& decompositionPathTextPrimitive()
		{
			// strip portions to maPathTextPortions
			mrOutliner.SetDrawPortionHdl(LINK(this, impTextBreakupHandler, decompositionPathTextPrimitive));
			mrOutliner.StripPortions();
			
			if(!maPathTextPortions.empty())
			{
				// sort portions by paragraph, x and y
				::std::sort(maPathTextPortions.begin(), maPathTextPortions.end());
			}

			return maPathTextPortions;
		}
	};

	IMPL_LINK(impTextBreakupHandler, decompositionPathTextPrimitive, DrawPortionInfo*, pInfo)
	{
		maPathTextPortions.push_back(impPathTextPortion(*pInfo));
		return 0;
	}
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////
// TextBreakup one poly and one paragraph helper

namespace
{
	class impPolygonParagraphHandler
	{
        const drawinglayer::attribute::SdrFormTextAttribute			maSdrFormTextAttribute;	// FormText parameters
		std::vector< drawinglayer::primitive2d::BasePrimitive2D* >&	mrDecomposition;		// destination primitive list
		std::vector< drawinglayer::primitive2d::BasePrimitive2D* >&	mrShadowDecomposition;	// destination primitive list for shadow
		Reference < com::sun::star::i18n::XBreakIterator >			mxBreak;				// break iterator

		double getParagraphTextLength(const ::std::vector< const impPathTextPortion* >& rTextPortions)
		{
			drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
			double fRetval(0.0);

			for(sal_uInt32 a(0L); a < rTextPortions.size(); a++)
			{
				const impPathTextPortion* pCandidate = rTextPortions[a];

				if(pCandidate && pCandidate->getTextLength())
				{
					aTextLayouter.setFont(pCandidate->getFont());
					fRetval += pCandidate->getDisplayLength(0L, pCandidate->getTextLength());
				}
			}

			return fRetval;
		}

		xub_StrLen getNextGlyphLen(const impPathTextPortion* pCandidate, xub_StrLen nPosition, const ::com::sun::star::lang::Locale& rFontLocale)
		{
			xub_StrLen nNextGlyphLen(1);

			if(mxBreak.is())
			{
				sal_Int32 nDone(0L);
				nNextGlyphLen = (xub_StrLen)mxBreak->nextCharacters(pCandidate->getText(), nPosition, 
					rFontLocale, CharacterIteratorMode::SKIPCELL, 1, nDone) - nPosition;
			}

			return nNextGlyphLen;
		}

	public:
		impPolygonParagraphHandler(
			const drawinglayer::attribute::SdrFormTextAttribute& rSdrFormTextAttribute, 
			std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rDecomposition, 
			std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rShadowDecomposition)
		:	maSdrFormTextAttribute(rSdrFormTextAttribute),
			mrDecomposition(rDecomposition),
			mrShadowDecomposition(rShadowDecomposition)
		{
			// prepare BreakIterator
			Reference < XMultiServiceFactory > xMSF = ::comphelper::getProcessServiceFactory();
			Reference < XInterface > xInterface = xMSF->createInstance(::rtl::OUString::createFromAscii("com.sun.star.i18n.BreakIterator"));
			
			if(xInterface.is())
			{
				Any x = xInterface->queryInterface(::getCppuType((const Reference< XBreakIterator >*)0));
				x >>= mxBreak;
			}
		}

		void HandlePair(const basegfx::B2DPolygon rPolygonCandidate, const ::std::vector< const impPathTextPortion* >& rTextPortions)
		{
			// prepare polygon geometry, take into account as many parameters as possible
			basegfx::B2DPolygon aPolygonCandidate(rPolygonCandidate);
			const double fPolyLength(basegfx::tools::getLength(aPolygonCandidate));
			double fPolyEnd(fPolyLength);
			double fPolyStart(0.0);
			double fAutosizeScaleFactor(1.0);
			bool bAutosizeScale(false);

			if(maSdrFormTextAttribute.getFormTextMirror())
			{
				aPolygonCandidate.flip();
			}

			if(maSdrFormTextAttribute.getFormTextStart() 
                && (XFT_LEFT == maSdrFormTextAttribute.getFormTextAdjust() 
                    || XFT_RIGHT == maSdrFormTextAttribute.getFormTextAdjust()))
			{
				if(XFT_LEFT == maSdrFormTextAttribute.getFormTextAdjust())
				{
					fPolyStart += maSdrFormTextAttribute.getFormTextStart();

					if(fPolyStart > fPolyEnd)
					{
						fPolyStart = fPolyEnd;
					}
				}
				else
				{
					fPolyEnd -= maSdrFormTextAttribute.getFormTextStart();

					if(fPolyEnd < fPolyStart)
					{
						fPolyEnd = fPolyStart;
					}
				}
			}

			if(XFT_LEFT != maSdrFormTextAttribute.getFormTextAdjust())
			{
				// calculate total text length of this paragraph, some layout needs to be done
				const double fParagraphTextLength(getParagraphTextLength(rTextPortions));

				// check if text is too long for paragraph. If yes, handle as if left aligned (default),
				// but still take care of XFT_AUTOSIZE in that case
				const bool bTextTooLong(fParagraphTextLength > (fPolyEnd - fPolyStart));

				if(XFT_RIGHT == maSdrFormTextAttribute.getFormTextAdjust())
				{
					if(!bTextTooLong)
					{
						// if right aligned, add difference to polygon start
						fPolyStart += ((fPolyEnd - fPolyStart) - fParagraphTextLength);
					}
				}
				else if(XFT_CENTER == maSdrFormTextAttribute.getFormTextAdjust())
				{
					if(!bTextTooLong)
					{
						// if centered, add half of difference to polygon start
						fPolyStart += ((fPolyEnd - fPolyStart) - fParagraphTextLength) / 2.0;
					}
				}
				else if(XFT_AUTOSIZE == maSdrFormTextAttribute.getFormTextAdjust())
				{
					// if scale, prepare scale factor between curve length and text length
					if(0.0 != fParagraphTextLength)
					{
						fAutosizeScaleFactor = (fPolyEnd - fPolyStart) / fParagraphTextLength;
						bAutosizeScale = true;
					}
				}
			}

			// handle text portions for this paragraph
			for(sal_uInt32 a(0L); a < rTextPortions.size() && fPolyStart < fPolyEnd; a++)
			{
				const impPathTextPortion* pCandidate = rTextPortions[a];
				basegfx::B2DVector aFontScaling;
				const drawinglayer::attribute::FontAttribute aCandidateFontAttribute(
                    drawinglayer::primitive2d::getFontAttributeFromVclFont(
                        aFontScaling, 
                        pCandidate->getFont(),
                        pCandidate->isRTL(),
                        false));

				if(pCandidate && pCandidate->getTextLength())
				{
					drawinglayer::primitive2d::TextLayouterDevice aTextLayouter;
					aTextLayouter.setFont(pCandidate->getFont());
					xub_StrLen nUsedTextLength(0);

					while(nUsedTextLength < pCandidate->getTextLength() && fPolyStart < fPolyEnd)
					{
						xub_StrLen nNextGlyphLen(getNextGlyphLen(pCandidate, pCandidate->getTextStart() + nUsedTextLength, pCandidate->getLocale()));

						// prepare portion length. Takes RTL sections into account.
						double fPortionLength(pCandidate->getDisplayLength(nUsedTextLength, nNextGlyphLen));

						if(bAutosizeScale)
						{
							// when autosize scaling, expand portion length
							fPortionLength *= fAutosizeScaleFactor;
						}

						// create transformation
						basegfx::B2DHomMatrix aNewTransformA, aNewTransformB, aNewShadowTransform;
						basegfx::B2DPoint aStartPos(basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart, fPolyLength));
						basegfx::B2DPoint aEndPos(aStartPos);

						// add font scaling
						aNewTransformA.scale(aFontScaling.getX(), aFontScaling.getY());

						// prepare scaling of text primitive
						if(bAutosizeScale)
						{
							// when autosize scaling, expand text primitive scaling to it
							aNewTransformA.scale(fAutosizeScaleFactor, fAutosizeScaleFactor);
						}

						// eventually create shadow primitives from aDecomposition and add to rDecomposition
						const bool bShadow(XFTSHADOW_NONE != maSdrFormTextAttribute.getFormTextShadow());

						if(bShadow)
						{
							if(XFTSHADOW_NORMAL == maSdrFormTextAttribute.getFormTextShadow())
							{
								aNewShadowTransform.translate(
                                    maSdrFormTextAttribute.getFormTextShdwXVal(), 
                                    -maSdrFormTextAttribute.getFormTextShdwYVal());
							}
							else // XFTSHADOW_SLANT
							{
								double fScaleValue(maSdrFormTextAttribute.getFormTextShdwYVal() / 100.0);
								double fShearValue(-maSdrFormTextAttribute.getFormTextShdwXVal() * F_PI1800);
								
								aNewShadowTransform.scale(1.0, fScaleValue);
								aNewShadowTransform.shearX(sin(fShearValue));
								aNewShadowTransform.scale(1.0, cos(fShearValue));
							}
						}

						switch(maSdrFormTextAttribute.getFormTextStyle())
						{
							case XFT_ROTATE :
							{
								aEndPos = basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart + fPortionLength, fPolyLength);
								const basegfx::B2DVector aDirection(aEndPos - aStartPos);
								aNewTransformB.rotate(atan2(aDirection.getY(), aDirection.getX()));
								aNewTransformB.translate(aStartPos.getX(), aStartPos.getY());
								
								break;
							}
							case XFT_UPRIGHT :
							{
								aNewTransformB.translate(aStartPos.getX() - (fPortionLength / 2.0), aStartPos.getY());
								
								break;
							}
							case XFT_SLANTX :
							{
								aEndPos = basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart + fPortionLength, fPolyLength);
								const basegfx::B2DVector aDirection(aEndPos - aStartPos);
								const double fShearValue(atan2(aDirection.getY(), aDirection.getX()));
                                const double fSin(sin(fShearValue));
                                const double fCos(cos(fShearValue));

   								aNewTransformB.shearX(-fSin);

								// Scale may lead to objects without height since fCos == 0.0 is possible.
								// Renderers need to handle that, it's not a forbidden value and does not
								// need to be avoided
                                aNewTransformB.scale(1.0, fCos);
                                aNewTransformB.translate(aStartPos.getX() - (fPortionLength / 2.0), aStartPos.getY());
								
								break;
							}
							case XFT_SLANTY :
							{
								aEndPos = basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart + fPortionLength, fPolyLength);
								const basegfx::B2DVector aDirection(aEndPos - aStartPos);
								const double fShearValue(atan2(aDirection.getY(), aDirection.getX()));
                                const double fCos(cos(fShearValue));
                                const double fTan(tan(fShearValue));
								
								// shear to 'stand' on the curve
								aNewTransformB.shearY(fTan);

								// scale in X to make as tight as needed. As with XFT_SLANT_X, this may
								// lead to primitives without width which the renderers will handle
   								aNewTransformA.scale(fCos, 1.0);

								aNewTransformB.translate(aStartPos.getX(), aStartPos.getY());
								
								break;
							}
							default : break; // XFT_NONE
						}

						// distance from path?
						if(maSdrFormTextAttribute.getFormTextDistance())
						{
							if(aEndPos.equal(aStartPos))
							{
								aEndPos = basegfx::tools::getPositionAbsolute(aPolygonCandidate, fPolyStart + fPortionLength, fPolyLength);
							}

							// use back vector (aStartPos - aEndPos) here to get mirrored perpendicular as in old stuff
							const basegfx::B2DVector aPerpendicular(
                                basegfx::getNormalizedPerpendicular(aStartPos - aEndPos) * 
                                maSdrFormTextAttribute.getFormTextDistance());
							aNewTransformB.translate(aPerpendicular.getX(), aPerpendicular.getY());
						}

						if(pCandidate->getText().Len() && nNextGlyphLen)
						{
							const xub_StrLen nPortionIndex(pCandidate->getPortionIndex(nUsedTextLength, nNextGlyphLen));
							::std::vector< double > aNewDXArray;
							
							if(nNextGlyphLen > 1 && pCandidate->getDoubleDXArray().size())
							{
								// copy DXArray for portion
								aNewDXArray.insert(
									aNewDXArray.begin(),
									pCandidate->getDoubleDXArray().begin() + nPortionIndex,
									pCandidate->getDoubleDXArray().begin() + (nPortionIndex + nNextGlyphLen));

								if(nPortionIndex > 0)
								{
									// adapt to portion start
									double fDXOffset= *(pCandidate->getDoubleDXArray().begin() + (nPortionIndex - 1));
									::std::transform(
										aNewDXArray.begin(), aNewDXArray.end(),
										aNewDXArray.begin(), ::std::bind2nd(::std::minus<double>(), fDXOffset));
								}

								if(bAutosizeScale)
								{
									// when autosize scaling, adapt to DXArray, too
									::std::transform(
										aNewDXArray.begin(), aNewDXArray.end(),
										aNewDXArray.begin(), ::std::bind2nd(::std::multiplies<double>(), fAutosizeScaleFactor));
								}
							}

                            if(bShadow)
						    {
    						    // shadow primitive creation
							    const Color aShadowColor(maSdrFormTextAttribute.getFormTextShdwColor());
							    const basegfx::BColor aRGBShadowColor(aShadowColor.getBColor());

							    drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pNew = 
                                    new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
								        aNewTransformB * aNewShadowTransform * aNewTransformA, 
								        pCandidate->getText(), 
								        nPortionIndex, 
								        nNextGlyphLen,
								        aNewDXArray, 
								        aCandidateFontAttribute, 
                                        pCandidate->getLocale(),
								        aRGBShadowColor);
								
							    mrShadowDecomposition.push_back(pNew);
						    }

						    {
    						    // primitive creation
							    const Color aColor(pCandidate->getFont().GetColor());
							    const basegfx::BColor aRGBColor(aColor.getBColor());

							    drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pNew = 
                                    new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
								        aNewTransformB * aNewTransformA, 
								        pCandidate->getText(), 
								        nPortionIndex, 
								        nNextGlyphLen, 
								        aNewDXArray, 
								        aCandidateFontAttribute, 
                                        pCandidate->getLocale(),
								        aRGBColor);
    							
							    mrDecomposition.push_back(pNew);
						    }
                        }

						// consume from portion // no += here, xub_StrLen is sal_uInt16 and the compiler will gererate a warning here
						nUsedTextLength = nUsedTextLength + nNextGlyphLen;

						// consume from polygon
						fPolyStart += fPortionLength;
					}
				}
			}
		}
	};
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////
// primitive decomposition helpers

namespace
{
	void impAddPolygonStrokePrimitives(
		const basegfx::B2DPolyPolygonVector& rB2DPolyPolyVector, 
		const basegfx::B2DHomMatrix& rTransform, 
		const drawinglayer::attribute::LineAttribute& rLineAttribute, 
		const drawinglayer::attribute::StrokeAttribute& rStrokeAttribute, 
		std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rTarget)
	{
		for(basegfx::B2DPolyPolygonVector::const_iterator aPolygon(rB2DPolyPolyVector.begin()); aPolygon != rB2DPolyPolyVector.end(); aPolygon++)
		{
			// prepare PolyPolygons
			basegfx::B2DPolyPolygon aB2DPolyPolygon = *aPolygon;
			aB2DPolyPolygon.transform(rTransform);
			
			for(sal_uInt32 a(0L); a < aB2DPolyPolygon.count(); a++)
			{
				// create one primitive per polygon
				drawinglayer::primitive2d::PolygonStrokePrimitive2D* pNew = 
                    new drawinglayer::primitive2d::PolygonStrokePrimitive2D(
                        aB2DPolyPolygon.getB2DPolygon(a), rLineAttribute, rStrokeAttribute);
				rTarget.push_back(pNew);
			}
		}
	}

	drawinglayer::primitive2d::Primitive2DSequence impAddPathTextOutlines(
		const std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rSource, 
        const drawinglayer::attribute::SdrFormTextOutlineAttribute& rOutlineAttribute)
	{
		std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aNewPrimitives;
		
		for(sal_uInt32 a(0L); a < rSource.size(); a++)
		{
			const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* pTextCandidate = dynamic_cast< const drawinglayer::primitive2d::TextSimplePortionPrimitive2D* >(rSource[a]);

			if(pTextCandidate)
			{
				basegfx::B2DPolyPolygonVector aB2DPolyPolyVector;
			    basegfx::B2DHomMatrix aPolygonTransform;

                // get text outlines and their object transformation
                pTextCandidate->getTextOutlinesAndTransformation(aB2DPolyPolyVector, aPolygonTransform);

				if(!aB2DPolyPolyVector.empty())
                {
				    // create stroke primitives
				    std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aStrokePrimitives;
				    impAddPolygonStrokePrimitives(
                        aB2DPolyPolyVector, 
                        aPolygonTransform, 
                        rOutlineAttribute.getLineAttribute(), 
                        rOutlineAttribute.getStrokeAttribute(), 
                        aStrokePrimitives);
				    const sal_uInt32 nStrokeCount(aStrokePrimitives.size());

				    if(nStrokeCount)
				    {
					    if(rOutlineAttribute.getTransparence())
					    {
						    // create UnifiedTransparencePrimitive2D
						    drawinglayer::primitive2d::Primitive2DSequence aStrokePrimitiveSequence(nStrokeCount);

						    for(sal_uInt32 b(0L); b < nStrokeCount; b++)
						    {
							    aStrokePrimitiveSequence[b] = drawinglayer::primitive2d::Primitive2DReference(aStrokePrimitives[b]);
						    }

						    drawinglayer::primitive2d::UnifiedTransparencePrimitive2D* pNew2 = 
                                new drawinglayer::primitive2d::UnifiedTransparencePrimitive2D(
                                    aStrokePrimitiveSequence, 
                                    (double)rOutlineAttribute.getTransparence() / 100.0);
						    aNewPrimitives.push_back(pNew2);
					    }
					    else
					    {
						    // add polygons to rDecomposition as polygonStrokePrimitives
						    aNewPrimitives.insert(aNewPrimitives.end(), aStrokePrimitives.begin(), aStrokePrimitives.end());
					    }
                    }
				}
			}
		}

		const sal_uInt32 nNewCount(aNewPrimitives.size());

		if(nNewCount)
		{
			drawinglayer::primitive2d::Primitive2DSequence aRetval(nNewCount);

			for(sal_uInt32 a(0L); a < nNewCount; a++)
			{
				aRetval[a] = drawinglayer::primitive2d::Primitive2DReference(aNewPrimitives[a]);
			}

			return aRetval;
		}
		else
		{
			return drawinglayer::primitive2d::Primitive2DSequence();
		}
	}
} // end of anonymous namespace

//////////////////////////////////////////////////////////////////////////////
// primitive decomposition

void SdrTextObj::impDecomposePathTextPrimitive(
	drawinglayer::primitive2d::Primitive2DSequence& rTarget, 
	const drawinglayer::primitive2d::SdrPathTextPrimitive2D& rSdrPathTextPrimitive,
	const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
{
	drawinglayer::primitive2d::Primitive2DSequence aRetvalA;
	drawinglayer::primitive2d::Primitive2DSequence aRetvalB;

	// prepare outliner
	SdrOutliner& rOutliner = ImpGetDrawOutliner();
	rOutliner.SetUpdateMode(true);
	rOutliner.Clear();
	rOutliner.SetPaperSize(Size(LONG_MAX,LONG_MAX));
	rOutliner.SetText(rSdrPathTextPrimitive.getOutlinerParaObject());

	// set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
	rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));

	// now break up to text portions
	impTextBreakupHandler aConverter(rOutliner);
	const ::std::vector< impPathTextPortion > rPathTextPortions = aConverter.decompositionPathTextPrimitive();

	if(!rPathTextPortions.empty())
	{
		// get FormText and polygon values
        const drawinglayer::attribute::SdrFormTextAttribute& rFormTextAttribute = rSdrPathTextPrimitive.getSdrFormTextAttribute();
		const basegfx::B2DPolyPolygon& rPathPolyPolygon(rSdrPathTextPrimitive.getPathPolyPolygon());

		// get loop count
		sal_uInt32 nLoopCount(rPathPolyPolygon.count());

		if(rOutliner.GetParagraphCount() < nLoopCount)
		{
			nLoopCount = rOutliner.GetParagraphCount();
		}

		if(nLoopCount)
		{
			// prepare common decomposition stuff
			std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aRegularDecomposition;
			std::vector< drawinglayer::primitive2d::BasePrimitive2D* > aShadowDecomposition;
			impPolygonParagraphHandler aPolygonParagraphHandler(
                rFormTextAttribute, 
				aRegularDecomposition, 
				aShadowDecomposition);
			sal_uInt32 a;

			for(a = 0L; a < nLoopCount; a++)
			{
				// filter text portions for this paragraph
				::std::vector< const impPathTextPortion* > aParagraphTextPortions;

				for(sal_uInt32 b(0L); b < rPathTextPortions.size(); b++)
				{
					const impPathTextPortion& rCandidate = rPathTextPortions[b];

					if(rCandidate.getParagraph() == a)
					{
						aParagraphTextPortions.push_back(&rCandidate);
					}
				}

				// handle data pair polygon/ParagraphTextPortions
				if(!aParagraphTextPortions.empty())
				{
					aPolygonParagraphHandler.HandlePair(rPathPolyPolygon.getB2DPolygon(a), aParagraphTextPortions);
				}
			}

			const sal_uInt32 nShadowCount(aShadowDecomposition.size());
			const sal_uInt32 nRegularCount(aRegularDecomposition.size());
			
			if(nShadowCount)
			{
				// add shadow primitives to decomposition
				aRetvalA.realloc(nShadowCount);

				for(a = 0L; a < nShadowCount; a++)
				{
					aRetvalA[a] = drawinglayer::primitive2d::Primitive2DReference(aShadowDecomposition[a]);
				}

				// evtl. add shadow outlines
				if(rFormTextAttribute.getFormTextOutline() 
					&& !rFormTextAttribute.getShadowOutline().isDefault())
				{
					const drawinglayer::primitive2d::Primitive2DSequence aOutlines(
                        impAddPathTextOutlines(
							aShadowDecomposition, 
							rFormTextAttribute.getShadowOutline()));
					
					drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aRetvalA, aOutlines);
				}
			}

			if(nRegularCount)
			{
				// add normal primitives to decomposition
				aRetvalB.realloc(nRegularCount);

				for(a = 0L; a < nRegularCount; a++)
				{
					aRetvalB[a] = drawinglayer::primitive2d::Primitive2DReference(aRegularDecomposition[a]);
				}

				// evtl. add outlines
				if(rFormTextAttribute.getFormTextOutline() 
					&& !rFormTextAttribute.getOutline().isDefault())
				{
					const drawinglayer::primitive2d::Primitive2DSequence aOutlines(
                        impAddPathTextOutlines(
							aRegularDecomposition, 
							rFormTextAttribute.getOutline()));

					drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(aRetvalB, aOutlines);
				}
			}
		}
	}

	// cleanup outliner
	rOutliner.SetDrawPortionHdl(Link());
	rOutliner.Clear();
	rOutliner.setVisualizedPage(0);

	// concatenate all results
	drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aRetvalA);
	drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(rTarget, aRetvalB);
}

//////////////////////////////////////////////////////////////////////////////
// eof
