Commits

Anonymous committed 46b7b02

#i10000#,#i102100#: fix broken merge cause by CRLF

  • Participants
  • Parent commits c435fb9

Comments (0)

Files changed (1)

File svx/source/msfilter/msdffimp.cxx

+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: msdffimp.cxx,v $
+ * $Revision: 1.157 $
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org.  If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_svx.hxx"
+/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
+#include <com/sun/star/embed/Aspects.hpp>
+
+#include <math.h>
+#include <limits.h>
+#include <vector>
+#include <osl/endian.h>
+#include <tools/solar.h>               // UINTXX
+#include <rtl/math.hxx>
+
+#include <sot/clsids.hxx>
+#include <toolkit/helper/vclunohelper.hxx>
+#include <unotools/streamwrap.hxx>
+#include <comphelper/processfactory.hxx>
+#include <sot/exchange.hxx>
+#include <sot/storinfo.hxx>
+#include <vcl/cvtgrf.hxx>
+
+#include "viscache.hxx"
+
+// SvxItem-Mapping. Wird benoetigt um die SvxItem-Header erfolgreich zu includen
+#include <svx/eeitem.hxx>
+#ifndef _EDITDATA_HXX
+#include <svx/editdata.hxx>
+#endif
+
+#include <svtools/urihelper.hxx>
+
+//      textitem.hxx        editdata.hxx
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+//      paraitem.hxx       editdata.hxx
+
+
+#include <tools/stream.hxx>
+#include <tools/debug.hxx>
+#ifndef _TOOLS_ZCODEC_HXX
+#include <tools/zcodec.hxx>
+#endif
+#ifndef _UNOTOOLS_UCBSTREAMHELPER_HXX
+#include <unotools/ucbstreamhelper.hxx>
+#endif
+#include <unotools/localfilehelper.hxx>
+#include <svx/escherex.hxx>
+#include <basegfx/range/b2drange.hxx>
+#include <com/sun/star/container/XIdentifierContainer.hpp>
+#include <com/sun/star/drawing/XGluePointsSupplier.hpp>
+#include <com/sun/star/drawing/Position3D.hpp>
+#include <com/sun/star/drawing/Direction3D.hpp>
+#include <com/sun/star/drawing/GluePoint2.hpp>
+#include <com/sun/star/drawing/XShapes.hpp>
+#include <svx/charscaleitem.hxx>
+#include <svx/kernitem.hxx>
+#include <svtools/filter.hxx>
+#include <tools/string.hxx>
+#ifndef _TOOLS_URLOBJ_HXX
+#include <tools/urlobj.hxx>
+#endif
+#include <vcl/virdev.hxx>
+#include <vcl/bmpacc.hxx>
+#ifndef _SVSTOR_HXX //autogen
+#include <sot/storage.hxx>
+#endif
+#include <sfx2/docfac.hxx>
+#include <sfx2/docfilt.hxx>
+#include <sfx2/docfile.hxx>
+#include <sfx2/fcontnr.hxx>
+#include <sfx2/module.hxx>
+//#ifndef _SFX_INTERNO_HXX
+//#include <sfx2/interno.hxx>
+//#endif
+
+#ifndef _SDGCPITM_HXX
+
+//#endif
+#include <svx/sdgcpitm.hxx>
+#endif
+#include <svx/sdgmoitm.hxx>
+#include <svx/tstpitem.hxx>
+#include <svx/fmmodel.hxx>
+#include <svx/svdmodel.hxx>
+#include <svx/svdobj.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/svdogrp.hxx>
+#include <svx/svdograf.hxx>
+#include <svx/svdotext.hxx>
+#include <svx/svdorect.hxx>
+#ifndef _SVDOCAPT_HXX
+#include <svx/svdocapt.hxx>
+#endif
+#include <svx/svdoedge.hxx>
+#include <svx/svdocirc.hxx>
+#include <svx/svdoutl.hxx>
+#include <svx/svdoole2.hxx>
+#include <svx/svdopath.hxx>
+#include <svx/frmdir.hxx>
+#include <svx/frmdiritem.hxx>
+#include <svx/svdtrans.hxx>
+#include <svx/sxenditm.hxx>
+#include <svx/sdgluitm.hxx>
+#include <svx/fhgtitem.hxx>
+#include <svx/wghtitem.hxx>
+#include <svx/postitem.hxx>
+#include <svx/udlnitem.hxx>
+#include <svx/crsditem.hxx>
+#include <svx/shdditem.hxx>
+#include <fontitem.hxx>
+#include <svx/colritem.hxx>
+#include <svx/sxekitm.hxx>
+#include <bulitem.hxx>
+#include <svx/polysc3d.hxx>
+#include <svx/extrud3d.hxx>
+#include "svditer.hxx"
+#include <svx/xpoly.hxx>
+#include "xattr.hxx"
+
+#ifndef _IMPGRF_HXX //autogen
+#include "impgrf.hxx"
+#endif
+#include <svx/msdffimp.hxx> // extern sichtbare Header-Datei
+#include <svx/outliner.hxx>
+#include <svx/outlobj.hxx>
+#include <svx/editobj.hxx>
+#include <svx/editeng.hxx>
+#include "gallery.hxx"
+#include <com/sun/star/drawing/ShadeMode.hpp>
+#include <svtools/itempool.hxx>
+#include <vcl/svapp.hxx>
+#include <svx/svx3ditems.hxx>
+#include <svx/svdoashp.hxx>
+#include <svx/sdasaitm.hxx>
+#ifndef _UCBHELPER_CONTENT_HXX_
+#include <ucbhelper/content.hxx>
+#endif
+#ifndef _UCBHELPER_CONTENTBROKER_HXX_
+#include <ucbhelper/contentbroker.hxx>
+#endif
+#include <vos/xception.hxx>
+#ifndef _VOS_NO_NAMESPACE
+using namespace vos;
+#endif
+#include "../customshapes/EnhancedCustomShapeTypeNames.hxx"
+#include "../customshapes/EnhancedCustomShapeGeometry.hxx"
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
+#include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
+#ifndef __com_sun_star_beans_PropertyValues_hpp__
+#include <com/sun/star/beans/PropertyValues.hpp>
+#endif
+#include <com/sun/star/drawing/ProjectionMode.hpp>
+#include "../customshapes/EnhancedCustomShape2d.hxx"
+
+using namespace ::com::sun::star    ;
+using namespace ::com::sun::star::drawing;
+using namespace uno		            ;
+using namespace beans		        ;
+using namespace drawing	            ;
+using namespace container	        ;
+
+#define ITEMVALUE(ItemSet,Id,Cast)  ((const Cast&)(ItemSet).Get(Id)).GetValue()
+
+// static counter for OLE-Objects
+static sal_uInt32 nMSOleObjCntr = 0;
+#define MSO_OLE_Obj "MSO_OLE_Obj"
+
+
+/*************************************************************************/
+BOOL Impl_OlePres::Read( SvStream & rStm )
+{
+	ULONG nBeginPos = rStm.Tell();
+	INT32 n;
+	rStm >> n;
+	if( n != -1 )
+	{
+		pBmp = new Bitmap;
+		rStm >> *pBmp;
+		if( rStm.GetError() == SVSTREAM_OK )
+		{
+			nFormat = FORMAT_BITMAP;
+			aSize = pBmp->GetPrefSize();
+			MapMode aMMSrc;
+			if( !aSize.Width() || !aSize.Height() )
+			{
+				// letzte Chance
+				aSize = pBmp->GetSizePixel();
+				aMMSrc = MAP_PIXEL;
+			}
+			else
+				aMMSrc = pBmp->GetPrefMapMode();
+			MapMode aMMDst( MAP_100TH_MM );
+			aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
+			return TRUE;
+		}
+		else
+		{
+			delete pBmp;
+			pBmp = NULL;
+
+			pMtf = new GDIMetaFile();
+			rStm.ResetError();
+			rStm >> *pMtf;
+			if( rStm.GetError() == SVSTREAM_OK )
+			{
+				nFormat = FORMAT_GDIMETAFILE;
+				aSize = pMtf->GetPrefSize();
+				MapMode aMMSrc = pMtf->GetPrefMapMode();
+				MapMode aMMDst( MAP_100TH_MM );
+				aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
+				return TRUE;
+			}
+			else
+			{
+				delete pMtf;
+				pMtf = NULL;
+			}
+		}
+
+	}
+
+	rStm.ResetError();
+	rStm.Seek( nBeginPos );
+	nFormat = ReadClipboardFormat( rStm );
+	// JobSetup, bzw. TargetDevice ueberlesen
+	// Information aufnehmen, um sie beim Schreiben nicht zu verlieren
+	nJobLen = 0;
+	rStm >> nJobLen;
+	if( nJobLen >= 4 )
+	{
+		nJobLen -= 4;
+		if( nJobLen )
+		{
+			pJob = new BYTE[ nJobLen ];
+			rStm.Read( pJob, nJobLen );
+		}
+	}
+	else
+	{
+		rStm.SetError( SVSTREAM_GENERALERROR );
+		return FALSE;
+	}
+	UINT32 nAsp;
+	rStm >> nAsp;
+	USHORT nSvAsp = USHORT( nAsp );
+	SetAspect( nSvAsp );
+	rStm.SeekRel( 4 ); //L-Index ueberlesen
+	rStm >> nAdvFlags;
+	rStm.SeekRel( 4 ); //Compression
+	UINT32 nWidth  = 0;
+	UINT32 nHeight = 0;
+	UINT32 nSize   = 0;
+	rStm >> nWidth >> nHeight >> nSize;
+	aSize.Width() = nWidth;
+	aSize.Height() = nHeight;
+
+	if( nFormat == FORMAT_GDIMETAFILE )
+	{
+		pMtf = new GDIMetaFile();
+		ReadWindowMetafile( rStm, *pMtf, NULL );
+	}
+	else if( nFormat == FORMAT_BITMAP )
+	{
+		pBmp = new Bitmap();
+		rStm >> *pBmp;
+	}
+	else
+	{
+		BYTE * p = new BYTE[ nSize ];
+		rStm.Read( p, nSize );
+		delete p;
+		return FALSE;
+	}
+	return TRUE;
+}
+
+/************************************************************************/
+void Impl_OlePres::Write( SvStream & rStm )
+{
+	WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE );
+	rStm << (INT32)(nJobLen +4);       // immer leeres TargetDevice
+	if( nJobLen )
+		rStm.Write( pJob, nJobLen );
+	rStm << (UINT32)nAspect;
+	rStm << (INT32)-1;      //L-Index immer -1
+	rStm << (INT32)nAdvFlags;
+	rStm << (INT32)0;       //Compression
+	rStm << (INT32)aSize.Width();
+	rStm << (INT32)aSize.Height();
+	ULONG nPos = rStm.Tell();
+	rStm << (INT32)0;
+
+	if( GetFormat() == FORMAT_GDIMETAFILE && pMtf )
+	{
+		// Immer auf 1/100 mm, bis Mtf-Loesung gefunden
+		// Annahme (keine Skalierung, keine Org-Verschiebung)
+		DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ),
+					"X-Skalierung im Mtf" );
+		DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ),
+					"Y-Skalierung im Mtf" );
+		DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(),
+					"Origin-Verschiebung im Mtf" );
+		MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit();
+		if( MAP_100TH_MM != nMU )
+		{
+			Size aPrefS( pMtf->GetPrefSize() );
+			Size aS( aPrefS );
+			aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM );
+
+			pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ),
+						 Fraction( aS.Height(), aPrefS.Height() ) );
+			pMtf->SetPrefMapMode( MAP_100TH_MM );
+			pMtf->SetPrefSize( aS );
+		}
+		WriteWindowMetafileBits( rStm, *pMtf );
+	}
+	else
+	{
+		DBG_ERROR( "unknown format" );
+	}
+	ULONG nEndPos = rStm.Tell();
+	rStm.Seek( nPos );
+	rStm << (UINT32)(nEndPos - nPos - 4);
+	rStm.Seek( nEndPos );
+}
+
+Impl_OlePres * CreateCache_Impl( SotStorage * pStor )
+{
+	SotStorageStreamRef xOleObjStm =pStor->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ),
+														STREAM_READ | STREAM_NOCREATE );
+	if( xOleObjStm->GetError() )
+		return NULL;
+	SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm );
+	if( xOleObjStor->GetError() )
+		return NULL;
+
+	String aStreamName;
+	if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) ) ) )
+		aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) );
+	else if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ) ) )
+		aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) );
+
+	if( aStreamName.Len() == 0 )
+		return NULL;
+
+
+	for( USHORT i = 1; i < 10; i++ )
+	{
+		SotStorageStreamRef xStm = xOleObjStor->OpenSotStream( aStreamName,
+												STREAM_READ | STREAM_NOCREATE );
+		if( xStm->GetError() )
+			break;
+
+		xStm->SetBufferSize( 8192 );
+        Impl_OlePres * pEle = new Impl_OlePres( 0 );
+		if( pEle->Read( *xStm ) && !xStm->GetError() )
+		{
+			if( pEle->GetFormat() == FORMAT_GDIMETAFILE || pEle->GetFormat() == FORMAT_BITMAP )
+				return pEle;
+		}
+		delete pEle;
+		aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres00" ) );
+		aStreamName += String( i );
+	};
+	return NULL;
+}
+
+
+
+//---------------------------------------------------------------------------
+//  Hilfs Klassen aus MSDFFDEF.HXX
+//---------------------------------------------------------------------------
+
+SvStream& operator>>( SvStream& rIn, DffRecordHeader& rRec )
+{
+	rRec.nFilePos = rIn.Tell();
+	UINT16 nTmp(0);
+	rIn >> nTmp;
+	rRec.nImpVerInst = nTmp;
+	rRec.nRecVer = sal::static_int_cast< BYTE >(nTmp & 0x000F);
+	rRec.nRecInstance = nTmp >> 4;
+	rIn >> rRec.nRecType;
+	rIn >> rRec.nRecLen;
+	return rIn;
+}
+
+// Masse fuer dashed lines
+#define LLEN_MIDDLE         (450)
+#define LLEN_SPACE_MIDDLE   (360)
+#define LLEN_LONG           (LLEN_MIDDLE * 2)
+#define LLEN_SPACE_LONG     (LLEN_SPACE_MIDDLE + 20)
+#define LLEN_POINT          (LLEN_MIDDLE / 4)
+#define LLEN_SPACE_POINT    (LLEN_SPACE_MIDDLE / 4)
+
+SvStream& operator>>( SvStream& rIn, DffPropSet& rRec )
+{
+	rRec.InitializePropSet();
+
+	DffRecordHeader aHd;
+	rIn >> aHd;
+	UINT32 nPropCount = aHd.nRecInstance;
+
+	// FilePos der ComplexData merken
+	UINT32 nComplexDataFilePos = rIn.Tell() + ( nPropCount * 6 );
+
+	for( UINT32 nPropNum = 0; nPropNum < nPropCount; nPropNum++ )
+	{
+		sal_uInt16 nTmp;
+		sal_uInt32 nRecType, nContent, nContentEx = 0xffff0000;
+		rIn >> nTmp
+			>> nContent;
+
+		nRecType = nTmp & 0x3fff;
+
+		if ( nRecType > 0x3ff )
+			break;
+		if ( ( nRecType & 0x3f ) == 0x3f )
+		{	// clear flags that have to be cleared
+			rRec.mpContents[ nRecType ] &= ( ( nContent >> 16 ) ^ 0xffffffff );
+			// set flags that have to be set
+			rRec.mpContents[ nRecType ] |= nContent;
+			nContentEx |= ( nContent >> 16 );
+			rRec.Replace( nRecType, (void*)nContentEx );
+		}
+		else
+		{
+			DffPropFlags aPropFlag = { 1, 0, 0, 0 };
+			if ( nTmp & 0x4000 )
+				aPropFlag.bBlip = sal_True;
+			if ( nTmp & 0x8000 )
+				aPropFlag.bComplex = sal_True;
+			if ( aPropFlag.bComplex && nContent && ( nComplexDataFilePos < aHd.GetRecEndFilePos() ) )
+            {
+                // normally nContent is the complete size of the complex property,
+                // but this is not always true for IMsoArrays ( what the hell is a IMsoArray ? )
+
+                // I love special threatments :-(
+				if ( ( nRecType == DFF_Prop_pVertices ) || ( nRecType == DFF_Prop_pSegmentInfo )
+                    || ( nRecType == DFF_Prop_fillShadeColors ) || ( nRecType == DFF_Prop_lineDashStyle )
+                        || ( nRecType == DFF_Prop_pWrapPolygonVertices ) || ( nRecType == DFF_Prop_connectorPoints )
+							|| ( nRecType == DFF_Prop_Handles ) || ( nRecType == DFF_Prop_pFormulas )
+								|| ( nRecType == DFF_Prop_textRectangles ) )
+				{
+                    // now check if the current content size is possible, or 6 bytes too small
+					sal_uInt32  nOldPos = rIn.Tell();
+					sal_Int16   nNumElem, nNumElemReserved, nSize;
+
+                    rIn.Seek( nComplexDataFilePos );
+					rIn >>  nNumElem >> nNumElemReserved >> nSize;
+                    if ( nNumElemReserved >= nNumElem )
+                    {
+                        // the size of these array elements is nowhere defined,
+                        // what if the size is negative ?
+                        // ok, we will make it positive and shift it.
+                        // for -16 this works
+						if ( nSize < 0 )
+							nSize = ( -nSize ) >> 2;
+                        sal_uInt32 nDataSize = (sal_uInt32)( nSize * nNumElem );
+
+                        // sometimes the content size is 6 bytes too small (array header information is missing )
+                        if ( nDataSize == nContent )
+                            nContent += 6;
+
+                        // check if array fits into the PropertyContainer
+                        if ( ( nComplexDataFilePos + nContent ) > aHd.GetRecEndFilePos() )
+                            nContent = 0;
+                    }
+                    else
+                        nContent = 0;
+					rIn.Seek( nOldPos );
+				}
+                if ( nContent )
+                {
+        		    nContentEx = nComplexDataFilePos;   // insert the filepos of this property;
+                    nComplexDataFilePos += nContent;    // store filepos, that is used for the next complex property
+                }
+                else                                    // a complex property needs content
+                    aPropFlag.bSet = sal_False;         // otherwise something is wrong
+			}
+			rRec.mpContents[ nRecType ] = nContent;
+			rRec.mpFlags[ nRecType ] = aPropFlag;
+			rRec.Insert( nRecType, (void*)nContentEx );
+		}
+	}
+	aHd.SeekToEndOfRecord( rIn );
+	return rIn;
+}
+
+void DffPropSet::InitializePropSet() const
+{
+    /*
+    cmc:
+    " Boolean properties are grouped in bitfields by property set; note that
+    the Boolean properties in each property set are contiguous. They are saved
+    under the property ID of the last Boolean property in the set, and are
+    placed in the value field in reverse order starting with the last property
+    in the low bit. "
+
+    e.g.
+
+    fEditedWrap
+    fBehindDocument
+    fOnDblClickNotify
+    fIsButton
+    fOneD
+    fHidden
+    fPrint
+
+    are all part of a group and all are by default false except for fPrint,
+    which equates to a default bit sequence for the group of 0000001 -> 0x1
+
+    If at a later stage word sets fBehindDocument away from the default it
+    will be done by having a property named fPrint whose bitsequence will have
+    the fBehindDocument bit set. e.g. a DFF_Prop_fPrint with value 0x200020
+    has set bit 6 on so as to enable fBehindDocument (as well as disabling
+    everything else)
+    */
+
+	memset( ( (DffPropSet*) this )->mpFlags, 0, 0x400 * sizeof(DffPropFlags) );
+	( (DffPropSet*) this )->Clear();
+
+	DffPropFlags nFlags = { 1, 0, 0, 1 };
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_LockAgainstGrouping ] = 0x0000;		//0x01ff0000;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_LockAgainstGrouping ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_LockAgainstGrouping, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_FitTextToShape ] = 0x0010;				//0x001f0010;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_FitTextToShape ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_FitTextToShape, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_gtextFStrikethrough ] = 0x0000;		//0xffff0000;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_gtextFStrikethrough ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_gtextFStrikethrough, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_pictureActive ] = 0x0000;				//0x000f0000;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_pictureActive ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_pictureActive, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fFillOK ] = 0x0039;					//0x003f0039;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fFillOK ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fFillOK, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoFillHitTest ] = 0x001c;				//0x001f001c;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoFillHitTest ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fNoFillHitTest, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoLineDrawDash ] = 0x001e;			//0x001f000e;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoLineDrawDash ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fNoLineDrawDash, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fshadowObscured ] = 0x0000;			//0x00030000;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fshadowObscured ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fshadowObscured, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fPerspective ] = 0x0000;				//0x00010000;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPerspective ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fPerspective, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DLightFace ] = 0x0001;				//0x000f0001;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DLightFace ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fc3DLightFace, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DFillHarsh ] = 0x0016;				//0x001f0016;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DFillHarsh ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fc3DFillHarsh, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fBackground ] = 0x0000;				//0x001f0000;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fBackground ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fBackground, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fCalloutLengthSpecified ] = 0x0010;	//0x00ef0010;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fCalloutLengthSpecified ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fCalloutLengthSpecified, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fPrint ] = 0x0001;						//0x00ef0001;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPrint ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fPrint, (void*)0xffff0000 );
+
+	( (DffPropSet*) this )->mpContents[ DFF_Prop_fillColor ] = 0xffffff;
+	( (DffPropSet*) this )->mpFlags[ DFF_Prop_fillColor ] = nFlags;
+	( (DffPropSet*) this )->Insert( DFF_Prop_fillColor, (void*)0xffff0000 );
+}
+
+void DffPropSet::Merge( DffPropSet& rMaster ) const
+{
+	for ( void* pDummy = rMaster.First(); pDummy; pDummy = rMaster.Next() )
+	{
+		UINT32 nRecType = rMaster.GetCurKey();
+		if ( ( nRecType & 0x3f ) == 0x3f )		// this is something called FLAGS
+		{
+			UINT32 nCurrentFlags = mpContents[ nRecType ];
+			UINT32 nMergeFlags = rMaster.mpContents[ nRecType ];
+			nMergeFlags &=  ( nMergeFlags >> 16 ) | 0xffff0000;				// clearing low word
+			nMergeFlags &= ( ( nCurrentFlags & 0xffff0000 )					// remove allready hard set
+							| ( nCurrentFlags >> 16 ) ) ^ 0xffffffff;		// attributes from mergeflags
+			nCurrentFlags &= ( ( nMergeFlags & 0xffff0000 )					// apply zero master bits
+							| ( nMergeFlags >> 16 ) ) ^ 0xffffffff;
+			nCurrentFlags |= (UINT16)nMergeFlags;							// apply filled master bits
+			( (DffPropSet*) this )->mpContents[ nRecType ] = nCurrentFlags;
+
+
+			sal_uInt32 nNewContentEx = (sal_uInt32)(sal_uIntPtr)rMaster.GetCurObject();
+			if ( ((DffPropSet*)this)->Seek( nRecType ) )
+				nNewContentEx |= (sal_uInt32)(sal_uIntPtr)GetCurObject();
+			( (DffPropSet*) this )->Replace( nRecType, (void*)nNewContentEx );
+		}
+		else
+		{
+			if ( !IsProperty( nRecType ) || !IsHardAttribute( nRecType ) )
+			{
+				( (DffPropSet*) this )->mpContents[ nRecType ] = rMaster.mpContents[ nRecType ];
+				DffPropFlags nFlags( rMaster.mpFlags[ nRecType ] );
+				nFlags.bSoftAttr = TRUE;
+				( (DffPropSet*) this )->mpFlags[ nRecType ] = nFlags;
+				( (DffPropSet*) this )->Insert( nRecType, pDummy );
+			}
+		}
+	}
+}
+
+BOOL DffPropSet::IsHardAttribute( UINT32 nId ) const
+{
+	BOOL bRetValue = TRUE;
+	nId &= 0x3ff;
+	if ( ( nId & 0x3f ) >= 48 )	// is this a flag id
+	{
+		if ( ((DffPropSet*)this)->Seek( nId | 0x3f ) )
+		{
+			sal_uInt32 nContentEx = (sal_uInt32)(sal_uIntPtr)GetCurObject();
+			bRetValue = ( nContentEx & ( 1 << ( 0xf - ( nId & 0xf ) ) ) ) != 0;
+		}
+	}
+	else
+		bRetValue = ( mpFlags[ nId ].bSoftAttr == 0 );
+	return bRetValue;
+};
+
+UINT32 DffPropSet::GetPropertyValue( UINT32 nId, UINT32 nDefault ) const
+{
+	nId &= 0x3ff;
+	return ( mpFlags[ nId ].bSet ) ? mpContents[ nId ] : nDefault;
+};
+
+bool DffPropSet::GetPropertyBool( UINT32 nId, bool bDefault ) const
+{
+    UINT32 nBaseId = nId | 31;              // base ID to get the UINT32 property value
+    UINT32 nMask = 1 << (nBaseId - nId);    // bit mask of the boolean property
+
+    UINT32 nPropValue = GetPropertyValue( nBaseId, bDefault ? nMask : 0 );
+    return (nPropValue & nMask) != 0;
+}
+
+::rtl::OUString DffPropSet::GetPropertyString( UINT32 nId, SvStream& rStrm ) const
+{
+    sal_Size nOldPos = rStrm.Tell();
+    ::rtl::OUStringBuffer aBuffer;
+    sal_uInt32 nBufferSize = GetPropertyValue( nId );
+    if( (nBufferSize > 0) && SeekToContent( nId, rStrm ) )
+    {
+        sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufferSize / 2 );
+        aBuffer.ensureCapacity( nStrLen );
+        for( sal_Int32 nCharIdx = 0; nCharIdx < nStrLen; ++nCharIdx )
+        {
+            sal_uInt16 nChar = 0;
+            rStrm >> nChar;
+            if( nChar > 0 )
+                aBuffer.append( static_cast< sal_Unicode >( nChar ) );
+            else
+                break;
+        }
+    }
+    rStrm.Seek( nOldPos );
+    return aBuffer.makeStringAndClear();
+}
+
+void DffPropSet::SetPropertyValue( UINT32 nId, UINT32 nValue ) const
+{
+	if ( !mpFlags[ nId ].bSet )
+	{
+		( (DffPropSet*) this )->Insert( nId, (void*)nValue );
+		( (DffPropSet*) this )->mpFlags[ nId ].bSet = TRUE;
+	}
+	( (DffPropSet*) this )->mpContents[ nId ] = nValue;
+};
+
+BOOL DffPropSet::SeekToContent( UINT32 nRecType, SvStream& rStrm ) const
+{
+	nRecType &= 0x3ff;
+	if ( mpFlags[ nRecType ].bSet )
+	{
+		if ( mpFlags[ nRecType ].bComplex )
+		{
+			if ( ((DffPropSet*)this)->Seek( nRecType ) )
+			{
+				sal_uInt32 nOffset = (sal_uInt32)(sal_uIntPtr)GetCurObject();
+				if ( nOffset && ( ( nOffset & 0xffff0000 ) != 0xffff0000 ) )
+				{
+					rStrm.Seek( nOffset );
+					return TRUE;
+				}
+			}
+		}
+	}
+	return FALSE;
+}
+
+DffPropertyReader::DffPropertyReader( const SvxMSDffManager& rMan ) :
+	rManager( rMan ),
+	pDefaultPropSet( NULL )
+{
+	InitializePropSet();
+}
+
+void DffPropertyReader::SetDefaultPropSet( SvStream& rStCtrl, UINT32 nOffsDgg ) const
+{
+	delete pDefaultPropSet;
+	UINT32 nMerk = rStCtrl.Tell();
+	rStCtrl.Seek( nOffsDgg );
+	DffRecordHeader aRecHd;
+	rStCtrl >> aRecHd;
+	if ( aRecHd.nRecType == DFF_msofbtDggContainer )
+	{
+		if ( rManager.SeekToRec( rStCtrl, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
+		{
+			( (DffPropertyReader*) this )->pDefaultPropSet = new DffPropSet;
+			rStCtrl >> *pDefaultPropSet;
+		}
+	}
+	rStCtrl.Seek( nMerk );
+}
+
+#ifdef DBG_CUSTOMSHAPE
+void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData, UINT32 nShapeId ) const
+#else
+void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData ) const
+#endif
+{
+	ULONG nFilePos = rIn.Tell();
+	rIn >> (DffPropertyReader&)*this;
+
+	if ( IsProperty( DFF_Prop_hspMaster ) )
+	{
+		if ( rManager.SeekToShape( rIn, pClientData, GetPropertyValue( DFF_Prop_hspMaster ) ) )
+		{
+			DffRecordHeader aRecHd;
+			rIn >> aRecHd;
+			if ( rManager.SeekToRec( rIn, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
+			{
+				DffPropSet aMasterPropSet;
+				rIn >> aMasterPropSet;
+				Merge( aMasterPropSet );
+			}
+		}
+	}
+//	if ( pDefaultPropSet )
+//		Merge( *( pDefaultPropSet ) );
+
+	( (DffPropertyReader*) this )->mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) );
+
+#ifdef DBG_CUSTOMSHAPE
+
+	String aURLStr;
+
+	if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( String( RTL_CONSTASCII_STRINGPARAM( "d:\\ashape.dbg" ) ), aURLStr ) )
+	{
+		SvStream* pOut = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_WRITE );
+
+		if( pOut )
+		{
+			pOut->Seek( STREAM_SEEK_TO_END );
+
+			if ( IsProperty( DFF_Prop_adjustValue ) || IsProperty( DFF_Prop_pVertices ) )
+			{
+				pOut->WriteLine( "" );
+				ByteString aString( "ShapeId: " );
+				aString.Append( ByteString::CreateFromInt32( nShapeId ) );
+				pOut->WriteLine( aString );
+			}
+			for ( sal_uInt32 i = DFF_Prop_adjustValue; i <=	DFF_Prop_adjust10Value; i++ )
+			{
+				if ( IsProperty( i ) )
+				{
+					ByteString aString( "Prop_adjustValue" );
+					aString.Append( ByteString::CreateFromInt32( ( i - DFF_Prop_adjustValue ) + 1 ) );
+					aString.Append( ":" );
+					aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
+					pOut->WriteLine( aString );
+				}
+			}
+			sal_Int32 i;
+			for ( i = 320; i < 383; i++ )
+			{
+				if ( ( i >= DFF_Prop_adjustValue ) && ( i <= DFF_Prop_adjust10Value ) )
+					continue;
+				if ( IsProperty( i ) )
+				{
+					if ( SeekToContent( i, rIn ) )
+					{
+						INT32 nLen = (INT32)GetPropertyValue( i );
+						if ( nLen )
+						{
+							pOut->WriteLine( "" );
+							ByteString aDesc( "Property:" );
+							aDesc.Append( ByteString::CreateFromInt32( i ) );
+							aDesc.Append( ByteString( "  Size:" ) );
+							aDesc.Append( ByteString::CreateFromInt32( nLen ) );
+							pOut->WriteLine( aDesc );
+							INT16	nNumElem, nNumElemMem, nNumSize;
+							rIn >> nNumElem >> nNumElemMem >> nNumSize;
+							aDesc = ByteString( "Entries: " );
+							aDesc.Append( ByteString::CreateFromInt32( nNumElem ) );
+							aDesc.Append( ByteString(  "  Size:" ) );
+							aDesc.Append( ByteString::CreateFromInt32( nNumSize ) );
+							pOut->WriteLine( aDesc );
+							if ( nNumSize < 0 )
+								nNumSize = ( ( -nNumSize ) >> 2 );
+							if ( !nNumSize )
+								nNumSize = 16;
+							nLen -= 6;
+							while ( nLen > 0 )
+							{
+								ByteString aString;
+								for ( UINT32 j = 0; nLen && ( j < ( nNumSize >> 1 ) ); j++ )
+								{
+									for ( UINT32 k = 0; k < 2; k++ )
+									{
+										if ( nLen )
+										{
+											BYTE nVal;
+											rIn >> nVal;
+											if ( ( nVal >> 4 ) > 9 )
+												*pOut << (BYTE)( ( nVal >> 4 ) + 'A' - 10 );
+											else
+												*pOut << (BYTE)( ( nVal >> 4 ) + '0' );
+
+											if ( ( nVal & 0xf ) > 9 )
+												*pOut << (BYTE)( ( nVal & 0xf ) + 'A' - 10 );
+											else
+												*pOut << (BYTE)( ( nVal & 0xf ) + '0' );
+
+											nLen--;
+										}
+									}
+									*pOut << (char)( ' ' );
+								}
+								pOut->WriteLine( aString );
+							}
+						}
+					}
+					else
+					{
+						ByteString aString( "Property" );
+						aString.Append( ByteString::CreateFromInt32( i ) );
+						aString.Append( ":" );
+						aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
+						pOut->WriteLine( aString );
+					}
+				}
+			}
+
+			delete pOut;
+		}
+	}
+
+#endif
+
+	rIn.Seek( nFilePos );
+}
+
+
+INT32 DffPropertyReader::Fix16ToAngle( INT32 nContent ) const
+{
+	INT32 nAngle = 0;
+	if ( nContent )
+	{
+		nAngle = ( (INT16)( nContent >> 16) * 100L ) + ( ( ( nContent & 0x0000ffff) * 100L ) >> 16 );
+		nAngle = NormAngle360( -nAngle );
+	}
+	return nAngle;
+}
+
+DffPropertyReader::~DffPropertyReader()
+{
+	delete pDefaultPropSet;
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+SvStream& operator>>( SvStream& rIn, SvxMSDffConnectorRule& rRule )
+{
+	rIn >> rRule.nRuleId
+		>> rRule.nShapeA
+		>> rRule.nShapeB
+		>> rRule.nShapeC
+		>> rRule.ncptiA
+		>> rRule.ncptiB;
+
+	return rIn;
+}
+
+SvxMSDffSolverContainer::SvxMSDffSolverContainer()
+{
+}
+
+SvxMSDffSolverContainer::~SvxMSDffSolverContainer()
+{
+	for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)aCList.First();
+			pPtr; pPtr = (SvxMSDffConnectorRule*)aCList.Next() )
+		delete pPtr;
+}
+
+SvStream& operator>>( SvStream& rIn, SvxMSDffSolverContainer& rContainer )
+{
+	DffRecordHeader aHd;
+	rIn >> aHd;
+	if ( aHd.nRecType == DFF_msofbtSolverContainer )
+	{
+		DffRecordHeader aCRule;
+		while ( ( rIn.GetError() == 0 ) && ( rIn.Tell() < aHd.GetRecEndFilePos() ) )
+		{
+			rIn >> aCRule;
+			if ( aCRule.nRecType == DFF_msofbtConnectorRule )
+			{
+				SvxMSDffConnectorRule* pRule = new SvxMSDffConnectorRule;
+				rIn >> *pRule;
+				rContainer.aCList.Insert( pRule, LIST_APPEND );
+			}
+			aCRule.SeekToEndOfRecord( rIn );
+		}
+	}
+	return rIn;
+}
+
+void SvxMSDffManager::SolveSolver( const SvxMSDffSolverContainer& rSolver )
+{
+    sal_Int32 i, nCnt;
+    for ( i = 0, nCnt = rSolver.aCList.Count(); i < nCnt; i++ )
+    {
+        SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)rSolver.aCList.GetObject( i );
+		if ( pPtr->pCObj )
+		{
+			for ( int nN = 0; nN < 2; nN++ )
+			{
+				SdrObject*  pO;
+				sal_uInt32  nC, nSpFlags;
+				sal_Bool    bTail;
+				if ( !nN )
+				{
+					bTail = sal_True;
+					pO = pPtr->pAObj;
+					nC = pPtr->ncptiA;
+                    nSpFlags = pPtr->nSpFlagsA;
+				}
+				else
+				{
+					bTail = sal_False;
+					pO = pPtr->pBObj;
+					nC = pPtr->ncptiB;
+                    nSpFlags = pPtr->nSpFlagsB;
+				}
+				if ( pO )
+				{
+					Any aAny;
+					SdrGluePoint aGluePoint;
+					Reference< XShape > aXShape( pO->getUnoShape(), UNO_QUERY );
+					Reference< XShape > aXConnector( pPtr->pCObj->getUnoShape(), UNO_QUERY );
+					SdrGluePointList* pList = pO->ForceGluePointList();
+
+                    sal_Bool bValidGluePoint = sal_False;
+					sal_Int32 nId = nC;
+                    sal_uInt32 nInventor = pO->GetObjInventor();
+
+					if( nInventor == SdrInventor )
+					{
+						sal_uInt32 nObjId = pO->GetObjIdentifier();
+						switch( nObjId )
+						{
+							case OBJ_GRUP :
+							case OBJ_GRAF :
+							case OBJ_RECT :
+							case OBJ_TEXT :
+							case OBJ_PAGE :
+							case OBJ_TEXTEXT :
+							case OBJ_wegFITTEXT :
+							case OBJ_wegFITALLTEXT :
+							case OBJ_TITLETEXT :
+							case OBJ_OUTLINETEXT :
+							{
+								if ( nC & 1 )
+								{
+									if ( nSpFlags & SP_FFLIPH )
+										nC ^= 2;    // 1 <-> 3
+								}
+								else
+								{
+									if ( nSpFlags & SP_FFLIPV )
+										nC ^= 1;    // 0 <-> 2
+								}
+								switch( nC )
+								{
+									case 0 :
+										nId = 0;	// SDRVERTALIGN_TOP;
+									break;
+									case 1 :
+										nId = 3;	// SDRHORZALIGN_RIGHT;
+									break;
+									case 2 :
+										nId = 2;	// SDRVERTALIGN_BOTTOM;
+									break;
+									case 3 :
+										nId = 1; // SDRHORZALIGN_LEFT;
+									break;
+								}
+								if ( nId <= 3 )
+									bValidGluePoint = sal_True;
+							}
+							break;
+							case OBJ_POLY :
+							case OBJ_PLIN :
+							case OBJ_LINE :
+							case OBJ_PATHLINE :
+							case OBJ_PATHFILL :
+							case OBJ_FREELINE :
+							case OBJ_FREEFILL :
+							case OBJ_SPLNLINE :
+							case OBJ_SPLNFILL :
+							case OBJ_PATHPOLY :
+							case OBJ_PATHPLIN :
+							{
+								if ( pList && ( pList->GetCount() > nC ) )
+								{
+									bValidGluePoint = sal_True;
+									nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
+								}
+								else
+								{
+									sal_Bool bNotFound = sal_True;
+
+									PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aXShape ) );
+									sal_uInt16 k, j, nPolySize = aPolyPoly.Count();
+									if ( nPolySize )
+									{
+										sal_uInt32  nPointCount = 0;
+										Rectangle aBoundRect( aPolyPoly.GetBoundRect() );
+										if ( aBoundRect.GetWidth() && aBoundRect.GetHeight() )
+										{
+											for ( k = 0; bNotFound && ( k < nPolySize ); k++ )
+											{
+												const Polygon& rPolygon = aPolyPoly.GetObject( k );
+												for ( j = 0; bNotFound && ( j < rPolygon.GetSize() ); j++ )
+												{
+													PolyFlags eFlags = rPolygon.GetFlags( j );
+													if ( eFlags == POLY_NORMAL )
+													{
+														if ( nC == nPointCount )
+														{
+															const Point& rPoint = rPolygon.GetPoint( j );
+															double fXRel = rPoint.X() - aBoundRect.Left();
+															double fYRel = rPoint.Y() - aBoundRect.Top();
+															sal_Int32 nWidth = aBoundRect.GetWidth();
+															if ( !nWidth )
+																nWidth = 1;
+															sal_Int32 nHeight= aBoundRect.GetHeight();
+															if ( !nHeight )
+																nHeight = 1;
+															fXRel /= (double)nWidth;
+															fXRel *= 10000;
+															fYRel /= (double)nHeight;
+															fYRel *= 10000;
+															aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) );
+															aGluePoint.SetPercent( sal_True );
+															aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
+															aGluePoint.SetEscDir( SDRESC_SMART );
+															nId = (sal_Int32)((*pList)[ pList->Insert( aGluePoint ) ].GetId() + 3 );
+															bNotFound = sal_False;
+														}
+														nPointCount++;
+													}
+												}
+											}
+										}
+									}
+									if ( !bNotFound )
+									{
+										bValidGluePoint = sal_True;
+									}
+								}
+							}
+							break;
+
+							case OBJ_CUSTOMSHAPE :
+							{
+								SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pO)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
+								const rtl::OUString	sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
+								const rtl::OUString	sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
+								sal_Int16 nGluePointType = EnhancedCustomShapeGluePointType::SEGMENTS;
+								com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePointType );
+								if ( pAny )
+									*pAny >>= nGluePointType;
+								else
+								{
+									const rtl::OUString	sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
+									rtl::OUString sShapeType;
+									pAny = aGeometryItem.GetPropertyValueByName( sType );
+									if ( pAny )
+										*pAny >>= sShapeType;
+									MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
+									nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType );
+								}
+								if ( nGluePointType == EnhancedCustomShapeGluePointType::CUSTOM )
+								{
+									if ( pList && ( pList->GetCount() > nC ) )
+									{
+										bValidGluePoint = sal_True;
+										nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
+									}
+								}
+								else if ( nGluePointType == EnhancedCustomShapeGluePointType::RECT )
+								{
+									if ( nC & 1 )
+									{
+										if ( nSpFlags & SP_FFLIPH )
+											nC ^= 2;    // 1 <-> 3
+									}
+									else
+									{
+										if ( nSpFlags & SP_FFLIPV )
+											nC ^= 1;    // 0 <-> 2
+									}
+									switch( nC )
+									{
+										case 0 :
+											nId = 0;	// SDRVERTALIGN_TOP;
+										break;
+										case 1 :
+											nId = 3;	// SDRHORZALIGN_RIGHT;
+										break;
+										case 2 :
+											nId = 2;	// SDRVERTALIGN_BOTTOM;
+										break;
+										case 3 :
+											nId = 1; // SDRHORZALIGN_LEFT;
+										break;
+									}
+									if ( nId <= 3 )
+										bValidGluePoint = sal_True;
+								}
+								else if ( nGluePointType == EnhancedCustomShapeGluePointType::SEGMENTS )
+								{
+									const rtl::OUString	sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
+									const rtl::OUString	sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
+
+									sal_uInt32 k, nPt = nC;
+									com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
+									pAny = aGeometryItem.GetPropertyValueByName( sPath, sSegments );
+									if ( pAny )
+									{
+										if ( *pAny >>= aSegments )
+										{
+											for ( nPt = 0, k = 1; nC && ( k < (sal_uInt32)aSegments.getLength() ); k++ )
+											{
+												sal_Int16 j, nCnt2 = aSegments[ k ].Count;
+												if ( aSegments[ k ].Command != EnhancedCustomShapeSegmentCommand::UNKNOWN )
+												{
+													for ( j = 0; nC && ( j < nCnt2 ); j++ )
+													{
+														switch( aSegments[ k ].Command )
+														{
+															case EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
+															case EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
+															case EnhancedCustomShapeSegmentCommand::LINETO :
+															case EnhancedCustomShapeSegmentCommand::MOVETO :
+															{
+																nC--;
+																nPt++;
+															}
+															break;
+															case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
+															case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
+															break;
+
+															case EnhancedCustomShapeSegmentCommand::CURVETO :
+															{
+																nC--;
+																nPt += 3;
+															}
+															break;
+
+															case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
+															case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
+															{
+																nC--;
+																nPt += 3;
+															}
+															break;
+															case EnhancedCustomShapeSegmentCommand::ARCTO :
+															case EnhancedCustomShapeSegmentCommand::ARC :
+															case EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
+															case EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
+															{
+																nC--;
+																nPt += 4;
+															}
+															break;
+														}
+													}
+												}
+											}
+										}
+									}
+									pAny = aGeometryItem.GetPropertyValueByName( sPath, sCoordinates );
+									if ( pAny )
+									{
+										com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
+										*pAny >>= aCoordinates;
+										if ( nPt < (sal_uInt32)aCoordinates.getLength() )
+										{
+											nId = 4;
+											com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPara = aCoordinates[ nPt ];
+											sal_Int32 nX = 0, nY = 0;
+											if ( ( rPara.First.Value >>= nX ) && ( rPara.Second.Value >>= nY ) )
+											{
+												const rtl::OUString	sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
+												com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
+												pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePoints );
+												if ( pAny )
+													*pAny >>= aGluePoints;
+												sal_Int32 nGluePoints = aGluePoints.getLength();
+												aGluePoints.realloc( nGluePoints + 1 );
+												EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].First, nX );
+												EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].Second, nY );
+												PropertyValue aProp;
+												aProp.Name = sGluePoints;
+												aProp.Value <<= aGluePoints;
+												aGeometryItem.SetPropertyValue( sPath, aProp );
+												bValidGluePoint = sal_True;
+												((SdrObjCustomShape*)pO)->SetMergedItem( aGeometryItem );
+												SdrGluePointList* pLst = pO->ForceGluePointList();
+												if ( pLst->GetCount() > nGluePoints )
+													nId = (sal_Int32)((*pLst)[ (sal_uInt16)nGluePoints ].GetId() + 3 );
+											}
+										}
+									}
+								}
+							}
+							break;
+						}
+						if ( bValidGluePoint )
+						{
+							Reference< XPropertySet > xPropSet( aXConnector, UNO_QUERY );
+							if ( xPropSet.is() )
+							{
+								if ( nN )
+								{
+									String aPropName( RTL_CONSTASCII_USTRINGPARAM( "EndShape" ) );
+									aAny <<= aXShape;
+									SetPropValue( aAny, xPropSet, aPropName, sal_True );
+									aPropName  = String( RTL_CONSTASCII_USTRINGPARAM( "EndGluePointIndex" ) );
+									aAny <<= nId;
+									SetPropValue( aAny, xPropSet, aPropName, sal_True );
+								}
+								else
+								{
+									String aPropName( RTL_CONSTASCII_USTRINGPARAM( "StartShape" ) );
+									aAny <<= aXShape;
+									SetPropValue( aAny, xPropSet, aPropName, sal_True );
+									aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "StartGluePointIndex" ) );
+									aAny <<= nId;
+									SetPropValue( aAny, xPropSet, aPropName, sal_True );
+								}
+
+								// Not sure what this is good for, repaint or broadcast of object change.
+								//( Thus i am adding repaint here
+								pO->SetChanged();
+								pO->BroadcastObjectChange();
+							}
+						}
+					}
+				}
+			}
+		}
+	}
+}
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+
+static basegfx::B2DPolygon GetLineArrow( const sal_Int32 nLineWidth, const MSO_LineEnd eLineEnd,
+	const MSO_LineEndWidth eLineWidth, const MSO_LineEndLength eLineLenght,
+	sal_Int32& rnArrowWidth, sal_Bool& rbArrowCenter,
+	String& rsArrowName, sal_Bool bScaleArrow )
+{
+	basegfx::B2DPolygon aRetval;
+	double		fLineWidth = nLineWidth < 70 ? 70.0 : nLineWidth;
+	double		fLenghtMul, fWidthMul;
+	sal_Int32	nLineNumber;
+	switch( eLineLenght )
+	{
+		default :
+		case mso_lineMediumLenArrow		: fLenghtMul = 3.0; nLineNumber = 2; break;
+		case mso_lineShortArrow			: fLenghtMul = 2.0; nLineNumber = 1; break;
+		case mso_lineLongArrow			: fLenghtMul = 5.0; nLineNumber = 3; break;
+	}
+	switch( eLineWidth )
+	{
+		default :
+		case mso_lineMediumWidthArrow	: fWidthMul = 3.0; nLineNumber += 3; break;
+		case mso_lineNarrowArrow		: fWidthMul = 2.0; break;
+		case mso_lineWideArrow			: fWidthMul = 5.0; nLineNumber += 6; break;
+	}
+
+	if ( bScaleArrow )	// #i33630 arrows imported from Word are too big
+	{
+		fWidthMul /= 1.75;
+		fLenghtMul/= 1.75;
+	}
+
+	rbArrowCenter = sal_False;
+	switch ( eLineEnd )
+	{
+		case mso_lineArrowEnd :
+		{
+			basegfx::B2DPolygon aTriangle;
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, 0.0 ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth ));
+			aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
+			aTriangle.setClosed(true);
+			aRetval = aTriangle;
+			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowEnd " ), RTL_TEXTENCODING_UTF8 );
+		}
+		break;
+
+		case mso_lineArrowOpenEnd :
+		{
+			switch( eLineLenght )
+			{
+				default :
+				case mso_lineMediumLenArrow		: fLenghtMul = 4.5; break;
+				case mso_lineShortArrow			: fLenghtMul = 3.5; break;
+				case mso_lineLongArrow			: fLenghtMul = 6.0; break;
+			}
+			switch( eLineWidth )
+			{
+				default :
+				case mso_lineMediumWidthArrow	: fWidthMul = 4.5; break;
+				case mso_lineNarrowArrow		: fWidthMul = 3.5; break;
+				case mso_lineWideArrow			: fWidthMul = 6.0; break;
+			}
+			basegfx::B2DPolygon aTriangle;
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth * 0.91 ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.85, fLenghtMul * fLineWidth ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, fLenghtMul * fLineWidth * 0.36 ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.15, fLenghtMul * fLineWidth ));
+			aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.91 ));
+			aTriangle.setClosed(true);
+			aRetval = aTriangle;
+			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOpenEnd " ), RTL_TEXTENCODING_UTF8 );
+		}
+		break;
+		case mso_lineArrowStealthEnd :
+		{
+			basegfx::B2DPolygon aTriangle;
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth * 0.60 ));
+			aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
+			aTriangle.setClosed(true);
+			aRetval = aTriangle;
+			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowStealthEnd " ), RTL_TEXTENCODING_UTF8 );
+		}
+		break;
+		case mso_lineArrowDiamondEnd :
+		{
+			basegfx::B2DPolygon aTriangle;
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth * 0.50 ));
+			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth ));
+			aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.50 ));
+			aTriangle.setClosed(true);
+			aRetval = aTriangle;
+			rbArrowCenter = sal_True;
+			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowDiamondEnd " ), RTL_TEXTENCODING_UTF8 );
+		}
+		break;
+		case mso_lineArrowOvalEnd :
+		{
+			aRetval = XPolygon( Point( (sal_Int32)( fWidthMul * fLineWidth * 0.50 ), 0 ),
+								(sal_Int32)( fWidthMul * fLineWidth * 0.50 ),
+									(sal_Int32)( fLenghtMul * fLineWidth * 0.50 ), 0, 3600 ).getB2DPolygon();
+			rbArrowCenter = sal_True;
+			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOvalEnd " ), RTL_TEXTENCODING_UTF8 );
+		}
+		break;
+		default: break;
+	}
+	rsArrowName.Append( String::CreateFromInt32( nLineNumber ) );
+	rnArrowWidth = (sal_Int32)( fLineWidth * fWidthMul );
+
+	return aRetval;
+}
+
+void DffPropertyReader::ApplyLineAttributes( SfxItemSet& rSet, const MSO_SPT eShapeType ) const // #i28269#
+{
+	UINT32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
+
+	if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( eShapeType ))
+	{
+		nLineFlags &= ~0x08;
+	}
+
+	if ( nLineFlags & 8 )
+	{
+		// Linienattribute
+		sal_Int32 nLineWidth = (INT32)GetPropertyValue( DFF_Prop_lineWidth, 9525 );
+
+		MSO_LineDashing eLineDashing = (MSO_LineDashing)GetPropertyValue( DFF_Prop_lineDashing, mso_lineSolid );
+		if ( eLineDashing == mso_lineSolid )
+			rSet.Put(XLineStyleItem( XLINE_SOLID ) );
+		else
+		{
+//			MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare );
+
+			XDashStyle  eDash = XDASH_RECT;
+			sal_uInt16	nDots = 1;
+			sal_uInt32	nDotLen	= nLineWidth / 360;
+			sal_uInt16	nDashes = 0;
+			sal_uInt32	nDashLen = ( 8 * nLineWidth ) / 360;
+			sal_uInt32	nDistance = ( 3 * nLineWidth ) / 360;;
+
+			switch ( eLineDashing )
+			{
+				default:
+				case mso_lineDotSys :
+				{
+					nDots = 1;
+					nDashes = 0;
+					nDistance = nDotLen;
+				}
+				break;
+
+				case mso_lineDashGEL :
+				{
+					nDots = 0;
+					nDashes = 1;
+					nDashLen = ( 4 * nLineWidth ) / 360;
+				}
+				break;
+
+				case mso_lineDashDotGEL :
+				{
+					nDots = 1;
+					nDashes = 1;
+					nDashLen = ( 4 * nLineWidth ) / 360;
+				}
+				break;
+
+				case mso_lineLongDashGEL :
+				{
+					nDots = 0;
+					nDashes = 1;
+				}
+				break;
+
+				case mso_lineLongDashDotGEL :
+				{
+					nDots = 1;
+					nDashes = 1;
+				}
+				break;
+
+				case mso_lineLongDashDotDotGEL:
+				{
+					nDots = 2;
+					nDashes = 1;
+				}
+				break;
+			}
+
+			rSet.Put( XLineDashItem( String(), XDash( eDash, nDots, nDotLen, nDashes, nDashLen, nDistance ) ) );
+			rSet.Put( XLineStyleItem( XLINE_DASH ) );
+		}
+		rSet.Put( XLineColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_lineColor ), DFF_Prop_lineColor ) ) );
+		if ( IsProperty( DFF_Prop_lineOpacity ) )
+        {
+			double nTrans = GetPropertyValue(DFF_Prop_lineOpacity, 0x10000);
+            nTrans = (nTrans * 100) / 65536;
+			rSet.Put(XLineTransparenceItem(
+                sal_uInt16(100 - ::rtl::math::round(nTrans))));
+        }
+
+		rManager.ScaleEmu( nLineWidth );
+		rSet.Put( XLineWidthItem( nLineWidth ) );
+
+		// SJ: LineJoint (setting each time a line is set, because our internal joint type has another default)
+		MSO_LineJoin eLineJointDefault = mso_lineJoinMiter;
+		if ( eShapeType == mso_sptMin )
+			eLineJointDefault = mso_lineJoinRound;
+		MSO_LineJoin eLineJoint = (MSO_LineJoin)GetPropertyValue( DFF_Prop_lineJoinStyle, eLineJointDefault );
+		XLineJoint eXLineJoint( XLINEJOINT_MITER );
+		if ( eLineJoint == mso_lineJoinBevel )
+			eXLineJoint = XLINEJOINT_BEVEL;
+		else if ( eLineJoint == mso_lineJoinRound )
+			eXLineJoint = XLINEJOINT_ROUND;
+		rSet.Put( XLineJointItem( eXLineJoint ) );
+
+		if ( nLineFlags & 0x10 )
+		{
+			sal_Bool bScaleArrows = rManager.pSdrModel->GetScaleUnit() == MAP_TWIP;
+			///////////////
+			// LineStart //
+			///////////////
+			if ( IsProperty( DFF_Prop_lineStartArrowhead ) )
+			{
+				MSO_LineEnd			eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineStartArrowhead );
+				MSO_LineEndWidth	eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineStartArrowWidth, mso_lineMediumWidthArrow );
+				MSO_LineEndLength	eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineStartArrowLength, mso_lineMediumLenArrow );
+
+				sal_Int32	nArrowWidth;
+				sal_Bool	bArrowCenter;
+				String		aArrowName;
+				basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
+
+				rSet.Put( XLineStartWidthItem( nArrowWidth ) );
+				rSet.Put( XLineStartItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
+				rSet.Put( XLineStartCenterItem( bArrowCenter ) );
+			}
+			/////////////
+			// LineEnd //
+			/////////////
+			if ( IsProperty( DFF_Prop_lineEndArrowhead ) )
+			{
+				MSO_LineEnd			eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineEndArrowhead );
+				MSO_LineEndWidth	eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineEndArrowWidth, mso_lineMediumWidthArrow );
+				MSO_LineEndLength	eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineEndArrowLength, mso_lineMediumLenArrow );
+
+				sal_Int32	nArrowWidth;
+				sal_Bool	bArrowCenter;
+				String		aArrowName;
+				basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
+
+				rSet.Put( XLineEndWidthItem( nArrowWidth ) );
+				rSet.Put( XLineEndItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
+				rSet.Put( XLineEndCenterItem( bArrowCenter ) );
+			}
+			if ( IsProperty( DFF_Prop_lineEndCapStyle ) )
+			{
+				MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle );
+				const SfxPoolItem* pPoolItem = NULL;
+				if ( rSet.GetItemState( XATTR_LINEDASH, FALSE, &pPoolItem ) == SFX_ITEM_SET )
+				{
+					XDashStyle eNewStyle = XDASH_RECT;
+					if ( eLineCap == mso_lineEndCapRound )
+						eNewStyle = XDASH_ROUND;
+					const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue();
+					if ( rOldDash.GetDashStyle() != eNewStyle )
+					{
+						XDash aNew( rOldDash );
+						aNew.SetDashStyle( eNewStyle );
+						rSet.Put( XLineDashItem( XubString(), aNew ) );
+					}
+				}
+			}
+		}
+	}
+	else
+		rSet.Put( XLineStyleItem( XLINE_NONE ) );
+}
+
+struct ShadeColor
+{
+	Color		aColor;
+	double		fDist;
+
+	ShadeColor( const Color& rC, double fR ) : aColor( rC ), fDist( fR ) {}; 
+};
+
+void GetShadeColors( const SvxMSDffManager& rManager, const DffPropertyReader& rProperties, SvStream& rIn, std::vector< ShadeColor >& rShadeColors )
+{
+	sal_uInt32 nPos = rIn.Tell();
+	if ( rProperties.IsProperty( DFF_Prop_fillShadeColors ) )
+	{
+		if ( rProperties.SeekToContent( DFF_Prop_fillShadeColors, rIn ) )
+		{
+			sal_uInt16 i = 0, nNumElem = 0, nNumElemReserved = 0, nSize = 0;
+			rIn >> nNumElem >> nNumElemReserved >> nSize;
+			for ( ; i < nNumElem; i++ )
+			{
+				sal_Int32	nColor;
+				sal_Int32	nDist;
+
+				rIn >> nColor >> nDist;
+				rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( nColor, DFF_Prop_fillColor ), 1.0 - ( nDist / 65536.0 ) ) );
+			}
+		}
+	}
+	if ( !rShadeColors.size() )
+	{
+		rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ), 0 ) );
+		rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ), 1 ) );
+	}
+	rIn.Seek( nPos );
+}
+
+struct QuantErr
+{
+	double	fRed;
+	double	fGreen;
+	double	fBlue;
+
+	QuantErr() : fRed( 0.0 ), fGreen( 0.0 ), fBlue( 0.0 ){};
+};
+
+void ApplyRectangularGradientAsBitmap( const SvxMSDffManager& rManager, SvStream& rIn, SfxItemSet& rSet, const std::vector< ShadeColor >& rShadeColors, const DffObjData& rObjData, sal_Int32 nFix16Angle )
+{
+	Size aBitmapSizePixel( static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetWidth() / 2540.0 ) * 90.0 ),		// we will create a bitmap with 90 dpi
+						   static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetHeight() / 2540.0 ) * 90.0 ) );
+	if ( aBitmapSizePixel.Width() && aBitmapSizePixel.Height() && ( aBitmapSizePixel.Width() <= 1024 ) && ( aBitmapSizePixel.Height() <= 1024 ) )
+	{
+//		std::vector< QuantErr > aQuantErrCurrScan( aBitmapSizePixel.Width() + 1 );
+//		std::vector< QuantErr > aQuantErrNextScan( aBitmapSizePixel.Width() + 1 );
+
+		double fFocusX = rManager.GetPropertyValue( DFF_Prop_fillToRight, 0 ) / 65536.0;
+		double fFocusY = rManager.GetPropertyValue( DFF_Prop_fillToBottom, 0 ) / 65536.0;
+
+		Bitmap aBitmap( aBitmapSizePixel, 24 );
+		BitmapWriteAccess* pAcc = aBitmap.AcquireWriteAccess();
+		if ( pAcc )
+		{
+			sal_Int32 nX, nY;
+			for ( nY = 0; nY < aBitmapSizePixel.Height(); nY++ )
+			{
+				for ( nX = 0; nX < aBitmapSizePixel.Width(); nX++ )
+				{
+					double fX = static_cast< double >( nX ) / aBitmapSizePixel.Width();
+					double fY = static_cast< double >( nY ) / aBitmapSizePixel.Height();
+										
+					double fD, fDist;
+					if ( fX < fFocusX )
+					{
+						if ( fY < fFocusY )
+						{
+							if ( fX > fY )
+								fDist = fY, fD = fFocusY;
+							else
+								fDist = fX, fD = fFocusX;
+						}
+						else
+						{
+							if ( fX > ( 1 - fY ) )
+								fDist = ( 1 - fY ), fD = 1 - fFocusY;
+							else
+								fDist = fX, fD = fFocusX;
+						}
+					}
+					else
+					{
+						if ( fY < fFocusY )
+						{
+							if ( ( 1 - fX ) > fY )
+								fDist = fY, fD = fFocusY;
+							else
+								fDist = ( 1 - fX ), fD = 1 - fFocusX;
+						}
+						else
+						{
+							if ( ( 1 - fX ) > ( 1 - fY ) )
+								fDist = ( 1 - fY ), fD = 1 - fFocusY;
+							else
+								fDist = ( 1 - fX ), fD = 1 - fFocusX;
+						}
+					}
+					if ( fD != 0.0 )
+						fDist /= fD;
+					
+					std::vector< ShadeColor >::const_iterator aIter( rShadeColors.begin() );
+					double fA = 0.0;
+					Color aColorA = aIter->aColor;
+					double fB = 1.0;
+					Color aColorB( aColorA );
+					while ( aIter != rShadeColors.end() )
+					{
+						if ( aIter->fDist <= fDist )
+						{
+							if ( aIter->fDist >= fA )
+							{
+								fA = aIter->fDist;
+								aColorA = aIter->aColor;
+							}
+						}
+						if ( aIter->fDist > fDist )
+						{
+							if ( aIter->fDist <= fB )
+							{
+								fB = aIter->fDist;
+								aColorB = aIter->aColor;
+							}
+						}
+						aIter++;
+					}			
+					double fRed = aColorA.GetRed(), fGreen = aColorA.GetGreen(), fBlue = aColorA.GetBlue();
+					double fD1 = fB - fA;
+					if ( fD1 != 0.0 )
+					{
+						fRed   += ( ( ( fDist - fA ) * ( aColorB.GetRed() - aColorA.GetRed() ) ) / fD1 );		// + aQuantErrCurrScan[ nX ].fRed;
+						fGreen += ( ( ( fDist - fA ) * ( aColorB.GetGreen() - aColorA.GetGreen() ) ) / fD1 );	// + aQuantErrCurrScan[ nX ].fGreen;
+						fBlue  += ( ( ( fDist - fA ) * ( aColorB.GetBlue() - aColorA.GetBlue() ) ) / fD1 );		// + aQuantErrCurrScan[ nX ].fBlue;
+					}
+					sal_Int16 nRed   = static_cast< sal_Int16 >( fRed   + 0.5 );
+					sal_Int16 nGreen = static_cast< sal_Int16 >( fGreen + 0.5 );
+					sal_Int16 nBlue  = static_cast< sal_Int16 >( fBlue  + 0.5 );
+/*
+					double fErr = fRed - nRed;
+					aQuantErrCurrScan[ nX + 1 ].fRed += 7.0 * fErr / 16.0;
+					if ( nX )
+						aQuantErrNextScan[ nX - 1 ].fRed += 3.0 * fErr / 16.0;
+					aQuantErrNextScan[ nX ].fRed += 5.0 * fErr / 16.0;
+					aQuantErrNextScan[ nX + 1 ].fRed += 1.0 * fErr / 16.0;
+
+					fErr = fGreen - nGreen;
+					aQuantErrCurrScan[ nX + 1 ].fGreen += 7.0 * fErr / 16.0;
+					if ( nX )
+						aQuantErrNextScan[ nX - 1 ].fGreen += 3.0 * fErr / 16.0;
+					aQuantErrNextScan[ nX ].fGreen += 5.0 * fErr / 16.0;
+					aQuantErrNextScan[ nX + 1 ].fGreen += 1.0 * fErr / 16.0;
+
+					fErr = fBlue - nBlue;
+					aQuantErrCurrScan[ nX + 1 ].fBlue += 7.0 * fErr / 16.0;
+					if ( nX )
+						aQuantErrNextScan[ nX - 1 ].fBlue += 3.0 * fErr / 16.0;
+					aQuantErrNextScan[ nX ].fBlue += 5.0 * fErr / 16.0;
+					aQuantErrNextScan[ nX + 1 ].fBlue += 1.0 * fErr / 16.0;
+*/					
+					if ( nRed < 0 )
+						nRed = 0;
+					if ( nRed > 255 )
+						nRed = 255;
+					if ( nGreen < 0 )
+						nGreen = 0;
+					if ( nGreen > 255 )
+						nGreen = 255;
+					if ( nBlue < 0 )
+						nBlue = 0;
+					if ( nBlue > 255 )
+						nBlue = 255;
+
+					pAcc->SetPixel( nY, nX, BitmapColor( static_cast< sal_Int8 >( nRed ), static_cast< sal_Int8 >( nGreen ), static_cast< sal_Int8 >( nBlue ) ) );
+				}
+/*
+				aQuantErrCurrScan.swap( aQuantErrNextScan );
+				std::vector< QuantErr >::iterator aIter( aQuantErrNextScan.begin() );
+				while( aIter != aQuantErrNextScan.end() )
+				{
+					*aIter = QuantErr();
+					aIter++;
+				}
+*/
+			}
+			aBitmap.ReleaseAccess( pAcc );
+
+			if ( nFix16Angle )
+			{
+				sal_Bool bRotateWithShape = sal_True;	// TRUE seems to be default
+				sal_uInt32 nPos = rIn.Tell();
+				if ( const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.SeekToContent( rIn, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ) )
+				{
+					const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.Current()->SeekToBegOfRecord( rIn );
+					DffPropertyReader aSecPropSet( rManager );
+					aSecPropSet.ReadPropSet( rIn, NULL );
+					sal_Int32 nSecFillProperties = aSecPropSet.GetPropertyValue( DFF_Prop_fNoFillHitTest, 0x200020 );
+					bRotateWithShape = ( nSecFillProperties & 0x0020 );
+				}
+				rIn.Seek( nPos );
+				if ( bRotateWithShape )
+				{
+					aBitmap.Rotate( nFix16Angle / 10, rShadeColors[ 0 ].aColor );
+		
+					ULONG nMirrorFlags = BMP_MIRROR_NONE;
+					if ( rObjData.nSpFlags & SP_FFLIPV )
+						nMirrorFlags |= BMP_MIRROR_VERT;
+					if ( rObjData.nSpFlags & SP_FFLIPH )
+						nMirrorFlags |= BMP_MIRROR_HORZ;
+					if ( nMirrorFlags != BMP_MIRROR_NONE )
+						aBitmap.Mirror( nMirrorFlags );
+				}
+			}
+
+			XOBitmap aXBmp( aBitmap, XBITMAP_STRETCH );
+			rSet.Put( XFillBmpTileItem( sal_False ) );
+			rSet.Put( XFillBitmapItem( String(), aXBmp ) );
+		}
+	}
+}
+
+void DffPropertyReader::ApplyFillAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
+{
+	UINT32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
+
+	std::vector< ShadeColor > aShadeColors;
+	GetShadeColors( rManager, *this, rIn, aShadeColors );
+
+	if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType ))
+	{
+		nFillFlags &= ~0x10;
+	}
+
+	if ( nFillFlags & 0x10 )
+	{
+		MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
+		XFillStyle eXFill = XFILL_NONE;
+		switch( eMSO_FillType )
+		{
+			case mso_fillSolid :			// Fill with a solid color
+				eXFill = XFILL_SOLID;
+			break;
+			case mso_fillPattern :			// Fill with a pattern (bitmap)
+			case mso_fillTexture :			// A texture (pattern with its own color map)
+			case mso_fillPicture :			// Center a picture in the shape
+				eXFill = XFILL_BITMAP;
+			break;
+			case mso_fillShadeCenter :		// Shade from bounding rectangle to end point
+			{
+				if ( rObjData.aBoundRect.IsEmpty() )// size of object needed to be able
+					eXFill = XFILL_GRADIENT;		// to create a bitmap substitution
+				else
+					eXFill = XFILL_BITMAP;
+			}
+			break;
+			case mso_fillShade :			// Shade from start to end points
+			case mso_fillShadeShape :		// Shade from shape outline to end point
+			case mso_fillShadeScale :		// Similar to mso_fillShade, but the fillAngle
+			case mso_fillShadeTitle :		// special type - shade to title ---  for PP
+				eXFill = XFILL_GRADIENT;
+			break;
+//			case mso_fillBackground	:		// Use the background fill color/pattern
+			default: break;
+		}
+		rSet.Put( XFillStyleItem( eXFill ) );
+
+        if (IsProperty(DFF_Prop_fillOpacity))
+        {
+			double nTrans = GetPropertyValue(DFF_Prop_fillOpacity);
+            nTrans = (nTrans * 100) / 65536;
+			rSet.Put(XFillTransparenceItem(
+                sal_uInt16(100 - ::rtl::math::round(nTrans))));
+        }
+
+		if ( ( eMSO_FillType == mso_fillShadeCenter ) && ( eXFill == XFILL_BITMAP ) )
+		{
+			ApplyRectangularGradientAsBitmap( rManager, rIn, rSet, aShadeColors, rObjData, mnFix16Angle );
+		}
+		else if ( eXFill == XFILL_GRADIENT )
+		{
+			sal_Int32 nAngle = 3600 - ( ( Fix16ToAngle( GetPropertyValue( DFF_Prop_fillAngle, 0 ) ) + 5 ) / 10 );
+
+			// Rotationswinkel in Bereich zwingen
+			while ( nAngle >= 3600 )
+				nAngle -= 3600;
+			while ( nAngle < 0 )
+				nAngle += 3600;
+
+			sal_Int32 nFocus = GetPropertyValue( DFF_Prop_fillFocus, 0 );
+			XGradientStyle eGrad = XGRAD_LINEAR;
+			sal_Int32 nChgColors = 0;
+
+			if ( !nAngle )
+				nChgColors ^= 1;
+
+			if ( !nFocus )
+				nChgColors ^= 1;
+			else if ( nFocus < 0 )		// Bei negativem Focus sind die Farben zu tauschen
+			{
+				nFocus =- nFocus;
+				nChgColors ^= 1;
+			}
+			if( nFocus > 40 && nFocus < 60 )
+			{
+				eGrad = XGRAD_AXIAL;	// Besser gehts leider nicht
+				nChgColors ^= 1;
+			}
+			USHORT nFocusX = (USHORT)nFocus;
+			USHORT nFocusY = (USHORT)nFocus;
+
+			switch( eMSO_FillType )
+			{
+				case mso_fillShadeShape :
+				{
+					eGrad = XGRAD_RECT;
+					nFocusY = nFocusX = 50;
+					nChgColors ^= 1;
+				}
+				break;
+				case mso_fillShadeCenter :
+				{
+					eGrad = XGRAD_RECT;
+					nFocusX = ( IsProperty( DFF_Prop_fillToRight ) ) ? 100 : 0;
+					nFocusY = ( IsProperty( DFF_Prop_fillToBottom ) ) ? 100 : 0;
+					nChgColors ^= 1;
+				}
+				break;
+				default: break;
+			}
+			Color aCol1( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ) );
+			Color aCol2( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ) );
+
+			if ( nChgColors )
+			{
+				Color aZwi( aCol1 );
+				aCol1 = aCol2;
+				aCol2 = aZwi;
+			}
+			XGradient aGrad( aCol2, aCol1, eGrad, nAngle, nFocusX, nFocusY );
+			aGrad.SetStartIntens( 100 );
+			aGrad.SetEndIntens( 100 );
+			rSet.Put( XFillGradientItem( String(), aGrad ) );
+		}
+		else if ( eXFill == XFILL_BITMAP )
+		{
+			if( IsProperty( DFF_Prop_fillBlip ) )
+			{
+				Graphic aGraf;
+                // first try to get BLIP from cache
+                BOOL bOK = rManager.GetBLIP( GetPropertyValue( DFF_Prop_fillBlip ), aGraf, NULL );
+                // then try directly from stream (i.e. Excel chart hatches/bitmaps)
+                if ( !bOK )
+                    bOK = SeekToContent( DFF_Prop_fillBlip, rIn ) && rManager.GetBLIPDirect( rIn, aGraf, NULL );
+                if ( bOK )
+				{
+					Bitmap aBmp( aGraf.GetBitmap() );
+
+					if ( eMSO_FillType == mso_fillPattern )
+					{
+						Color aCol1( COL_WHITE ), aCol2( COL_WHITE );
+						if ( IsProperty( DFF_Prop_fillColor ) )
+							aCol1 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor );
+						if ( IsProperty( DFF_Prop_fillBackColor ) )
+							aCol2 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor ), DFF_Prop_fillBackColor );
+
+						XOBitmap aXOBitmap;
+
+						// Bitmap einsetzen
+						aXOBitmap.SetBitmap( aBmp );
+						aXOBitmap.SetBitmapType( XBITMAP_IMPORT );
+
+						if( aBmp.GetSizePixel().Width() == 8 && aBmp.GetSizePixel().Height() == 8 && aBmp.GetColorCount() == 2)
+						{
+							aXOBitmap.Bitmap2Array();
+							aXOBitmap.SetBitmapType( XBITMAP_8X8 );
+							aXOBitmap.SetPixelSize( aBmp.GetSizePixel() );
+
+							if( aXOBitmap.GetBackgroundColor() == COL_BLACK )
+							{
+								aXOBitmap.SetPixelColor( aCol1 );
+								aXOBitmap.SetBackgroundColor( aCol2 );
+							}
+							else
+							{
+								aXOBitmap.SetPixelColor( aCol2 );
+								aXOBitmap.SetBackgroundColor( aCol1 );
+							}
+						}
+						rSet.Put( XFillBitmapItem( String(), aXOBitmap ) );
+					}
+					else if ( eMSO_FillType == mso_fillTexture )
+					{
+						XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
+						rSet.Put( XFillBmpTileItem( sal_True ) );
+						rSet.Put( XFillBitmapItem( String(), aXBmp ) );
+						rSet.Put( XFillBmpSizeXItem( GetPropertyValue( DFF_Prop_fillWidth, 0 ) / 360 ) );
+						rSet.Put( XFillBmpSizeYItem( GetPropertyValue( DFF_Prop_fillHeight, 0 ) / 360 ) );
+						rSet.Put( XFillBmpSizeLogItem( sal_True ) );
+					}
+					else
+					{
+						XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
+						rSet.Put( XFillBitmapItem( String(), aXBmp ) );
+						rSet.Put( XFillBmpTileItem( sal_False ) );
+					}
+				}
+			}
+		}
+	}
+	else
+		rSet.Put( XFillStyleItem( XFILL_NONE ) );
+}
+
+void DffPropertyReader::ApplyCustomShapeTextAttributes( SfxItemSet& rSet ) const
+{
+//    sal_uInt32 nTextFlags = aTextObj.GetTextFlags();
+	sal_Bool  bVerticalText = sal_False;
+	sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ) / 360;		// 0.25 cm (emu)
+	sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ) / 360;	// 0.25 cm (emu)
+	sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ) / 360;		// 0.13 cm (emu)
+	sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 ) /360;	// 0.13 cm (emu)
+
+	SdrTextVertAdjust eTVA;
+	SdrTextHorzAdjust eTHA;
+
+	if ( IsProperty( DFF_Prop_txflTextFlow ) )
+	{
+		MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
+		switch( eTextFlow )
+		{
+			case mso_txflTtoBA :	/* #68110# */	// Top to Bottom @-font, oben -> unten
+			case mso_txflTtoBN :					// Top to Bottom non-@, oben -> unten
+			case mso_txflVertN :					// Vertical, non-@, oben -> unten
+				bVerticalText = sal_True;			// nTextRotationAngle += 27000;
+			break;
+			default: break;
+		}
+	}
+	sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 );
+	if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) )