1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_filter.hxx"
26 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
27 #include <com/sun/star/embed/Aspects.hpp>
28 
29 #include <math.h>
30 #include <limits.h>
31 #include <vector>
32 #include <osl/endian.h>
33 #include <tools/solar.h>               // UINTXX
34 #include <rtl/math.hxx>
35 
36 #include <sot/clsids.hxx>
37 #include <toolkit/helper/vclunohelper.hxx>
38 #include <unotools/streamwrap.hxx>
39 #include <comphelper/processfactory.hxx>
40 #include <comphelper/seqstream.hxx>
41 #include <comphelper/storagehelper.hxx>
42 #include <sot/exchange.hxx>
43 #include <sot/storinfo.hxx>
44 #include <vcl/cvtgrf.hxx>
45 #include "viscache.hxx"
46 
47 // SvxItem-Mapping. Wird benoetigt um die SvxItem-Header erfolgreich zu includen
48 #include <editeng/eeitem.hxx>
49 #include <editeng/editdata.hxx>
50 #include <svl/urihelper.hxx>
51 #include <tools/stream.hxx>
52 #include <tools/debug.hxx>
53 #include <tools/zcodec.hxx>
54 #include <unotools/ucbstreamhelper.hxx>
55 #include <unotools/localfilehelper.hxx>
56 #include <filter/msfilter/escherex.hxx>
57 #include <basegfx/range/b2drange.hxx>
58 #include <com/sun/star/container/XIdentifierContainer.hpp>
59 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
60 #include <com/sun/star/drawing/Position3D.hpp>
61 #include <com/sun/star/drawing/Direction3D.hpp>
62 #include <com/sun/star/drawing/GluePoint2.hpp>
63 #include <com/sun/star/drawing/XShapes.hpp>
64 #include <editeng/charscaleitem.hxx>
65 #include <editeng/kernitem.hxx>
66 #include <svtools/filter.hxx>
67 #include <tools/string.hxx>
68 #include <tools/urlobj.hxx>
69 #include <vcl/virdev.hxx>
70 #include <vcl/bmpacc.hxx>
71 #include <sot/storage.hxx>
72 #include <sfx2/docfac.hxx>
73 #include <sfx2/docfilt.hxx>
74 #include <sfx2/docfile.hxx>
75 #include <sfx2/fcontnr.hxx>
76 #include <sfx2/module.hxx>
77 #include <svx/sdgcpitm.hxx>
78 #include <svx/sdgmoitm.hxx>
79 #include <editeng/tstpitem.hxx>
80 #include <svx/fmmodel.hxx>
81 #include <svx/svdmodel.hxx>
82 #include <svx/svdobj.hxx>
83 #include <svx/svdpage.hxx>
84 #include <svx/svdogrp.hxx>
85 #include <svx/svdograf.hxx>
86 #include <svx/svdotext.hxx>
87 #include <svx/svdorect.hxx>
88 #include <svx/svdocapt.hxx>
89 #include <svx/svdoedge.hxx>
90 #include <svx/svdocirc.hxx>
91 #include <svx/svdoutl.hxx>
92 #include <svx/svdoole2.hxx>
93 #include <svx/svdopath.hxx>
94 #include <editeng/frmdir.hxx>
95 #include <editeng/frmdiritem.hxx>
96 #include <svx/svdtrans.hxx>
97 #include <svx/sxenditm.hxx>
98 #include <svx/sdgluitm.hxx>
99 #include <editeng/fhgtitem.hxx>
100 #include <editeng/wghtitem.hxx>
101 #include <editeng/postitem.hxx>
102 #include <editeng/udlnitem.hxx>
103 #include <editeng/crsditem.hxx>
104 #include <editeng/shdditem.hxx>
105 #include <editeng/fontitem.hxx>
106 #include <editeng/colritem.hxx>
107 #include <svx/sxekitm.hxx>
108 #include <editeng/bulitem.hxx>
109 #include <svx/polysc3d.hxx>
110 #include <svx/extrud3d.hxx>
111 #include "svx/svditer.hxx"
112 #include <svx/xpoly.hxx>
113 #include "svx/xattr.hxx"
114 #include <filter/msfilter/msdffimp.hxx> // extern sichtbare Header-Datei
115 #include <editeng/outliner.hxx>
116 #include <editeng/outlobj.hxx>
117 #include <editeng/editobj.hxx>
118 #include <editeng/editeng.hxx>
119 #include "svx/gallery.hxx"
120 #include <com/sun/star/drawing/ShadeMode.hpp>
121 #include <svl/itempool.hxx>
122 #include <vcl/svapp.hxx>
123 #include <svx/svx3ditems.hxx>
124 #include <svx/svdoashp.hxx>
125 #include <svx/sdasaitm.hxx>
126 #include <ucbhelper/content.hxx>
127 #include <ucbhelper/contentbroker.hxx>
128 #include <vos/xception.hxx>
129 using namespace vos;
130 #include "svx/EnhancedCustomShapeTypeNames.hxx"
131 #include "svx/EnhancedCustomShapeGeometry.hxx"
132 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
133 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
134 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
135 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
136 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
137 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
138 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
139 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
140 #include <com/sun/star/beans/PropertyValues.hpp>
141 #include <com/sun/star/drawing/ProjectionMode.hpp>
142 #include "svx/EnhancedCustomShape2d.hxx"
143 #include <vcl/dibtools.hxx>
144 
145 using namespace ::com::sun::star    ;
146 using namespace ::com::sun::star::drawing;
147 using namespace uno		            ;
148 using namespace beans		        ;
149 using namespace drawing	            ;
150 using namespace container	        ;
151 
152 #define ITEMVALUE(ItemSet,Id,Cast)  ((const Cast&)(ItemSet).Get(Id)).GetValue()
153 
154 // static counter for OLE-Objects
155 static sal_uInt32 nMSOleObjCntr = 0;
156 #define MSO_OLE_Obj "MSO_OLE_Obj"
157 
158 /************************************************************************/
159 void Impl_OlePres::Write( SvStream & rStm )
160 {
161 	WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE );
162 	rStm << (sal_Int32)(nJobLen +4);       // immer leeres TargetDevice
163 	if( nJobLen )
164 		rStm.Write( pJob, nJobLen );
165 	rStm << (sal_uInt32)nAspect;
166 	rStm << (sal_Int32)-1;      //L-Index immer -1
167 	rStm << (sal_Int32)nAdvFlags;
168 	rStm << (sal_Int32)0;       //Compression
169 	rStm << (sal_Int32)aSize.Width();
170 	rStm << (sal_Int32)aSize.Height();
171 	sal_uLong nPos = rStm.Tell();
172 	rStm << (sal_Int32)0;
173 
174 	if( GetFormat() == FORMAT_GDIMETAFILE && pMtf )
175 	{
176 		// Immer auf 1/100 mm, bis Mtf-Loesung gefunden
177 		// Annahme (keine Skalierung, keine Org-Verschiebung)
178 		DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ),
179 					"X-Skalierung im Mtf" );
180 		DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ),
181 					"Y-Skalierung im Mtf" );
182 		DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(),
183 					"Origin-Verschiebung im Mtf" );
184 		MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit();
185 		if( MAP_100TH_MM != nMU )
186 		{
187 			Size aPrefS( pMtf->GetPrefSize() );
188 			Size aS( aPrefS );
189 			aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM );
190 
191 			pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ),
192 						 Fraction( aS.Height(), aPrefS.Height() ) );
193 			pMtf->SetPrefMapMode( MAP_100TH_MM );
194 			pMtf->SetPrefSize( aS );
195 		}
196 		WriteWindowMetafileBits( rStm, *pMtf );
197 	}
198 	else
199 	{
200 		DBG_ERROR( "unknown format" );
201 	}
202 	sal_uLong nEndPos = rStm.Tell();
203 	rStm.Seek( nPos );
204 	rStm << (sal_uInt32)(nEndPos - nPos - 4);
205 	rStm.Seek( nEndPos );
206 }
207 
208 //---------------------------------------------------------------------------
209 //  Hilfs Klassen aus MSDFFDEF.HXX
210 //---------------------------------------------------------------------------
211 
212 // Masse fuer dashed lines
213 #define LLEN_MIDDLE         (450)
214 #define LLEN_SPACE_MIDDLE   (360)
215 #define LLEN_LONG           (LLEN_MIDDLE * 2)
216 #define LLEN_SPACE_LONG     (LLEN_SPACE_MIDDLE + 20)
217 #define LLEN_POINT          (LLEN_MIDDLE / 4)
218 #define LLEN_SPACE_POINT    (LLEN_SPACE_MIDDLE / 4)
219 
220 DffPropertyReader::DffPropertyReader( const SvxMSDffManager& rMan ) :
221 	rManager( rMan ),
222 	pDefaultPropSet( NULL ),
223 	mbRotateGranientFillWithAngle ( 0 )
224 {
225 	InitializePropSet( DFF_msofbtOPT );
226 }
227 
228 void DffPropertyReader::SetDefaultPropSet( SvStream& rStCtrl, sal_uInt32 nOffsDgg ) const
229 {
230 	delete pDefaultPropSet;
231 	sal_uInt32 nMerk = rStCtrl.Tell();
232 	rStCtrl.Seek( nOffsDgg );
233 	DffRecordHeader aRecHd;
234 	rStCtrl >> aRecHd;
235 	if ( aRecHd.nRecType == DFF_msofbtDggContainer )
236 	{
237 		if ( rManager.SeekToRec( rStCtrl, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
238 		{
239 			( (DffPropertyReader*) this )->pDefaultPropSet = new DffPropSet;
240 			rStCtrl >> *pDefaultPropSet;
241 		}
242 	}
243 	rStCtrl.Seek( nMerk );
244 }
245 
246 #ifdef DBG_CUSTOMSHAPE
247 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData, sal_uInt32 nShapeId ) const
248 #else
249 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData ) const
250 #endif
251 {
252 	sal_uLong nFilePos = rIn.Tell();
253 	rIn >> (DffPropertyReader&)*this;
254 
255 	if ( IsProperty( DFF_Prop_hspMaster ) )
256 	{
257 		if ( rManager.SeekToShape( rIn, pClientData, GetPropertyValue( DFF_Prop_hspMaster ) ) )
258 		{
259 			DffRecordHeader aRecHd;
260 			rIn >> aRecHd;
261 			if ( rManager.SeekToRec( rIn, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
262 			{
263 				rIn |= (DffPropertyReader&)*this;
264 			}
265 		}
266 	}
267 	( (DffPropertyReader*) this )->mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) );
268 
269 #ifdef DBG_CUSTOMSHAPE
270 
271 	String aURLStr;
272 
273 	if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( String( RTL_CONSTASCII_STRINGPARAM( "d:\\ashape.dbg" ) ), aURLStr ) )
274 	{
275 		SvStream* pOut = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_WRITE );
276 
277 		if( pOut )
278 		{
279 			pOut->Seek( STREAM_SEEK_TO_END );
280 
281 			if ( IsProperty( DFF_Prop_adjustValue ) || IsProperty( DFF_Prop_pVertices ) )
282 			{
283 				pOut->WriteLine( "" );
284 				ByteString aString( "ShapeId: " );
285 				aString.Append( ByteString::CreateFromInt32( nShapeId ) );
286 				pOut->WriteLine( aString );
287 			}
288 			for ( sal_uInt32 i = DFF_Prop_adjustValue; i <=	DFF_Prop_adjust10Value; i++ )
289 			{
290 				if ( IsProperty( i ) )
291 				{
292 					ByteString aString( "Prop_adjustValue" );
293 					aString.Append( ByteString::CreateFromInt32( ( i - DFF_Prop_adjustValue ) + 1 ) );
294 					aString.Append( ":" );
295 					aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
296 					pOut->WriteLine( aString );
297 				}
298 			}
299 			sal_Int32 i;
300 			for ( i = 320; i < 383; i++ )
301 			{
302 				if ( ( i >= DFF_Prop_adjustValue ) && ( i <= DFF_Prop_adjust10Value ) )
303 					continue;
304 				if ( IsProperty( i ) )
305 				{
306 					if ( SeekToContent( i, rIn ) )
307 					{
308 						sal_Int32 nLen = (sal_Int32)GetPropertyValue( i );
309 						if ( nLen )
310 						{
311 							pOut->WriteLine( "" );
312 							ByteString aDesc( "Property:" );
313 							aDesc.Append( ByteString::CreateFromInt32( i ) );
314 							aDesc.Append( ByteString( "  Size:" ) );
315 							aDesc.Append( ByteString::CreateFromInt32( nLen ) );
316 							pOut->WriteLine( aDesc );
317 							sal_Int16	nNumElem, nNumElemMem, nNumSize;
318 							rIn >> nNumElem >> nNumElemMem >> nNumSize;
319 							aDesc = ByteString( "Entries: " );
320 							aDesc.Append( ByteString::CreateFromInt32( nNumElem ) );
321 							aDesc.Append( ByteString(  "  Size:" ) );
322 							aDesc.Append( ByteString::CreateFromInt32( nNumSize ) );
323 							pOut->WriteLine( aDesc );
324 							if ( nNumSize < 0 )
325 								nNumSize = ( ( -nNumSize ) >> 2 );
326 							if ( !nNumSize )
327 								nNumSize = 16;
328 							nLen -= 6;
329 							while ( nLen > 0 )
330 							{
331 								ByteString aString;
332 								for ( sal_uInt32 j = 0; nLen && ( j < ( nNumSize >> 1 ) ); j++ )
333 								{
334 									for ( sal_uInt32 k = 0; k < 2; k++ )
335 									{
336 										if ( nLen )
337 										{
338 											sal_uInt8 nVal;
339 											rIn >> nVal;
340 											if ( ( nVal >> 4 ) > 9 )
341 												*pOut << (sal_uInt8)( ( nVal >> 4 ) + 'A' - 10 );
342 											else
343 												*pOut << (sal_uInt8)( ( nVal >> 4 ) + '0' );
344 
345 											if ( ( nVal & 0xf ) > 9 )
346 												*pOut << (sal_uInt8)( ( nVal & 0xf ) + 'A' - 10 );
347 											else
348 												*pOut << (sal_uInt8)( ( nVal & 0xf ) + '0' );
349 
350 											nLen--;
351 										}
352 									}
353 									*pOut << (char)( ' ' );
354 								}
355 								pOut->WriteLine( aString );
356 							}
357 						}
358 					}
359 					else
360 					{
361 						ByteString aString( "Property" );
362 						aString.Append( ByteString::CreateFromInt32( i ) );
363 						aString.Append( ":" );
364 						aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
365 						pOut->WriteLine( aString );
366 					}
367 				}
368 			}
369 
370 			delete pOut;
371 		}
372 	}
373 
374 #endif
375 
376 	rIn.Seek( nFilePos );
377 }
378 
379 
380 sal_Int32 DffPropertyReader::Fix16ToAngle( sal_Int32 nContent ) const
381 {
382 	sal_Int32 nAngle = 0;
383 	if ( nContent )
384 	{
385 		nAngle = ( (sal_Int16)( nContent >> 16) * 100L ) + ( ( ( nContent & 0x0000ffff) * 100L ) >> 16 );
386 		nAngle = NormAngle360( -nAngle );
387 	}
388 	return nAngle;
389 }
390 
391 DffPropertyReader::~DffPropertyReader()
392 {
393 	delete pDefaultPropSet;
394 }
395 
396 ////////////////////////////////////////////////////////////////////////////////////////////////////
397 
398 SvStream& operator>>( SvStream& rIn, SvxMSDffConnectorRule& rRule )
399 {
400 	rIn >> rRule.nRuleId
401 		>> rRule.nShapeA
402 		>> rRule.nShapeB
403 		>> rRule.nShapeC
404 		>> rRule.ncptiA
405 		>> rRule.ncptiB;
406 
407 	return rIn;
408 }
409 
410 SvxMSDffSolverContainer::SvxMSDffSolverContainer()
411 {
412 }
413 
414 SvxMSDffSolverContainer::~SvxMSDffSolverContainer()
415 {
416 	for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)aCList.First();
417 			pPtr; pPtr = (SvxMSDffConnectorRule*)aCList.Next() )
418 		delete pPtr;
419 }
420 
421 SvStream& operator>>( SvStream& rIn, SvxMSDffSolverContainer& rContainer )
422 {
423 	DffRecordHeader aHd;
424 	rIn >> aHd;
425 	if ( aHd.nRecType == DFF_msofbtSolverContainer )
426 	{
427 		DffRecordHeader aCRule;
428 		while ( ( rIn.GetError() == 0 ) && ( rIn.Tell() < aHd.GetRecEndFilePos() ) )
429 		{
430 			rIn >> aCRule;
431 			if ( aCRule.nRecType == DFF_msofbtConnectorRule )
432 			{
433 				SvxMSDffConnectorRule* pRule = new SvxMSDffConnectorRule;
434 				rIn >> *pRule;
435 				rContainer.aCList.Insert( pRule, LIST_APPEND );
436 			}
437 			aCRule.SeekToEndOfRecord( rIn );
438 		}
439 	}
440 	return rIn;
441 }
442 
443 void SvxMSDffManager::SolveSolver( const SvxMSDffSolverContainer& rSolver )
444 {
445     sal_Int32 i, nCnt;
446     for ( i = 0, nCnt = rSolver.aCList.Count(); i < nCnt; i++ )
447     {
448         SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)rSolver.aCList.GetObject( i );
449 		if ( pPtr->pCObj )
450 		{
451 			for ( int nN = 0; nN < 2; nN++ )
452 			{
453 				SdrObject*  pO;
454 				sal_uInt32  nC, nSpFlags;
455 				sal_Bool    bTail;
456 				if ( !nN )
457 				{
458 					bTail = sal_True;
459 					pO = pPtr->pAObj;
460 					nC = pPtr->ncptiA;
461                     nSpFlags = pPtr->nSpFlagsA;
462 				}
463 				else
464 				{
465 					bTail = sal_False;
466 					pO = pPtr->pBObj;
467 					nC = pPtr->ncptiB;
468                     nSpFlags = pPtr->nSpFlagsB;
469 				}
470 				if ( pO )
471 				{
472 					Any aAny;
473 					SdrGluePoint aGluePoint;
474 					Reference< XShape > aXShape( pO->getUnoShape(), UNO_QUERY );
475 					Reference< XShape > aXConnector( pPtr->pCObj->getUnoShape(), UNO_QUERY );
476 					SdrGluePointList* pList = pO->ForceGluePointList();
477 
478                     sal_Bool bValidGluePoint = sal_False;
479 					sal_Int32 nId = nC;
480                     sal_uInt32 nInventor = pO->GetObjInventor();
481 
482 					if( nInventor == SdrInventor )
483 					{
484 						sal_uInt32 nObjId = pO->GetObjIdentifier();
485 						switch( nObjId )
486 						{
487 							case OBJ_GRUP :
488 							case OBJ_GRAF :
489 							case OBJ_RECT :
490 							case OBJ_TEXT :
491 							case OBJ_PAGE :
492 							case OBJ_TEXTEXT :
493 							case OBJ_wegFITTEXT :
494 							case OBJ_wegFITALLTEXT :
495 							case OBJ_TITLETEXT :
496 							case OBJ_OUTLINETEXT :
497 							{
498 								if ( nC & 1 )
499 								{
500 									if ( nSpFlags & SP_FFLIPH )
501 										nC ^= 2;    // 1 <-> 3
502 								}
503 								else
504 								{
505 									if ( nSpFlags & SP_FFLIPV )
506 										nC ^= 1;    // 0 <-> 2
507 								}
508 								switch( nC )
509 								{
510 									case 0 :
511 										nId = 0;	// SDRVERTALIGN_TOP;
512 									break;
513 									case 1 :
514 										nId = 3;	// SDRHORZALIGN_RIGHT;
515 									break;
516 									case 2 :
517 										nId = 2;	// SDRVERTALIGN_BOTTOM;
518 									break;
519 									case 3 :
520 										nId = 1; // SDRHORZALIGN_LEFT;
521 									break;
522 								}
523 								if ( nId <= 3 )
524 									bValidGluePoint = sal_True;
525 							}
526 							break;
527 							case OBJ_POLY :
528 							case OBJ_PLIN :
529 							case OBJ_LINE :
530 							case OBJ_PATHLINE :
531 							case OBJ_PATHFILL :
532 							case OBJ_FREELINE :
533 							case OBJ_FREEFILL :
534 							case OBJ_SPLNLINE :
535 							case OBJ_SPLNFILL :
536 							case OBJ_PATHPOLY :
537 							case OBJ_PATHPLIN :
538 							{
539 								if ( pList && ( pList->GetCount() > nC ) )
540 								{
541 									bValidGluePoint = sal_True;
542 									nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
543 								}
544 								else
545 								{
546 									sal_Bool bNotFound = sal_True;
547 
548 									PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aXShape ) );
549 									sal_uInt16 k, j, nPolySize = aPolyPoly.Count();
550 									if ( nPolySize )
551 									{
552 										sal_uInt32  nPointCount = 0;
553 										Rectangle aBoundRect( aPolyPoly.GetBoundRect() );
554 										if ( aBoundRect.GetWidth() && aBoundRect.GetHeight() )
555 										{
556 											for ( k = 0; bNotFound && ( k < nPolySize ); k++ )
557 											{
558 												const Polygon& rPolygon = aPolyPoly.GetObject( k );
559 												for ( j = 0; bNotFound && ( j < rPolygon.GetSize() ); j++ )
560 												{
561 													PolyFlags eFlags = rPolygon.GetFlags( j );
562 													if ( eFlags == POLY_NORMAL )
563 													{
564 														if ( nC == nPointCount )
565 														{
566 															const Point& rPoint = rPolygon.GetPoint( j );
567 															double fXRel = rPoint.X() - aBoundRect.Left();
568 															double fYRel = rPoint.Y() - aBoundRect.Top();
569 															sal_Int32 nWidth = aBoundRect.GetWidth();
570 															if ( !nWidth )
571 																nWidth = 1;
572 															sal_Int32 nHeight= aBoundRect.GetHeight();
573 															if ( !nHeight )
574 																nHeight = 1;
575 															fXRel /= (double)nWidth;
576 															fXRel *= 10000;
577 															fYRel /= (double)nHeight;
578 															fYRel *= 10000;
579 															aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) );
580 															aGluePoint.SetPercent( sal_True );
581 															aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
582 															aGluePoint.SetEscDir( SDRESC_SMART );
583 															nId = (sal_Int32)((*pList)[ pList->Insert( aGluePoint ) ].GetId() + 3 );
584 															bNotFound = sal_False;
585 														}
586 														nPointCount++;
587 													}
588 												}
589 											}
590 										}
591 									}
592 									if ( !bNotFound )
593 									{
594 										bValidGluePoint = sal_True;
595 									}
596 								}
597 							}
598 							break;
599 
600 							case OBJ_CUSTOMSHAPE :
601 							{
602 								SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pO)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
603 								const rtl::OUString	sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
604 								const rtl::OUString	sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
605 								sal_Int16 nGluePointType = EnhancedCustomShapeGluePointType::SEGMENTS;
606 								com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePointType );
607 								if ( pAny )
608 									*pAny >>= nGluePointType;
609 								else
610 								{
611 									const rtl::OUString	sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
612 									rtl::OUString sShapeType;
613 									pAny = aGeometryItem.GetPropertyValueByName( sType );
614 									if ( pAny )
615 										*pAny >>= sShapeType;
616 									MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
617 									nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType );
618 								}
619 								if ( nGluePointType == EnhancedCustomShapeGluePointType::CUSTOM )
620 								{
621 									if ( pList && ( pList->GetCount() > nC ) )
622 									{
623 										bValidGluePoint = sal_True;
624 										nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
625 									}
626 								}
627 								else if ( nGluePointType == EnhancedCustomShapeGluePointType::RECT )
628 								{
629 									if ( nC & 1 )
630 									{
631 										if ( nSpFlags & SP_FFLIPH )
632 											nC ^= 2;    // 1 <-> 3
633 									}
634 									else
635 									{
636 										if ( nSpFlags & SP_FFLIPV )
637 											nC ^= 1;    // 0 <-> 2
638 									}
639 									switch( nC )
640 									{
641 										case 0 :
642 											nId = 0;	// SDRVERTALIGN_TOP;
643 										break;
644 										case 1 :
645 											nId = 3;	// SDRHORZALIGN_RIGHT;
646 										break;
647 										case 2 :
648 											nId = 2;	// SDRVERTALIGN_BOTTOM;
649 										break;
650 										case 3 :
651 											nId = 1; // SDRHORZALIGN_LEFT;
652 										break;
653 									}
654 									if ( nId <= 3 )
655 										bValidGluePoint = sal_True;
656 								}
657 								else if ( nGluePointType == EnhancedCustomShapeGluePointType::SEGMENTS )
658 								{
659 									const rtl::OUString	sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
660 									const rtl::OUString	sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
661 
662 									sal_uInt32 k, nPt = nC;
663 									com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
664 									pAny = aGeometryItem.GetPropertyValueByName( sPath, sSegments );
665 									if ( pAny )
666 									{
667 										if ( *pAny >>= aSegments )
668 										{
669 											for ( nPt = 0, k = 1; nC && ( k < (sal_uInt32)aSegments.getLength() ); k++ )
670 											{
671 												sal_Int16 j, nCnt2 = aSegments[ k ].Count;
672 												if ( aSegments[ k ].Command != EnhancedCustomShapeSegmentCommand::UNKNOWN )
673 												{
674 													for ( j = 0; nC && ( j < nCnt2 ); j++ )
675 													{
676 														switch( aSegments[ k ].Command )
677 														{
678 															case EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
679 															case EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
680 															case EnhancedCustomShapeSegmentCommand::LINETO :
681 															case EnhancedCustomShapeSegmentCommand::MOVETO :
682 															{
683 																nC--;
684 																nPt++;
685 															}
686 															break;
687 															case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
688 															case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
689 															break;
690 
691 															case EnhancedCustomShapeSegmentCommand::CURVETO :
692 															{
693 																nC--;
694 																nPt += 3;
695 															}
696 															break;
697 
698 															case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
699 															case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
700 															{
701 																nC--;
702 																nPt += 3;
703 															}
704 															break;
705 															case EnhancedCustomShapeSegmentCommand::ARCTO :
706 															case EnhancedCustomShapeSegmentCommand::ARC :
707 															case EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
708 															case EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
709 															{
710 																nC--;
711 																nPt += 4;
712 															}
713 															break;
714 														}
715 													}
716 												}
717 											}
718 										}
719 									}
720 									pAny = aGeometryItem.GetPropertyValueByName( sPath, sCoordinates );
721 									if ( pAny )
722 									{
723 										com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
724 										*pAny >>= aCoordinates;
725 										if ( nPt < (sal_uInt32)aCoordinates.getLength() )
726 										{
727 											nId = 4;
728 											com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPara = aCoordinates[ nPt ];
729 											sal_Int32 nX = 0, nY = 0;
730 											if ( ( rPara.First.Value >>= nX ) && ( rPara.Second.Value >>= nY ) )
731 											{
732 												const rtl::OUString	sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
733 												com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
734 												pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePoints );
735 												if ( pAny )
736 													*pAny >>= aGluePoints;
737 												sal_Int32 nGluePoints = aGluePoints.getLength();
738 												aGluePoints.realloc( nGluePoints + 1 );
739 												EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].First, nX );
740 												EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].Second, nY );
741 												PropertyValue aProp;
742 												aProp.Name = sGluePoints;
743 												aProp.Value <<= aGluePoints;
744 												aGeometryItem.SetPropertyValue( sPath, aProp );
745 												bValidGluePoint = sal_True;
746 												((SdrObjCustomShape*)pO)->SetMergedItem( aGeometryItem );
747 												SdrGluePointList* pLst = pO->ForceGluePointList();
748 												if ( pLst->GetCount() > nGluePoints )
749 													nId = (sal_Int32)((*pLst)[ (sal_uInt16)nGluePoints ].GetId() + 3 );
750 											}
751 										}
752 									}
753 								}
754 							}
755 							break;
756 						}
757 						if ( bValidGluePoint )
758 						{
759 							Reference< XPropertySet > xPropSet( aXConnector, UNO_QUERY );
760 							if ( xPropSet.is() )
761 							{
762 								if ( nN )
763 								{
764 									String aPropName( RTL_CONSTASCII_USTRINGPARAM( "EndShape" ) );
765 									aAny <<= aXShape;
766 									SetPropValue( aAny, xPropSet, aPropName, sal_True );
767 									aPropName  = String( RTL_CONSTASCII_USTRINGPARAM( "EndGluePointIndex" ) );
768 									aAny <<= nId;
769 									SetPropValue( aAny, xPropSet, aPropName, sal_True );
770 								}
771 								else
772 								{
773 									String aPropName( RTL_CONSTASCII_USTRINGPARAM( "StartShape" ) );
774 									aAny <<= aXShape;
775 									SetPropValue( aAny, xPropSet, aPropName, sal_True );
776 									aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "StartGluePointIndex" ) );
777 									aAny <<= nId;
778 									SetPropValue( aAny, xPropSet, aPropName, sal_True );
779 								}
780 
781 								// Not sure what this is good for, repaint or broadcast of object change.
782 								//( Thus i am adding repaint here
783 								pO->SetChanged();
784 								pO->BroadcastObjectChange();
785 							}
786 						}
787 					}
788 				}
789 			}
790 		}
791 	}
792 }
793 
794 ////////////////////////////////////////////////////////////////////////////////////////////////////
795 
796 static basegfx::B2DPolygon GetLineArrow( const sal_Int32 nLineWidth, const MSO_LineEnd eLineEnd,
797 	const MSO_LineEndWidth eLineWidth, const MSO_LineEndLength eLineLenght,
798 	sal_Int32& rnArrowWidth, sal_Bool& rbArrowCenter,
799 	String& rsArrowName, sal_Bool bScaleArrow )
800 {
801 	basegfx::B2DPolygon aRetval;
802 	// 70 100mm = 2pt = 40 twip. In MS, line width less than 2pt has the same size arrow as 2pt
803 	//If the unit is twip. Make all use this unit especailly the critical value 70/40.
804 	sal_Int32 	nLineWidthCritical = bScaleArrow ? 40 : 70;
805 	double		fLineWidth = nLineWidth < nLineWidthCritical ? nLineWidthCritical : nLineWidth;;
806 	double		fLenghtMul, fWidthMul;
807 	sal_Int32	nLineNumber;
808 	switch( eLineLenght )
809 	{
810 		default :
811 		case mso_lineMediumLenArrow		: fLenghtMul = 3.0; nLineNumber = 2; break;
812 		case mso_lineShortArrow			: fLenghtMul = 2.0; nLineNumber = 1; break;
813 		case mso_lineLongArrow			: fLenghtMul = 5.0; nLineNumber = 3; break;
814 	}
815 	switch( eLineWidth )
816 	{
817 		default :
818 		case mso_lineMediumWidthArrow	: fWidthMul = 3.0; nLineNumber += 3; break;
819 		case mso_lineNarrowArrow		: fWidthMul = 2.0; break;
820 		case mso_lineWideArrow			: fWidthMul = 5.0; nLineNumber += 6; break;
821 	}
822 
823 	rbArrowCenter = sal_False;
824 	switch ( eLineEnd )
825 	{
826 		case mso_lineArrowEnd :
827 		{
828 			basegfx::B2DPolygon aTriangle;
829 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, 0.0 ));
830 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth ));
831 			aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
832 			aTriangle.setClosed(true);
833 			aRetval = aTriangle;
834 			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowEnd " ), RTL_TEXTENCODING_UTF8 );
835 		}
836 		break;
837 
838 		case mso_lineArrowOpenEnd :
839 		{
840 			switch( eLineLenght )
841 			{
842 				default :
843 				case mso_lineMediumLenArrow		: fLenghtMul = 4.5; break;
844 				case mso_lineShortArrow			: fLenghtMul = 3.5; break;
845 				case mso_lineLongArrow			: fLenghtMul = 6.0; break;
846 			}
847 			switch( eLineWidth )
848 			{
849 				default :
850 				case mso_lineMediumWidthArrow	: fWidthMul = 4.5; break;
851 				case mso_lineNarrowArrow		: fWidthMul = 3.5; break;
852 				case mso_lineWideArrow			: fWidthMul = 6.0; break;
853 			}
854 			basegfx::B2DPolygon aTriangle;
855 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
856 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth * 0.91 ));
857 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.85, fLenghtMul * fLineWidth ));
858 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, fLenghtMul * fLineWidth * 0.36 ));
859 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.15, fLenghtMul * fLineWidth ));
860 			aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.91 ));
861 			aTriangle.setClosed(true);
862 			aRetval = aTriangle;
863 			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOpenEnd " ), RTL_TEXTENCODING_UTF8 );
864 		}
865 		break;
866 		case mso_lineArrowStealthEnd :
867 		{
868 			basegfx::B2DPolygon aTriangle;
869 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
870 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth ));
871 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth * 0.60 ));
872 			aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
873 			aTriangle.setClosed(true);
874 			aRetval = aTriangle;
875 			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowStealthEnd " ), RTL_TEXTENCODING_UTF8 );
876 		}
877 		break;
878 		case mso_lineArrowDiamondEnd :
879 		{
880 			basegfx::B2DPolygon aTriangle;
881 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
882 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth * 0.50 ));
883 			aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth ));
884 			aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.50 ));
885 			aTriangle.setClosed(true);
886 			aRetval = aTriangle;
887 			rbArrowCenter = sal_True;
888 			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowDiamondEnd " ), RTL_TEXTENCODING_UTF8 );
889 		}
890 		break;
891 		case mso_lineArrowOvalEnd :
892 		{
893 			aRetval = XPolygon( Point( (sal_Int32)( fWidthMul * fLineWidth * 0.50 ), 0 ),
894 								(sal_Int32)( fWidthMul * fLineWidth * 0.50 ),
895 									(sal_Int32)( fLenghtMul * fLineWidth * 0.50 ), 0, 3600 ).getB2DPolygon();
896 			rbArrowCenter = sal_True;
897 			rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOvalEnd " ), RTL_TEXTENCODING_UTF8 );
898 		}
899 		break;
900 		default: break;
901 	}
902 	rsArrowName.Append( String::CreateFromInt32( nLineNumber ) );
903 	rnArrowWidth = (sal_Int32)( fLineWidth * fWidthMul );
904 
905 	return aRetval;
906 }
907 
908 void DffPropertyReader::ApplyLineAttributes( SfxItemSet& rSet, const MSO_SPT eShapeType ) const // #i28269#
909 {
910 	sal_uInt32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
911 
912 	if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( eShapeType ))
913 	{
914 		nLineFlags &= ~0x08;
915 	}
916 
917 	if ( nLineFlags & 8 )
918 	{
919 		// Linienattribute
920 		sal_Int32 nLineWidth = (sal_Int32)GetPropertyValue( DFF_Prop_lineWidth, 9525 );
921 
922         // support LineCap
923         const MSO_LineCap eLineCap((MSO_LineCap)GetPropertyValue(DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare));
924 
925         switch(eLineCap)
926         {
927             default: /* case mso_lineEndCapFlat */
928             {
929                 // no need to set, it is the default. If this changes, this needs to be activated
930                 // rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_BUTT));
931                 break;
932             }
933             case mso_lineEndCapRound:
934             {
935                 rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_ROUND));
936                 break;
937             }
938             case mso_lineEndCapSquare:
939             {
940                 rSet.Put(XLineCapItem(com::sun::star::drawing::LineCap_SQUARE));
941                 break;
942             }
943         }
944 
945 		MSO_LineDashing eLineDashing = (MSO_LineDashing)GetPropertyValue( DFF_Prop_lineDashing, mso_lineSolid );
946 		if ( eLineDashing == mso_lineSolid )
947 			rSet.Put(XLineStyleItem( XLINE_SOLID ) );
948 		else
949 		{
950 
951 			XDashStyle  eDash = XDASH_RECT;
952 			sal_uInt16	nDots = 1;
953 			sal_uInt32	nDotLen	= nLineWidth / 360;
954 			sal_uInt16	nDashes = 0;
955 			sal_uInt32	nDashLen = ( 8 * nLineWidth ) / 360;
956 			sal_uInt32	nDistance = ( 3 * nLineWidth ) / 360;
957 
958 			switch ( eLineDashing )
959 			{
960 				default:
961 				case mso_lineDotSys :
962 				{
963 					nDots = 1;
964 					nDashes = 0;
965 					nDistance = nDotLen;
966 				}
967 				break;
968 
969 				case mso_lineDashGEL :
970 				{
971 					nDots = 0;
972 					nDashes = 1;
973 					nDashLen = ( 4 * nLineWidth ) / 360;
974 				}
975 				break;
976 
977 				case mso_lineDashDotGEL :
978 				{
979 					nDots = 1;
980 					nDashes = 1;
981 					nDashLen = ( 4 * nLineWidth ) / 360;
982 				}
983 				break;
984 
985 				case mso_lineLongDashGEL :
986 				{
987 					nDots = 0;
988 					nDashes = 1;
989 				}
990 				break;
991 
992 				case mso_lineLongDashDotGEL :
993 				{
994 					nDots = 1;
995 					nDashes = 1;
996 				}
997 				break;
998 
999 				case mso_lineLongDashDotDotGEL:
1000 				{
1001 					nDots = 2;
1002 					nDashes = 1;
1003 				}
1004 				break;
1005 			}
1006 
1007 			rSet.Put( XLineDashItem( String(), XDash( eDash, nDots, nDotLen, nDashes, nDashLen, nDistance ) ) );
1008 			rSet.Put( XLineStyleItem( XLINE_DASH ) );
1009 		}
1010 		rSet.Put( XLineColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_lineColor ), DFF_Prop_lineColor ) ) );
1011 		if ( IsProperty( DFF_Prop_lineOpacity ) )
1012         {
1013 			double nTrans = GetPropertyValue(DFF_Prop_lineOpacity, 0x10000);
1014             nTrans = (nTrans * 100) / 65536;
1015 			rSet.Put(XLineTransparenceItem(
1016                 sal_uInt16(100 - ::rtl::math::round(nTrans))));
1017         }
1018 
1019 		rManager.ScaleEmu( nLineWidth );
1020 		rSet.Put( XLineWidthItem( nLineWidth ) );
1021 
1022 		// SJ: LineJoint (setting each time a line is set, because our internal joint type has another default)
1023 		MSO_LineJoin eLineJointDefault = mso_lineJoinMiter;
1024 		if ( eShapeType == mso_sptMin )
1025 			eLineJointDefault = mso_lineJoinRound;
1026 		MSO_LineJoin eLineJoint = (MSO_LineJoin)GetPropertyValue( DFF_Prop_lineJoinStyle, eLineJointDefault );
1027 		com::sun::star::drawing::LineJoint eXLineJoint( com::sun::star::drawing::LineJoint_MITER );
1028 		if ( eLineJoint == mso_lineJoinBevel )
1029 			eXLineJoint = com::sun::star::drawing::LineJoint_BEVEL;
1030 		else if ( eLineJoint == mso_lineJoinRound )
1031 			eXLineJoint = com::sun::star::drawing::LineJoint_ROUND;
1032 		rSet.Put( XLineJointItem( eXLineJoint ) );
1033 
1034 		if ( nLineFlags & 0x10 )
1035 		{
1036 			sal_Bool bScaleArrows = rManager.pSdrModel->GetScaleUnit() == MAP_TWIP;
1037 			///////////////
1038 			// LineStart //
1039 			///////////////
1040 			if ( IsProperty( DFF_Prop_lineStartArrowhead ) )
1041 			{
1042 				MSO_LineEnd			eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineStartArrowhead );
1043 				MSO_LineEndWidth	eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineStartArrowWidth, mso_lineMediumWidthArrow );
1044 				MSO_LineEndLength	eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineStartArrowLength, mso_lineMediumLenArrow );
1045 
1046 				sal_Int32	nArrowWidth;
1047 				sal_Bool	bArrowCenter;
1048 				String		aArrowName;
1049 				basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
1050 
1051 				rSet.Put( XLineStartWidthItem( nArrowWidth ) );
1052 				rSet.Put( XLineStartItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
1053 				rSet.Put( XLineStartCenterItem( bArrowCenter ) );
1054 			}
1055 			/////////////
1056 			// LineEnd //
1057 			/////////////
1058 			if ( IsProperty( DFF_Prop_lineEndArrowhead ) )
1059 			{
1060 				MSO_LineEnd			eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineEndArrowhead );
1061 				MSO_LineEndWidth	eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineEndArrowWidth, mso_lineMediumWidthArrow );
1062 				MSO_LineEndLength	eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineEndArrowLength, mso_lineMediumLenArrow );
1063 
1064 				sal_Int32	nArrowWidth;
1065 				sal_Bool	bArrowCenter;
1066 				String		aArrowName;
1067 				basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
1068 
1069 				rSet.Put( XLineEndWidthItem( nArrowWidth ) );
1070 				rSet.Put( XLineEndItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
1071 				rSet.Put( XLineEndCenterItem( bArrowCenter ) );
1072 			}
1073 
1074             // this was used to at least adapt the lineDash to the lineCap before lineCap was
1075             // supported, so with supporting lineCap this is no longer needed
1076 			//if ( IsProperty( DFF_Prop_lineEndCapStyle ) )
1077 			//{
1078 			//	MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle );
1079 			//	const SfxPoolItem* pPoolItem = NULL;
1080 			//	if ( rSet.GetItemState( XATTR_LINEDASH, sal_False, &pPoolItem ) == SFX_ITEM_SET )
1081 			//	{
1082 			//		XDashStyle eNewStyle = XDASH_RECT;
1083 			//		if ( eLineCap == mso_lineEndCapRound )
1084 			//			eNewStyle = XDASH_ROUND;
1085 			//		const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue();
1086 			//		if ( rOldDash.GetDashStyle() != eNewStyle )
1087 			//		{
1088 			//			XDash aNew( rOldDash );
1089 			//			aNew.SetDashStyle( eNewStyle );
1090 			//			rSet.Put( XLineDashItem( XubString(), aNew ) );
1091 			//		}
1092 			//	}
1093 			//}
1094 		}
1095 	}
1096 	else
1097 		rSet.Put( XLineStyleItem( XLINE_NONE ) );
1098 }
1099 
1100 struct ShadeColor
1101 {
1102 	Color		aColor;
1103 	double		fDist;
1104 
1105 	ShadeColor( const Color& rC, double fR ) : aColor( rC ), fDist( fR ) {};
1106 };
1107 
1108 void GetShadeColors( const SvxMSDffManager& rManager, const DffPropertyReader& rProperties, SvStream& rIn, std::vector< ShadeColor >& rShadeColors )
1109 {
1110 	sal_uInt32 nPos = rIn.Tell();
1111 	if ( rProperties.IsProperty( DFF_Prop_fillShadeColors ) )
1112 	{
1113 		if ( rProperties.SeekToContent( DFF_Prop_fillShadeColors, rIn ) )
1114 		{
1115 			sal_uInt16 i = 0, nNumElem = 0, nNumElemReserved = 0, nSize = 0;
1116 			rIn >> nNumElem >> nNumElemReserved >> nSize;
1117 			for ( ; i < nNumElem; i++ )
1118 			{
1119 				sal_Int32	nColor;
1120 				sal_Int32	nDist;
1121 
1122 				rIn >> nColor >> nDist;
1123 				rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( nColor, DFF_Prop_fillColor ), 1.0 - ( nDist / 65536.0 ) ) );
1124 			}
1125 		}
1126 	}
1127 	if ( !rShadeColors.size() )
1128 	{
1129 		rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ), 0 ) );
1130 		rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ), 1 ) );
1131 	}
1132 	rIn.Seek( nPos );
1133 }
1134 
1135 struct QuantErr
1136 {
1137 	double	fRed;
1138 	double	fGreen;
1139 	double	fBlue;
1140 
1141 	QuantErr() : fRed( 0.0 ), fGreen( 0.0 ), fBlue( 0.0 ){};
1142 };
1143 
1144 void ApplyRectangularGradientAsBitmap( const SvxMSDffManager& rManager, SvStream& rIn, SfxItemSet& rSet, const std::vector< ShadeColor >& rShadeColors, const DffObjData& rObjData, sal_Int32 nFix16Angle )
1145 {
1146 	Size aBitmapSizePixel( static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetWidth() / 2540.0 ) * 90.0 ),		// we will create a bitmap with 90 dpi
1147 						   static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetHeight() / 2540.0 ) * 90.0 ) );
1148 	if ( aBitmapSizePixel.Width() && aBitmapSizePixel.Height() && ( aBitmapSizePixel.Width() <= 1024 ) && ( aBitmapSizePixel.Height() <= 1024 ) )
1149 	{
1150 //		std::vector< QuantErr > aQuantErrCurrScan( aBitmapSizePixel.Width() + 1 );
1151 //		std::vector< QuantErr > aQuantErrNextScan( aBitmapSizePixel.Width() + 1 );
1152 
1153 		double fFocusX = rManager.GetPropertyValue( DFF_Prop_fillToRight, 0 ) / 65536.0;
1154 		double fFocusY = rManager.GetPropertyValue( DFF_Prop_fillToBottom, 0 ) / 65536.0;
1155 
1156 		Bitmap aBitmap( aBitmapSizePixel, 24 );
1157 		BitmapWriteAccess* pAcc = aBitmap.AcquireWriteAccess();
1158 		if ( pAcc )
1159 		{
1160 			sal_Int32 nX, nY;
1161 			for ( nY = 0; nY < aBitmapSizePixel.Height(); nY++ )
1162 			{
1163 				for ( nX = 0; nX < aBitmapSizePixel.Width(); nX++ )
1164 				{
1165 					double fX = static_cast< double >( nX ) / aBitmapSizePixel.Width();
1166 					double fY = static_cast< double >( nY ) / aBitmapSizePixel.Height();
1167 
1168 					double fD, fDist;
1169 					if ( fX < fFocusX )
1170 					{
1171 						if ( fY < fFocusY )
1172 						{
1173 							if ( fX > fY )
1174 								fDist = fY, fD = fFocusY;
1175 							else
1176 								fDist = fX, fD = fFocusX;
1177 						}
1178 						else
1179 						{
1180 							if ( fX > ( 1 - fY ) )
1181 								fDist = ( 1 - fY ), fD = 1 - fFocusY;
1182 							else
1183 								fDist = fX, fD = fFocusX;
1184 						}
1185 					}
1186 					else
1187 					{
1188 						if ( fY < fFocusY )
1189 						{
1190 							if ( ( 1 - fX ) > fY )
1191 								fDist = fY, fD = fFocusY;
1192 							else
1193 								fDist = ( 1 - fX ), fD = 1 - fFocusX;
1194 						}
1195 						else
1196 						{
1197 							if ( ( 1 - fX ) > ( 1 - fY ) )
1198 								fDist = ( 1 - fY ), fD = 1 - fFocusY;
1199 							else
1200 								fDist = ( 1 - fX ), fD = 1 - fFocusX;
1201 						}
1202 					}
1203 					if ( fD != 0.0 )
1204 						fDist /= fD;
1205 
1206 					std::vector< ShadeColor >::const_iterator aIter( rShadeColors.begin() );
1207 					double fA = 0.0;
1208 					Color aColorA = aIter->aColor;
1209 					double fB = 1.0;
1210 					Color aColorB( aColorA );
1211 					while ( aIter != rShadeColors.end() )
1212 					{
1213 						if ( aIter->fDist <= fDist )
1214 						{
1215 							if ( aIter->fDist >= fA )
1216 							{
1217 								fA = aIter->fDist;
1218 								aColorA = aIter->aColor;
1219 							}
1220 						}
1221 						if ( aIter->fDist > fDist )
1222 						{
1223 							if ( aIter->fDist <= fB )
1224 							{
1225 								fB = aIter->fDist;
1226 								aColorB = aIter->aColor;
1227 							}
1228 						}
1229 						aIter++;
1230 					}
1231 					double fRed = aColorA.GetRed(), fGreen = aColorA.GetGreen(), fBlue = aColorA.GetBlue();
1232 					double fD1 = fB - fA;
1233 					if ( fD1 != 0.0 )
1234 					{
1235 						fRed   += ( ( ( fDist - fA ) * ( aColorB.GetRed() - aColorA.GetRed() ) ) / fD1 );		// + aQuantErrCurrScan[ nX ].fRed;
1236 						fGreen += ( ( ( fDist - fA ) * ( aColorB.GetGreen() - aColorA.GetGreen() ) ) / fD1 );	// + aQuantErrCurrScan[ nX ].fGreen;
1237 						fBlue  += ( ( ( fDist - fA ) * ( aColorB.GetBlue() - aColorA.GetBlue() ) ) / fD1 );		// + aQuantErrCurrScan[ nX ].fBlue;
1238 					}
1239 					sal_Int16 nRed   = static_cast< sal_Int16 >( fRed   + 0.5 );
1240 					sal_Int16 nGreen = static_cast< sal_Int16 >( fGreen + 0.5 );
1241 					sal_Int16 nBlue  = static_cast< sal_Int16 >( fBlue  + 0.5 );
1242 /*
1243 					double fErr = fRed - nRed;
1244 					aQuantErrCurrScan[ nX + 1 ].fRed += 7.0 * fErr / 16.0;
1245 					if ( nX )
1246 						aQuantErrNextScan[ nX - 1 ].fRed += 3.0 * fErr / 16.0;
1247 					aQuantErrNextScan[ nX ].fRed += 5.0 * fErr / 16.0;
1248 					aQuantErrNextScan[ nX + 1 ].fRed += 1.0 * fErr / 16.0;
1249 
1250 					fErr = fGreen - nGreen;
1251 					aQuantErrCurrScan[ nX + 1 ].fGreen += 7.0 * fErr / 16.0;
1252 					if ( nX )
1253 						aQuantErrNextScan[ nX - 1 ].fGreen += 3.0 * fErr / 16.0;
1254 					aQuantErrNextScan[ nX ].fGreen += 5.0 * fErr / 16.0;
1255 					aQuantErrNextScan[ nX + 1 ].fGreen += 1.0 * fErr / 16.0;
1256 
1257 					fErr = fBlue - nBlue;
1258 					aQuantErrCurrScan[ nX + 1 ].fBlue += 7.0 * fErr / 16.0;
1259 					if ( nX )
1260 						aQuantErrNextScan[ nX - 1 ].fBlue += 3.0 * fErr / 16.0;
1261 					aQuantErrNextScan[ nX ].fBlue += 5.0 * fErr / 16.0;
1262 					aQuantErrNextScan[ nX + 1 ].fBlue += 1.0 * fErr / 16.0;
1263 */
1264 					if ( nRed < 0 )
1265 						nRed = 0;
1266 					if ( nRed > 255 )
1267 						nRed = 255;
1268 					if ( nGreen < 0 )
1269 						nGreen = 0;
1270 					if ( nGreen > 255 )
1271 						nGreen = 255;
1272 					if ( nBlue < 0 )
1273 						nBlue = 0;
1274 					if ( nBlue > 255 )
1275 						nBlue = 255;
1276 
1277 					pAcc->SetPixel( nY, nX, BitmapColor( static_cast< sal_Int8 >( nRed ), static_cast< sal_Int8 >( nGreen ), static_cast< sal_Int8 >( nBlue ) ) );
1278 				}
1279 /*
1280 				aQuantErrCurrScan.swap( aQuantErrNextScan );
1281 				std::vector< QuantErr >::iterator aIter( aQuantErrNextScan.begin() );
1282 				while( aIter != aQuantErrNextScan.end() )
1283 				{
1284 					*aIter = QuantErr();
1285 					aIter++;
1286 				}
1287 */
1288 			}
1289 			aBitmap.ReleaseAccess( pAcc );
1290 
1291 			if ( nFix16Angle )
1292 			{
1293 				sal_Bool bRotateWithShape = sal_True;	// sal_True seems to be default
1294 				sal_uInt32 nPos = rIn.Tell();
1295 				if ( const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.SeekToContent( rIn, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ) )
1296 				{
1297 					const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.Current()->SeekToBegOfRecord( rIn );
1298 					DffPropertyReader aSecPropSet( rManager );
1299 					aSecPropSet.ReadPropSet( rIn, NULL );
1300 					sal_Int32 nSecFillProperties = aSecPropSet.GetPropertyValue( DFF_Prop_fNoFillHitTest, 0x200020 );
1301 					bRotateWithShape = ( nSecFillProperties & 0x0020 );
1302 				}
1303 				rIn.Seek( nPos );
1304 				if ( bRotateWithShape )
1305 				{
1306 					aBitmap.Rotate( nFix16Angle / 10, rShadeColors[ 0 ].aColor );
1307 
1308 					sal_uLong nMirrorFlags = BMP_MIRROR_NONE;
1309 					if ( rObjData.nSpFlags & SP_FFLIPV )
1310 						nMirrorFlags |= BMP_MIRROR_VERT;
1311 					if ( rObjData.nSpFlags & SP_FFLIPH )
1312 						nMirrorFlags |= BMP_MIRROR_HORZ;
1313 					if ( nMirrorFlags != BMP_MIRROR_NONE )
1314 						aBitmap.Mirror( nMirrorFlags );
1315 				}
1316 			}
1317 
1318 			rSet.Put(XFillBmpTileItem(false));
1319 			rSet.Put(XFillBitmapItem(String(), Graphic(aBitmap)));
1320 		}
1321 	}
1322 }
1323 
1324 void DffPropertyReader::ApplyFillAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
1325 {
1326 	sal_uInt32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
1327 
1328 	std::vector< ShadeColor > aShadeColors;
1329 	GetShadeColors( rManager, *this, rIn, aShadeColors );
1330 
1331 	if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType ))
1332 	{
1333 		nFillFlags &= ~0x10;
1334 	}
1335 
1336 	if ( nFillFlags & 0x10 )
1337 	{
1338 		MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
1339 		XFillStyle eXFill = XFILL_NONE;
1340 		switch( eMSO_FillType )
1341 		{
1342 			case mso_fillSolid :			// Fill with a solid color
1343 				eXFill = XFILL_SOLID;
1344 			break;
1345 			case mso_fillPattern :			// Fill with a pattern (bitmap)
1346 			case mso_fillTexture :			// A texture (pattern with its own color map)
1347 			case mso_fillPicture :			// Center a picture in the shape
1348 				eXFill = XFILL_BITMAP;
1349 			break;
1350 			case mso_fillShadeCenter :		// Shade from bounding rectangle to end point
1351 			{
1352 				//If it is imported as a bitmap, it will not work well with transparecy especially 100
1353 				//But the gradient look well comparing with imported as gradient. And rotate with shape
1354 				//also works better. So here just keep it.
1355 				if ( rObjData.aBoundRect.IsEmpty() )// size of object needed to be able
1356 					eXFill = XFILL_GRADIENT;		// to create a bitmap substitution
1357 				else
1358 					eXFill = XFILL_BITMAP;
1359 			}
1360 			break;
1361 			case mso_fillShade :			// Shade from start to end points
1362 			case mso_fillShadeShape :		// Shade from shape outline to end point
1363 			case mso_fillShadeScale :		// Similar to mso_fillShade, but the fillAngle
1364 			case mso_fillShadeTitle :		// special type - shade to title ---  for PP
1365 				eXFill = XFILL_GRADIENT;
1366 			break;
1367 //			case mso_fillBackground	:		// Use the background fill color/pattern
1368 			default: break;
1369 		}
1370 		rSet.Put( XFillStyleItem( eXFill ) );
1371 
1372 		double dTrans  = 1.0;
1373 		double dBackTrans = 1.0;
1374 		if (IsProperty(DFF_Prop_fillOpacity))
1375 		{
1376 			dTrans = GetPropertyValue(DFF_Prop_fillOpacity) / 65536.0;
1377 			if ( eXFill != XFILL_GRADIENT )
1378 			{
1379 				dTrans = dTrans * 100;
1380 				rSet.Put(XFillTransparenceItem(
1381 					sal_uInt16(100 - ::rtl::math::round(dTrans))));
1382 			}
1383 		}
1384 
1385 		if ( IsProperty(DFF_Prop_fillBackOpacity) )
1386 			dBackTrans = GetPropertyValue(DFF_Prop_fillBackOpacity) / 65536.0;
1387 
1388 		if ( ( eMSO_FillType == mso_fillShadeCenter ) && ( eXFill == XFILL_BITMAP ) )
1389 		{
1390 			ApplyRectangularGradientAsBitmap( rManager, rIn, rSet, aShadeColors, rObjData, mnFix16Angle );
1391 		}
1392 		else if ( eXFill == XFILL_GRADIENT )
1393 		{
1394 			ImportGradientColor ( rSet, eMSO_FillType, dTrans , dBackTrans );
1395 		}
1396 		else if ( eXFill == XFILL_BITMAP )
1397 		{
1398 			if( IsProperty( DFF_Prop_fillBlip ) )
1399 			{
1400 				Graphic aGraf;
1401                 // first try to get BLIP from cache
1402                 sal_Bool bOK = rManager.GetBLIP( GetPropertyValue( DFF_Prop_fillBlip ), aGraf, NULL );
1403                 // then try directly from stream (i.e. Excel chart hatches/bitmaps)
1404                 if ( !bOK )
1405                     bOK = SeekToContent( DFF_Prop_fillBlip, rIn ) && rManager.GetBLIPDirect( rIn, aGraf, NULL );
1406                 if ( bOK )
1407 				{
1408 					if ( eMSO_FillType == mso_fillPattern )
1409 					{
1410 						Color aCol1( COL_WHITE ), aCol2( COL_WHITE );
1411 
1412                         if ( IsProperty( DFF_Prop_fillColor ) )
1413 							aCol1 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor );
1414 
1415                         if ( IsProperty( DFF_Prop_fillBackColor ) )
1416 							aCol2 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor ), DFF_Prop_fillBackColor );
1417 
1418                         rSet.Put(XFillBitmapItem(String(), aGraf));
1419 					}
1420 					else if ( eMSO_FillType == mso_fillTexture )
1421 					{
1422 						rSet.Put(XFillBmpTileItem(true));
1423 						rSet.Put(XFillBitmapItem(String(), aGraf));
1424 						rSet.Put(XFillBmpSizeXItem(GetPropertyValue(DFF_Prop_fillWidth, 0) / 360));
1425 						rSet.Put(XFillBmpSizeYItem(GetPropertyValue(DFF_Prop_fillHeight, 0) / 360));
1426 						rSet.Put(XFillBmpSizeLogItem(true));
1427 					}
1428 					else
1429 					{
1430 						rSet.Put(XFillBitmapItem(String(), aGraf));
1431 						rSet.Put(XFillBmpTileItem(false));
1432 					}
1433 				}
1434 			}
1435 		}
1436 	}
1437 	else
1438 		rSet.Put( XFillStyleItem( XFILL_NONE ) );
1439 }
1440 
1441 void DffPropertyReader::ApplyCustomShapeTextAttributes( SfxItemSet& rSet ) const
1442 {
1443 //    sal_uInt32 nTextFlags = aTextObj.GetTextFlags();
1444 	sal_Bool  bVerticalText = sal_False;
1445 	sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ) / 360;		// 0.25 cm (emu)
1446 	sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ) / 360;	// 0.25 cm (emu)
1447 	sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ) / 360;		// 0.13 cm (emu)
1448 	sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 ) /360;	// 0.13 cm (emu)
1449 
1450 	SdrTextVertAdjust eTVA;
1451 	SdrTextHorzAdjust eTHA;
1452 
1453 	if ( IsProperty( DFF_Prop_txflTextFlow ) )
1454 	{
1455 		MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
1456 		switch( eTextFlow )
1457 		{
1458 			case mso_txflTtoBA :	/* #68110# */	// Top to Bottom @-font, oben -> unten
1459 			case mso_txflTtoBN :					// Top to Bottom non-@, oben -> unten
1460 			case mso_txflVertN :					// Vertical, non-@, oben -> unten
1461 				bVerticalText = sal_True;			// nTextRotationAngle += 27000;
1462 			break;
1463 			default: break;
1464 		}
1465 	}
1466 	sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 );
1467 	if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) )
1468 		bVerticalText = !bVerticalText;
1469 
1470 	if ( bVerticalText )
1471 	{
1472     	eTVA = SDRTEXTVERTADJUST_BLOCK;
1473 	    eTHA = SDRTEXTHORZADJUST_CENTER;
1474 
1475 		// Textverankerung lesen
1476 		MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
1477 
1478 		switch( eTextAnchor )
1479 		{
1480 			case mso_anchorTop:
1481 			case mso_anchorTopCentered:
1482 			case mso_anchorTopBaseline:
1483 			case mso_anchorTopCenteredBaseline:
1484 				eTHA = SDRTEXTHORZADJUST_RIGHT;
1485 			break;
1486 
1487 			case mso_anchorMiddle :
1488 			case mso_anchorMiddleCentered:
1489 				eTHA = SDRTEXTHORZADJUST_CENTER;
1490 			break;
1491 
1492 			case mso_anchorBottom:
1493 			case mso_anchorBottomCentered:
1494 			case mso_anchorBottomBaseline:
1495 			case mso_anchorBottomCenteredBaseline:
1496 				eTHA = SDRTEXTHORZADJUST_LEFT;
1497 			break;
1498 		}
1499         // if there is a 100% use of following attributes, the textbox can been aligned also in vertical direction
1500         switch ( eTextAnchor )
1501         {
1502 			case mso_anchorTopCentered :
1503 			case mso_anchorMiddleCentered :
1504 			case mso_anchorBottomCentered :
1505 			case mso_anchorTopCenteredBaseline:
1506 			case mso_anchorBottomCenteredBaseline:
1507 				eTVA = SDRTEXTVERTADJUST_CENTER;
1508             break;
1509 
1510             default :
1511                 eTVA = SDRTEXTVERTADJUST_TOP;
1512             break;
1513         }
1514 	}
1515 	else
1516 	{
1517 		eTVA = SDRTEXTVERTADJUST_CENTER;
1518 		eTHA = SDRTEXTHORZADJUST_BLOCK;
1519 
1520 		// Textverankerung lesen
1521 		MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
1522 
1523 		switch( eTextAnchor )
1524 		{
1525 			case mso_anchorTop:
1526 			case mso_anchorTopCentered:
1527 			case mso_anchorTopBaseline:
1528 			case mso_anchorTopCenteredBaseline:
1529 				eTVA = SDRTEXTVERTADJUST_TOP;
1530 			break;
1531 
1532 			case mso_anchorMiddle :
1533 			case mso_anchorMiddleCentered:
1534 				eTVA = SDRTEXTVERTADJUST_CENTER;
1535 			break;
1536 
1537 			case mso_anchorBottom:
1538 			case mso_anchorBottomCentered:
1539 			case mso_anchorBottomBaseline:
1540 			case mso_anchorBottomCenteredBaseline:
1541 				eTVA = SDRTEXTVERTADJUST_BOTTOM;
1542 			break;
1543 		}
1544         // if there is a 100% usage of following attributes, the textbox can be aligned also in horizontal direction
1545         switch ( eTextAnchor )
1546         {
1547 			case mso_anchorTopCentered :
1548 			case mso_anchorMiddleCentered :
1549 			case mso_anchorBottomCentered :
1550 			case mso_anchorTopCenteredBaseline:
1551 			case mso_anchorBottomCenteredBaseline:
1552                 eTHA = SDRTEXTHORZADJUST_CENTER;    // the text has to be displayed using the full width;
1553             break;
1554 
1555             default :
1556                 eTHA = SDRTEXTHORZADJUST_LEFT;
1557             break;
1558         }
1559 	}
1560 	rSet.Put( SvxFrameDirectionItem( bVerticalText ? FRMDIR_VERT_TOP_RIGHT : FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR ) );
1561 
1562 	rSet.Put( SdrTextVertAdjustItem( eTVA ) );
1563 	rSet.Put( SdrTextHorzAdjustItem( eTHA ) );
1564 
1565 	rSet.Put( SdrTextLeftDistItem( nTextLeft ) );
1566 	rSet.Put( SdrTextRightDistItem( nTextRight ) );
1567 	rSet.Put( SdrTextUpperDistItem( nTextTop ) );
1568 	rSet.Put( SdrTextLowerDistItem( nTextBottom ) );
1569 
1570 	rSet.Put( SdrTextWordWrapItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_True : sal_False ) );
1571 	rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
1572 
1573 //	rSet.Put( SdrTextAutoGrowWidthItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_False : sal_True ) );
1574 //	rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
1575 }
1576 
1577 void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
1578 {
1579 
1580 	sal_uInt32 nAdjustmentsWhichNeedsToBeConverted = 0;
1581 
1582 	///////////////////////////////////////
1583 	// creating SdrCustomShapeGeometryItem //
1584 	///////////////////////////////////////
1585 	typedef uno::Sequence< beans::PropertyValue > PropSeq;
1586 	typedef std::vector< beans::PropertyValue > PropVec;
1587 	typedef PropVec::iterator PropVecIter;
1588 	PropVecIter aIter;
1589 	PropVecIter aEnd;
1590 
1591 
1592 	// aPropVec will be filled with all PropertyValues
1593 	PropVec aPropVec;
1594 	PropertyValue aProp;
1595 
1596 	/////////////////////////////////////////////////////////////////////
1597 	// "Type" property, including the predefined CustomShape type name //
1598 	/////////////////////////////////////////////////////////////////////
1599 	const rtl::OUString	sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
1600 	aProp.Name  = sType;
1601 	aProp.Value <<= EnhancedCustomShapeTypeNames::Get( rObjData.eShapeType );
1602 	aPropVec.push_back( aProp );
1603 
1604 /*
1605 	/////////////////
1606 	// "MirroredX" //
1607 	/////////////////
1608 	if ( nShapeFlags & SP_FFLIPH )
1609 	{
1610 		const rtl::OUString	sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1611 		sal_Bool bMirroredX = sal_True;
1612 		aProp.Name = sMirroredX;
1613 		aProp.Value <<= bMirroredX;
1614 		aPropVec.push_back( aProp );
1615 	}
1616 	/////////////////
1617 	// "MirroredY" //
1618 	/////////////////
1619 	if ( nShapeFlags & SP_FFLIPV )
1620 	{
1621 		const rtl::OUString	sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1622 		sal_Bool bMirroredY = sal_True;
1623 		aProp.Name = sMirroredY;
1624 		aProp.Value <<= bMirroredY;
1625 		aPropVec.push_back( aProp );
1626 	}
1627 */
1628 	///////////////
1629 	// "ViewBox" //
1630 	///////////////
1631 
1632 	sal_Int32 nCoordWidth = 21600;	// needed to replace handle type center with absolute value
1633 	sal_Int32 nCoordHeight= 21600;
1634 	if ( IsProperty( DFF_Prop_geoLeft ) || IsProperty( DFF_Prop_geoTop ) || IsProperty( DFF_Prop_geoRight ) || IsProperty( DFF_Prop_geoBottom ) )
1635 	{
1636 		com::sun::star::awt::Rectangle aViewBox;
1637 		const rtl::OUString	sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
1638 		aViewBox.X = GetPropertyValue( DFF_Prop_geoLeft, 0 );
1639 		aViewBox.Y = GetPropertyValue( DFF_Prop_geoTop, 0 );
1640 		aViewBox.Width = nCoordWidth = ((sal_Int32)GetPropertyValue( DFF_Prop_geoRight, 21600 ) ) - aViewBox.X;
1641 		aViewBox.Height = nCoordHeight = ((sal_Int32)GetPropertyValue( DFF_Prop_geoBottom, 21600 ) ) - aViewBox.Y;
1642 		aProp.Name = sViewBox;
1643 		aProp.Value <<= aViewBox;
1644 		aPropVec.push_back( aProp );
1645 	}
1646 	/////////////////////
1647 	// TextRotateAngle //
1648 	/////////////////////
1649 	if ( IsProperty( DFF_Prop_txflTextFlow ) || IsProperty( DFF_Prop_cdirFont ) )
1650 	{
1651 		sal_Int32 nTextRotateAngle = 0;
1652 		MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
1653 /*		sal_Int32	 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ); */
1654 
1655 		if ( eTextFlow == mso_txflBtoT )	// Bottom to Top non-@, unten -> oben
1656 			nTextRotateAngle += 90;
1657 		switch( GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ) )	// SJ: mso_cdir90 and mso_cdir270 will be simulated by
1658 		{															// activating vertical writing for the text objects
1659 			case mso_cdir90 :
1660 			{
1661 				if ( eTextFlow == mso_txflTtoBA )
1662 					nTextRotateAngle -= 180;
1663 			}
1664 			break;
1665 			case mso_cdir180: nTextRotateAngle -= 180; break;
1666 			case mso_cdir270:
1667 			{
1668 				if ( eTextFlow != mso_txflTtoBA )
1669 					nTextRotateAngle -= 180;
1670 			}
1671 			break;
1672 			default: break;
1673 		}
1674 		if ( nTextRotateAngle )
1675 		{
1676 			double fTextRotateAngle = nTextRotateAngle;
1677 			const rtl::OUString	sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
1678 			aProp.Name = sTextRotateAngle;
1679 			aProp.Value <<= fTextRotateAngle;
1680 			aPropVec.push_back( aProp );
1681 		}
1682 	}
1683 	//////////////////////////////////////////
1684 	// "Extrusion" PropertySequence element //
1685 	//////////////////////////////////////////
1686 	sal_Bool bExtrusionOn = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 8 ) != 0;
1687 	if ( bExtrusionOn )
1688 	{
1689 		PropVec aExtrusionPropVec;
1690 
1691 		// "Extrusion"
1692 		const rtl::OUString	sExtrusionOn( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
1693 		aProp.Name = sExtrusionOn;
1694 		aProp.Value <<= bExtrusionOn;
1695 		aExtrusionPropVec.push_back( aProp );
1696 
1697 		// "Brightness"
1698 		if ( IsProperty( DFF_Prop_c3DAmbientIntensity ) )
1699 		{
1700 			const rtl::OUString	sExtrusionBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
1701 			double fBrightness = (sal_Int32)GetPropertyValue( DFF_Prop_c3DAmbientIntensity );
1702 			fBrightness /= 655.36;
1703 			aProp.Name = sExtrusionBrightness;
1704 			aProp.Value <<= fBrightness;
1705 			aExtrusionPropVec.push_back( aProp );
1706 		}
1707 		// "Depth" in 1/100mm
1708 		if ( IsProperty( DFF_Prop_c3DExtrudeBackward ) || IsProperty( DFF_Prop_c3DExtrudeForward ) )
1709 		{
1710 			const rtl::OUString	sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
1711 			double fBackDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeBackward, 1270 * 360 )) / 360.0;
1712 			double fForeDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeForward, 0 )) / 360.0;
1713 			double fDepth = fBackDepth + fForeDepth;
1714 			double fFraction = fDepth != 0.0 ? fForeDepth / fDepth : 0;
1715 			EnhancedCustomShapeParameterPair aDepthParaPair;
1716 			aDepthParaPair.First.Value <<= fDepth;
1717 			aDepthParaPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
1718 			aDepthParaPair.Second.Value <<= fFraction;
1719 			aDepthParaPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
1720 			aProp.Name = sDepth;
1721 			aProp.Value <<= aDepthParaPair;
1722 			aExtrusionPropVec.push_back( aProp );
1723 		}
1724 		// "Diffusion"
1725 		if ( IsProperty( DFF_Prop_c3DDiffuseAmt ) )
1726 		{
1727 			const rtl::OUString	sExtrusionDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
1728 			double fDiffusion = (sal_Int32)GetPropertyValue( DFF_Prop_c3DDiffuseAmt );
1729 			fDiffusion /= 655.36;
1730 			aProp.Name = sExtrusionDiffusion;
1731 			aProp.Value <<= fDiffusion;
1732 			aExtrusionPropVec.push_back( aProp );
1733 		}
1734 		// "NumberOfLineSegments"
1735 		if ( IsProperty( DFF_Prop_c3DTolerance ) )
1736 		{
1737 			const rtl::OUString	sExtrusionNumberOfLineSegments( RTL_CONSTASCII_USTRINGPARAM ( "NumberOfLineSegments" ) );
1738 			aProp.Name = sExtrusionNumberOfLineSegments;
1739 			aProp.Value <<= (sal_Int32)GetPropertyValue( DFF_Prop_c3DTolerance );
1740 			aExtrusionPropVec.push_back( aProp );
1741 		}
1742 		// "LightFace"
1743 		const rtl::OUString	sExtrusionLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) );
1744 		sal_Bool bExtrusionLightFace = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 1 ) != 0;
1745 		aProp.Name = sExtrusionLightFace;
1746 		aProp.Value <<= bExtrusionLightFace;
1747 		aExtrusionPropVec.push_back( aProp );
1748 		// "FirstLightHarsh"
1749 		const rtl::OUString	sExtrusionFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) );
1750 		sal_Bool bExtrusionFirstLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 2 ) != 0;
1751 		aProp.Name = sExtrusionFirstLightHarsh;
1752 		aProp.Value <<= bExtrusionFirstLightHarsh;
1753 		aExtrusionPropVec.push_back( aProp );
1754 		// "SecondLightHarsh"
1755 		const rtl::OUString	sExtrusionSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) );
1756 		sal_Bool bExtrusionSecondLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 1 ) != 0;
1757 		aProp.Name = sExtrusionSecondLightHarsh;
1758 		aProp.Value <<= bExtrusionSecondLightHarsh;
1759 		aExtrusionPropVec.push_back( aProp );
1760 		// "FirstLightLevel"
1761 		if ( IsProperty( DFF_Prop_c3DKeyIntensity ) )
1762 		{
1763 			const rtl::OUString	sExtrusionFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) );
1764 			double fFirstLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyIntensity );
1765 			fFirstLightLevel /= 655.36;
1766 			aProp.Name = sExtrusionFirstLightLevel;
1767 			aProp.Value <<= fFirstLightLevel;
1768 			aExtrusionPropVec.push_back( aProp );
1769 		}
1770 		// "SecondLightLevel"
1771 		if ( IsProperty( DFF_Prop_c3DFillIntensity ) )
1772 		{
1773 			const rtl::OUString	sExtrusionSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) );
1774 			double fSecondLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DFillIntensity );
1775 			fSecondLightLevel /= 655.36;
1776 			aProp.Name = sExtrusionSecondLightLevel;
1777 			aProp.Value <<= fSecondLightLevel;
1778 			aExtrusionPropVec.push_back( aProp );
1779 		}
1780 		// "FirtstLightDirection"
1781 		if ( IsProperty( DFF_Prop_c3DKeyX ) || IsProperty( DFF_Prop_c3DKeyY ) || IsProperty( DFF_Prop_c3DKeyZ ) )
1782 		{
1783 			double fLightX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyX, 50000 ));
1784 			double fLightY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyY, 0 ));
1785 			double fLightZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyZ, 10000 ));
1786 			::com::sun::star::drawing::Direction3D aExtrusionFirstLightDirection( fLightX, fLightY, fLightZ );
1787 			const rtl::OUString	sExtrusionFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
1788 			aProp.Name = sExtrusionFirstLightDirection;
1789 			aProp.Value <<= aExtrusionFirstLightDirection;
1790 			aExtrusionPropVec.push_back( aProp );
1791 		}
1792 		// "SecondLightDirection"
1793 		if ( IsProperty( DFF_Prop_c3DFillX ) || IsProperty( DFF_Prop_c3DFillY ) || IsProperty( DFF_Prop_c3DFillZ ) )
1794 		{
1795 			double fLight2X = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillX, (sal_uInt32)-50000 ));
1796 			double fLight2Y = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillY, 0 ));
1797 			double fLight2Z = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillZ, 10000 ));
1798 			::com::sun::star::drawing::Direction3D aExtrusionSecondLightDirection( fLight2X, fLight2Y, fLight2Z );
1799 			const rtl::OUString	sExtrusionSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
1800 			aProp.Name = sExtrusionSecondLightDirection;
1801 			aProp.Value <<= aExtrusionSecondLightDirection;
1802 			aExtrusionPropVec.push_back( aProp );
1803 		}
1804 
1805 /* LockRotationCenter, OrientationAngle and Orientation needs to be converted to use the properties AngleX, AngleY and RotationAngle instead.
1806 		// "LockRotationCenter"
1807 		const rtl::OUString	sExtrusionLockRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "LockRotationCenter" ) );
1808 		sal_Bool bExtrusionLockRotationCenter = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 16 ) != 0;
1809 		aProp.Name = sExtrusionLockRotationCenter;
1810 		aProp.Value <<= bExtrusionLockRotationCenter;
1811 		aExtrusionPropVec.push_back( aProp );
1812 
1813 		// "Orientation"
1814 		if ( IsProperty( DFF_Prop_c3DRotationAxisX ) || IsProperty( DFF_Prop_c3DRotationAxisY ) || IsProperty( DFF_Prop_c3DRotationAxisZ ) )
1815 		{
1816 			double fRotX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 ));
1817 			double fRotY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 ));
1818 			double fRotZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 ));
1819 			::com::sun::star::drawing::Direction3D aExtrusionDirection( fRotX, fRotY, fRotZ );
1820 			const rtl::OUString	sExtrusionDirection( RTL_CONSTASCII_USTRINGPARAM ( "Orientation" ) );
1821 			aProp.Name = sExtrusionDirection;
1822 			aProp.Value <<= aExtrusionDirection;
1823 			aExtrusionPropVec.push_back( aProp );
1824 		}
1825 		// "OrientationAngle" in Grad
1826 		if ( IsProperty( DFF_Prop_c3DRotationAngle ) )
1827 		{
1828 			const rtl::OUString	sExtrusionOrientationAngle( RTL_CONSTASCII_USTRINGPARAM ( "OrientationAngle" ) );
1829 			double fOrientationAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAngle )) / 65536.0;
1830 			aProp.Name = sExtrusionOrientationAngle;
1831 			aProp.Value <<= fOrientationAngle;
1832 			aExtrusionPropVec.push_back( aProp );
1833 		}
1834 */
1835 
1836 		// "Metal"
1837 		const rtl::OUString	sExtrusionMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
1838 		sal_Bool bExtrusionMetal = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 4 ) != 0;
1839 		aProp.Name = sExtrusionMetal;
1840 		aProp.Value <<= bExtrusionMetal;
1841 		aExtrusionPropVec.push_back( aProp );
1842 //		if ( IsProperty( DFF_Prop_c3DExtrudePlane ) )
1843 //		{
1844 //		UPS
1845 //		}
1846 		// "ShadeMode"
1847 		if ( IsProperty( DFF_Prop_c3DRenderMode ) )
1848 		{
1849 			const rtl::OUString	sExtrusionShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
1850 			sal_uInt32 nExtrusionRenderMode = GetPropertyValue( DFF_Prop_c3DRenderMode );
1851 			com::sun::star::drawing::ShadeMode eExtrusionShadeMode( com::sun::star::drawing::ShadeMode_FLAT );
1852 			if ( nExtrusionRenderMode == mso_Wireframe )
1853 				eExtrusionShadeMode = com::sun::star::drawing::ShadeMode_DRAFT;
1854 
1855 			aProp.Name = sExtrusionShadeMode;
1856 			aProp.Value <<= eExtrusionShadeMode;
1857 			aExtrusionPropVec.push_back( aProp );
1858 		}
1859 		// "RotateAngle" in Grad
1860 		if ( IsProperty( DFF_Prop_c3DXRotationAngle ) || IsProperty( DFF_Prop_c3DYRotationAngle ) )
1861 		{
1862 			const rtl::OUString	sExtrusionAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) );
1863 			double fAngleX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXRotationAngle, 0 )) / 65536.0;
1864 			double fAngleY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYRotationAngle, 0 )) / 65536.0;
1865 			EnhancedCustomShapeParameterPair aRotateAnglePair;
1866 			aRotateAnglePair.First.Value <<= fAngleX;
1867 			aRotateAnglePair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
1868 			aRotateAnglePair.Second.Value <<= fAngleY;
1869 			aRotateAnglePair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
1870 			aProp.Name = sExtrusionAngle;
1871 			aProp.Value <<= aRotateAnglePair;
1872 			aExtrusionPropVec.push_back( aProp );
1873 		}
1874 
1875 		// "AutoRotationCenter"
1876 		if ( ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 8 ) == 0 )
1877 		{
1878 			// "RotationCenter"
1879 			if ( IsProperty( DFF_Prop_c3DRotationCenterX ) || IsProperty( DFF_Prop_c3DRotationCenterY ) || IsProperty( DFF_Prop_c3DRotationCenterZ ) )
1880 			{
1881 				::com::sun::star::drawing::Direction3D aRotationCenter(
1882 					(double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 )) / 360.0,
1883 					(double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 )) / 360.0,
1884 					(double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterZ, 0 )) / 360.0 );
1885 
1886 				const rtl::OUString	sExtrusionRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) );
1887 				aProp.Name = sExtrusionRotationCenter;
1888 				aProp.Value <<= aRotationCenter;
1889 				aExtrusionPropVec.push_back( aProp );
1890 			}
1891 		}
1892 		// "Shininess"
1893 		if ( IsProperty( DFF_Prop_c3DShininess ) )
1894 		{
1895 			const rtl::OUString	sExtrusionShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) );
1896 			double fShininess = (sal_Int32)GetPropertyValue( DFF_Prop_c3DShininess );
1897 			fShininess /= 655.36;
1898 			aProp.Name = sExtrusionShininess;
1899 			aProp.Value <<= fShininess;
1900 			aExtrusionPropVec.push_back( aProp );
1901 		}
1902 		// "Skew"
1903 		if ( IsProperty( DFF_Prop_c3DSkewAmount ) || IsProperty( DFF_Prop_c3DSkewAngle ) )
1904 		{
1905 			const rtl::OUString	sExtrusionSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
1906 			double fSkewAmount = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAmount, 50 );
1907 			double fSkewAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAngle, sal::static_int_cast< sal_uInt32 >(-135 * 65536) )) / 65536.0;
1908 
1909 			EnhancedCustomShapeParameterPair aSkewPair;
1910 			aSkewPair.First.Value <<= fSkewAmount;
1911 			aSkewPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
1912 			aSkewPair.Second.Value <<= fSkewAngle;
1913 			aSkewPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
1914 			aProp.Name = sExtrusionSkew;
1915 			aProp.Value <<= aSkewPair;
1916 			aExtrusionPropVec.push_back( aProp );
1917 		}
1918 		// "Specularity"
1919 		if ( IsProperty( DFF_Prop_c3DSpecularAmt ) )
1920 		{
1921 			const rtl::OUString	sExtrusionSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
1922 			double fSpecularity = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSpecularAmt );
1923 			fSpecularity /= 1333;
1924 			aProp.Name = sExtrusionSpecularity;
1925 			aProp.Value <<= fSpecularity;
1926 			aExtrusionPropVec.push_back( aProp );
1927 		}
1928 		// "ProjectionMode"
1929 		const rtl::OUString	sExtrusionProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
1930 		ProjectionMode eProjectionMode = GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 4 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE;
1931 		aProp.Name = sExtrusionProjectionMode;
1932 		aProp.Value <<= eProjectionMode;
1933 		aExtrusionPropVec.push_back( aProp );
1934 
1935 		// "ViewPoint" in 1/100mm
1936 		if ( IsProperty( DFF_Prop_c3DXViewpoint ) || IsProperty( DFF_Prop_c3DYViewpoint ) || IsProperty( DFF_Prop_c3DZViewpoint ) )
1937 		{
1938 			double fViewX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXViewpoint, 1250000 )) / 360.0;
1939 			double fViewY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYViewpoint, (sal_uInt32)-1250000 ))/ 360.0;
1940 			double fViewZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DZViewpoint, 9000000 )) / 360.0;
1941 			::com::sun::star::drawing::Position3D aExtrusionViewPoint( fViewX, fViewY, fViewZ );
1942 			const rtl::OUString	sExtrusionViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
1943 			aProp.Name = sExtrusionViewPoint;
1944 			aProp.Value <<= aExtrusionViewPoint;
1945 			aExtrusionPropVec.push_back( aProp );
1946 		}
1947 		// "Origin"
1948 		if ( IsProperty( DFF_Prop_c3DOriginX ) || IsProperty( DFF_Prop_c3DOriginY ) )
1949 		{
1950 			const rtl::OUString	sExtrusionOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
1951 			double fOriginX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginX, 32768 ));
1952 			double fOriginY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginY, (sal_uInt32)-32768 ));
1953 			fOriginX /= 65536;
1954 			fOriginY /= 65536;
1955 			EnhancedCustomShapeParameterPair aOriginPair;
1956 			aOriginPair.First.Value <<= fOriginX;
1957 			aOriginPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
1958 			aOriginPair.Second.Value <<= fOriginY;
1959 			aOriginPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
1960 			aProp.Name = sExtrusionOrigin;
1961 			aProp.Value <<= aOriginPair;
1962 			aExtrusionPropVec.push_back( aProp );
1963 		}
1964 		// "ExtrusionColor"
1965 		const rtl::OUString	sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
1966 		sal_Bool bExtrusionColor = IsProperty( DFF_Prop_c3DExtrusionColor );	// ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 2 ) != 0;
1967 		aProp.Name = sExtrusionColor;
1968 		aProp.Value <<= bExtrusionColor;
1969 		aExtrusionPropVec.push_back( aProp );
1970 		if ( IsProperty( DFF_Prop_c3DExtrusionColor ) )
1971 			rSet.Put( XSecondaryFillColorItem( String(), rManager.MSO_CLR_ToColor(
1972 				GetPropertyValue( DFF_Prop_c3DExtrusionColor ), DFF_Prop_c3DExtrusionColor ) ) );
1973 		// pushing the whole Extrusion element
1974 		const rtl::OUString	sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
1975 		PropSeq aExtrusionPropSeq( aExtrusionPropVec.size() );
1976 		aIter = aExtrusionPropVec.begin();
1977 		aEnd = aExtrusionPropVec.end();
1978 		beans::PropertyValue* pExtrusionValues = aExtrusionPropSeq.getArray();
1979 		while ( aIter != aEnd )
1980 			*pExtrusionValues++ = *aIter++;
1981 		aProp.Name = sExtrusion;
1982 		aProp.Value <<= aExtrusionPropSeq;
1983 		aPropVec.push_back( aProp );
1984 	}
1985 
1986 	/////////////////////////////////////////
1987 	// "Equations" PropertySequence element //
1988 	/////////////////////////////////////////
1989 	if ( IsProperty( DFF_Prop_pFormulas ) )
1990 	{
1991 		sal_uInt16 i;
1992 		sal_uInt16 nNumElem = 0;
1993 		sal_uInt16 nNumElemMem = 0;
1994 		sal_uInt16 nElemSize = 8;
1995 
1996 		if ( SeekToContent( DFF_Prop_pFormulas, rIn ) )
1997 			rIn >> nNumElem >> nNumElemMem >> nElemSize;
1998 
1999 		sal_Int16 nP1, nP2, nP3;
2000 		sal_uInt16 nFlags;
2001 
2002 		uno::Sequence< rtl::OUString > aEquations( nNumElem );
2003 		for ( i = 0; i < nNumElem; i++ )
2004 		{
2005 			rIn >> nFlags >> nP1 >> nP2 >> nP3;
2006 			aEquations[ i ] = EnhancedCustomShape2d::GetEquation( nFlags, nP1, nP2, nP3 );
2007 		}
2008 		// pushing the whole Equations element
2009 		const rtl::OUString	sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
2010 		aProp.Name = sEquations;
2011 		aProp.Value <<= aEquations;
2012 		aPropVec.push_back( aProp );
2013 	}
2014 
2015 	////////////////////////////////////////
2016 	// "Handles" PropertySequence element //
2017 	////////////////////////////////////////
2018 	if ( IsProperty( DFF_Prop_Handles ) )
2019 	{
2020 		sal_uInt16 i;
2021 		sal_uInt16 nNumElem = 0;
2022 		sal_uInt16 nNumElemMem = 0;
2023 		sal_uInt16 nElemSize = 36;
2024 
2025 		if ( SeekToContent( DFF_Prop_Handles, rIn ) )
2026 			rIn >> nNumElem >> nNumElemMem >> nElemSize;
2027 		if ( nElemSize == 36 )
2028 		{
2029 			uno::Sequence< beans::PropertyValues > aHandles( nNumElem );
2030 			for ( i = 0; i < nNumElem; i++ )
2031 			{
2032 				PropVec aHandlePropVec;
2033 				sal_uInt32	nFlags;
2034 				sal_Int32	nPositionX, nPositionY, nCenterX, nCenterY, nRangeXMin, nRangeXMax, nRangeYMin, nRangeYMax;
2035 				rIn >> nFlags
2036 					>> nPositionX
2037 					>> nPositionY
2038 					>> nCenterX
2039 					>> nCenterY
2040 					>> nRangeXMin
2041 					>> nRangeXMax
2042 					>> nRangeYMin
2043 					>> nRangeYMax;
2044 
2045 				if ( nPositionX == 2 )	// replacing center position with absolute value
2046 					nPositionX = nCoordWidth / 2;
2047 				if ( nPositionY == 2 )
2048 					nPositionY = nCoordHeight / 2;
2049 				EnhancedCustomShapeParameterPair aPosition;
2050 				EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First,  nPositionX, sal_True, sal_True  );
2051 				EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, nPositionY, sal_True, sal_False );
2052 				const rtl::OUString	sHandlePosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
2053 				aProp.Name = sHandlePosition;
2054 				aProp.Value <<= aPosition;
2055 				aHandlePropVec.push_back( aProp );
2056 
2057 				if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
2058 				{
2059 					sal_Bool bMirroredX = sal_True;
2060 					const rtl::OUString	sHandleMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
2061 					aProp.Name = sHandleMirroredX;
2062 					aProp.Value <<= bMirroredX;
2063 					aHandlePropVec.push_back( aProp );
2064 				}
2065 				if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
2066 				{
2067 					sal_Bool bMirroredY = sal_True;
2068 					const rtl::OUString	sHandleMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
2069 					aProp.Name = sHandleMirroredY;
2070 					aProp.Value <<= bMirroredY;
2071 					aHandlePropVec.push_back( aProp );
2072 				}
2073 				if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
2074 				{
2075 					sal_Bool bSwitched = sal_True;
2076 					const rtl::OUString	sHandleSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
2077 					aProp.Name = sHandleSwitched;
2078 					aProp.Value <<= bSwitched;
2079 					aHandlePropVec.push_back( aProp );
2080 				}
2081 				if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
2082 				{
2083 					if ( nCenterX == 2 )
2084 						nCenterX = nCoordWidth / 2;
2085 					if ( nCenterY == 2 )
2086 						nCenterY = nCoordHeight / 2;
2087 					if ( ( nPositionY >= 0x256 ) || ( nPositionY <= 0x107 ) )	// position y
2088 						nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
2089 					EnhancedCustomShapeParameterPair aPolar;
2090 					EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.First,  nCenterX, ( nFlags & 0x800  ) != 0, sal_True  );
2091 					EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
2092 					const rtl::OUString	sHandlePolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
2093 					aProp.Name = sHandlePolar;
2094 					aProp.Value <<= aPolar;
2095 					aHandlePropVec.push_back( aProp );
2096 				}
2097 				if ( nFlags & MSDFF_HANDLE_FLAGS_MAP )
2098 				{
2099 					if ( nCenterX == 2 )
2100 						nCenterX = nCoordWidth / 2;
2101 					if ( nCenterY == 2 )
2102 						nCenterY = nCoordHeight / 2;
2103 					EnhancedCustomShapeParameterPair aMap;
2104 					EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.First,  nCenterX, ( nFlags & 0x800  ) != 0, sal_True  );
2105 					EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
2106 					const rtl::OUString	sHandleMap( RTL_CONSTASCII_USTRINGPARAM ( "Map" ) );
2107 					aProp.Name = sHandleMap;
2108 					aProp.Value <<= aMap;
2109 					aHandlePropVec.push_back( aProp );
2110 				}
2111 				if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
2112 				{
2113 					if ( (sal_uInt32)nRangeXMin != 0x80000000 )
2114 					{
2115 						if ( nRangeXMin == 2 )
2116 							nRangeXMin = nCoordWidth / 2;
2117 						EnhancedCustomShapeParameter aRangeXMinimum;
2118 						EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum,  nRangeXMin,
2119 							( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True  );
2120 						const rtl::OUString	sHandleRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
2121 						aProp.Name = sHandleRangeXMinimum;
2122 						aProp.Value <<= aRangeXMinimum;
2123 						aHandlePropVec.push_back( aProp );
2124 					}
2125 					if ( (sal_uInt32)nRangeXMax != 0x7fffffff )
2126 					{
2127 						if ( nRangeXMax == 2 )
2128 							nRangeXMax = nCoordWidth / 2;
2129 						EnhancedCustomShapeParameter aRangeXMaximum;
2130 						EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, nRangeXMax,
2131 							( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
2132 						const rtl::OUString	sHandleRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
2133 						aProp.Name = sHandleRangeXMaximum;
2134 						aProp.Value <<= aRangeXMaximum;
2135 						aHandlePropVec.push_back( aProp );
2136 					}
2137 					if ( (sal_uInt32)nRangeYMin != 0x80000000 )
2138 					{
2139 						if ( nRangeYMin == 2 )
2140 							nRangeYMin = nCoordHeight / 2;
2141 						EnhancedCustomShapeParameter aRangeYMinimum;
2142 						EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, nRangeYMin,
2143 							( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
2144 						const rtl::OUString	sHandleRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
2145 						aProp.Name = sHandleRangeYMinimum;
2146 						aProp.Value <<= aRangeYMinimum;
2147 						aHandlePropVec.push_back( aProp );
2148 					}
2149 					if ( (sal_uInt32)nRangeYMax != 0x7fffffff )
2150 					{
2151 						if ( nRangeYMax == 2 )
2152 							nRangeYMax = nCoordHeight / 2;
2153 						EnhancedCustomShapeParameter aRangeYMaximum;
2154 						EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, nRangeYMax,
2155 							( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
2156 						const rtl::OUString	sHandleRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
2157 						aProp.Name = sHandleRangeYMaximum;
2158 						aProp.Value <<= aRangeYMaximum;
2159 						aHandlePropVec.push_back( aProp );
2160 					}
2161 				}
2162 				if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
2163 				{
2164 					if ( (sal_uInt32)nRangeXMin != 0x7fffffff )
2165 					{
2166 						if ( nRangeXMin == 2 )
2167 							nRangeXMin = nCoordWidth / 2;
2168 						EnhancedCustomShapeParameter aRadiusRangeMinimum;
2169 						EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, nRangeXMin,
2170 							( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True  );
2171 						const rtl::OUString	sHandleRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
2172 						aProp.Name = sHandleRadiusRangeMinimum;
2173 						aProp.Value <<= aRadiusRangeMinimum;
2174 						aHandlePropVec.push_back( aProp );
2175 					}
2176 					if ( (sal_uInt32)nRangeXMax != 0x80000000 )
2177 					{
2178 						if ( nRangeXMax == 2 )
2179 							nRangeXMax = nCoordWidth / 2;
2180 						EnhancedCustomShapeParameter aRadiusRangeMaximum;
2181 						EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, nRangeXMax,
2182 							( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
2183 						const rtl::OUString	sHandleRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
2184 						aProp.Name = sHandleRadiusRangeMaximum;
2185 						aProp.Value <<= aRadiusRangeMaximum;
2186 						aHandlePropVec.push_back( aProp );
2187 					}
2188 				}
2189 				if ( aHandlePropVec.size() )
2190 				{
2191 					PropSeq aHandlePropSeq( aHandlePropVec.size() );
2192 					aIter = aHandlePropVec.begin();
2193 					aEnd = aHandlePropVec.end();
2194 					beans::PropertyValue* pHandleValues = aHandlePropSeq.getArray();
2195 					while ( aIter != aEnd )
2196 						*pHandleValues++ = *aIter++;
2197 					aHandles[ i ] = aHandlePropSeq;
2198 				}
2199 			}
2200 			// pushing the whole Handles element
2201 			const rtl::OUString	sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
2202 			aProp.Name = sHandles;
2203 			aProp.Value <<= aHandles;
2204 			aPropVec.push_back( aProp );
2205 		}
2206 	}
2207 	else
2208 	{
2209 		const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( rObjData.eShapeType );
2210 		if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
2211 		{
2212 			sal_Int32 i, nCnt = pDefCustomShape->nHandles;
2213 			const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
2214 			for ( i = 0; i < nCnt; i++, pData++ )
2215 			{
2216 				if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR )
2217 				{
2218 					if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) )
2219 						nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
2220 				}
2221 			}
2222 		}
2223 	}
2224 	/////////////////////////////////////
2225 	// "Path" PropertySequence element //
2226 	/////////////////////////////////////
2227 	{
2228 		PropVec aPathPropVec;
2229 
2230 		// "Path/ExtrusionAllowed"
2231 		if ( IsHardAttribute( DFF_Prop_f3DOK ) )
2232 		{
2233 			const rtl::OUString	sExtrusionAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ExtrusionAllowed" ) );
2234 			sal_Bool bExtrusionAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 16 ) != 0;
2235 			aProp.Name = sExtrusionAllowed;
2236 			aProp.Value <<= bExtrusionAllowed;
2237 			aPathPropVec.push_back( aProp );
2238 		}
2239 		// "Path/ConcentricGradientFillAllowed"
2240 		if ( IsHardAttribute( DFF_Prop_fFillShadeShapeOK ) )
2241 		{
2242 			const rtl::OUString	sConcentricGradientFillAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ConcentricGradientFillAllowed" ) );
2243 			sal_Bool bConcentricGradientFillAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 2 ) != 0;
2244 			aProp.Name = sConcentricGradientFillAllowed;
2245 			aProp.Value <<= bConcentricGradientFillAllowed;
2246 			aPathPropVec.push_back( aProp );
2247 		}
2248 		// "Path/TextPathAllowed"
2249 		if ( IsHardAttribute( DFF_Prop_fGtextOK ) || ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) )
2250 		{
2251 			const rtl::OUString	sTextPathAllowed( RTL_CONSTASCII_USTRINGPARAM ( "TextPathAllowed" ) );
2252 			sal_Bool bTextPathAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 4 ) != 0;
2253 			aProp.Name = sTextPathAllowed;
2254 			aProp.Value <<= bTextPathAllowed;
2255 			aPathPropVec.push_back( aProp );
2256 		}
2257 		// Path/Coordinates
2258 		if ( IsProperty( DFF_Prop_pVertices ) )
2259 		{
2260 			com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
2261 
2262 			sal_uInt16 i;
2263 			sal_uInt16 nNumElemVert = 0;
2264 			sal_uInt16 nNumElemMemVert = 0;
2265 			sal_uInt16 nElemSizeVert = 8;
2266 
2267 			if ( SeekToContent( DFF_Prop_pVertices, rIn ) )
2268 				rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
2269 			if ( nNumElemVert )
2270 			{
2271 				sal_Int32 nX, nY;
2272 				sal_Int16 nTmpA, nTmpB;
2273 				aCoordinates.realloc( nNumElemVert );
2274 				for ( i = 0; i < nNumElemVert; i++ )
2275 				{
2276 					if ( nElemSizeVert == 8 )
2277 					{
2278 						rIn >> nX
2279 							>> nY;
2280 					}
2281 					else
2282 					{
2283 						rIn >> nTmpA
2284 							>> nTmpB;
2285 
2286 						nX = nTmpA;
2287 						nY = nTmpB;
2288 					}
2289 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].First, nX );
2290 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].Second, nY );
2291 				}
2292 			}
2293 			const rtl::OUString	sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
2294 			aProp.Name = sCoordinates;
2295 			aProp.Value <<= aCoordinates;
2296 			aPathPropVec.push_back( aProp );
2297 		}
2298 		// Path/Segments
2299 		if ( IsProperty( DFF_Prop_pSegmentInfo ) )
2300 		{
2301 			com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
2302 
2303 			sal_uInt16 i, nTmp;
2304 			sal_uInt16 nNumElemSeg = 0;
2305 			sal_uInt16 nNumElemMemSeg = 0;
2306 			sal_uInt16 nElemSizeSeg = 2;
2307 
2308 			if ( SeekToContent( DFF_Prop_pSegmentInfo, rIn ) )
2309 				rIn >> nNumElemSeg >> nNumElemMemSeg >> nElemSizeSeg;
2310 			if ( nNumElemSeg )
2311 			{
2312 				sal_Int16 nCommand;
2313 				sal_Int16 nCnt;
2314 				aSegments.realloc( nNumElemSeg );
2315 				for ( i = 0; i < nNumElemSeg; i++ )
2316 				{
2317 					rIn >> nTmp;
2318 					nCommand = EnhancedCustomShapeSegmentCommand::UNKNOWN;
2319 					nCnt = (sal_Int16)( nTmp & 0x1fff );//Last 13 bits for segment points number
2320 					switch( nTmp >> 13 )//First 3 bits for command type
2321 					{
2322 						case 0x0: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break;
2323 						case 0x1: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break;
2324 						case 0x2: nCommand = EnhancedCustomShapeSegmentCommand::MOVETO; if ( !nCnt ) nCnt = 1; break;
2325 						case 0x3: nCommand = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; nCnt = 0; break;
2326 						case 0x4: nCommand = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; nCnt = 0; break;
2327 						case 0x5:
2328 						case 0x6:
2329 						{
2330 							switch ( ( nTmp >> 8 ) & 0x1f )//5 bits next to command type is for path escape type
2331 							{
2332 								case 0x0:
2333 								{
2334 									//It is msopathEscapeExtension which is transformed into LINETO.
2335 									//If issue happens, I think this part can be comment so that it will be taken as unknow command.
2336 									//When export, origin data will be export without any change.
2337 									nCommand = EnhancedCustomShapeSegmentCommand::LINETO;
2338 									if ( !nCnt )
2339 										nCnt = 1;
2340 								}
2341 								break;
2342 								case 0x1:
2343 								{
2344 									nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
2345 									nCnt = ( nTmp & 0xff ) / 3;
2346 								}
2347 								break;
2348 								case 0x2:
2349 								{
2350 									nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
2351 									nCnt = ( nTmp & 0xff ) / 3;
2352 								}
2353 								break;
2354 								case 0x3:
2355 								{
2356 									nCommand = EnhancedCustomShapeSegmentCommand::ARCTO;
2357 									nCnt = ( nTmp & 0xff ) >> 2;
2358 								};
2359 								break;
2360 								case 0x4:
2361 								{
2362 									nCommand = EnhancedCustomShapeSegmentCommand::ARC;
2363 									nCnt = ( nTmp & 0xff ) >> 2;
2364 								}
2365 								break;
2366 								case 0x5:
2367 								{
2368 									nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
2369 									nCnt = ( nTmp & 0xff ) >> 2;
2370 								}
2371 								break;
2372 								case 0x6:
2373 								{
2374 									nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
2375 									nCnt = ( nTmp & 0xff ) >> 2;
2376 								}
2377 								break;
2378 								case 0x7:
2379 								{
2380 									nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
2381 									nCnt = nTmp & 0xff;
2382 								}
2383 								break;
2384 								case 0x8:
2385 								{
2386 									nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
2387 									nCnt = nTmp & 0xff;
2388 								}
2389 								break;
2390 								case 0xa: nCommand = EnhancedCustomShapeSegmentCommand::NOFILL; nCnt = 0; break;
2391 								case 0xb: nCommand = EnhancedCustomShapeSegmentCommand::NOSTROKE; nCnt = 0; break;
2392 							}
2393 						}
2394 						break;
2395 					}
2396 					// if the command is unknown, we will store all the data in nCnt, so it will be possible to export without loss
2397 					if ( nCommand == EnhancedCustomShapeSegmentCommand::UNKNOWN )
2398 						nCnt = (sal_Int16)nTmp;
2399 					aSegments[ i ].Command = nCommand;
2400 					aSegments[ i ].Count = nCnt;
2401 				}
2402 			}
2403 			const rtl::OUString	sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
2404 			aProp.Name = sSegments;
2405 			aProp.Value <<= aSegments;
2406 			aPathPropVec.push_back( aProp );
2407 		}
2408 		// Path/StretchX
2409 		if ( IsProperty( DFF_Prop_stretchPointX ) )
2410 		{
2411 			const rtl::OUString	sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
2412 			sal_Int32 nStretchX = GetPropertyValue( DFF_Prop_stretchPointX, 0 );
2413 			aProp.Name = sStretchX;
2414 			aProp.Value <<= nStretchX;
2415 			aPathPropVec.push_back( aProp );
2416 		}
2417 		// Path/StretchX
2418 		if ( IsProperty( DFF_Prop_stretchPointY ) )
2419 		{
2420 			const rtl::OUString	sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
2421 			sal_Int32 nStretchY = GetPropertyValue( DFF_Prop_stretchPointY, 0 );
2422 			aProp.Name = sStretchY;
2423 			aProp.Value <<= nStretchY;
2424 			aPathPropVec.push_back( aProp );
2425 		}
2426 		// Path/TextFrames
2427 		if ( IsProperty( DFF_Prop_textRectangles ) )
2428 		{
2429 			sal_uInt16 i;
2430 			sal_uInt16 nNumElem = 0;
2431 			sal_uInt16 nNumElemMem = 0;
2432 			sal_uInt16 nElemSize = 16;
2433 
2434 			if ( SeekToContent( DFF_Prop_textRectangles, rIn ) )
2435 				rIn >> nNumElem >> nNumElemMem >> nElemSize;
2436 			if ( nElemSize == 16 )
2437 			{
2438 				sal_Int32 nLeft, nTop, nRight, nBottom;
2439 				com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem );
2440 				for ( i = 0; i < nNumElem; i++ )
2441 				{
2442 					rIn >> nLeft
2443 						>> nTop
2444 						>> nRight
2445 						>> nBottom;
2446 
2447 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.First,	 nLeft );
2448 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.Second, nTop  );
2449 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.First,	 nRight );
2450 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.Second, nBottom);
2451 				}
2452 				const rtl::OUString	sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
2453 				aProp.Name = sTextFrames;
2454 				aProp.Value <<= aTextFrames;
2455 				aPathPropVec.push_back( aProp );
2456 			}
2457 		}
2458 		//Path/GluePoints
2459 		if ( IsProperty( DFF_Prop_connectorPoints ) )
2460 		{
2461 			com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
2462 
2463 			sal_uInt16 i;
2464 			sal_uInt16 nNumElemVert = 0;
2465 			sal_uInt16 nNumElemMemVert = 0;
2466 			sal_uInt16 nElemSizeVert = 8;
2467 
2468 			if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) )
2469 				rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
2470 
2471 			sal_Int32 nX, nY;
2472 			sal_Int16 nTmpA, nTmpB;
2473 			aGluePoints.realloc( nNumElemVert );
2474 			for ( i = 0; i < nNumElemVert; i++ )
2475 			{
2476 				if ( nElemSizeVert == 8 )
2477 				{
2478 					rIn >> nX
2479 						>> nY;
2480 				}
2481 				else
2482 				{
2483 					rIn >> nTmpA
2484 						>> nTmpB;
2485 
2486 					nX = nTmpA;
2487 					nY = nTmpB;
2488 				}
2489 				EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First,  nX );
2490 				EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY );
2491 			}
2492 			const rtl::OUString	sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
2493 			aProp.Name = sGluePoints;
2494 			aProp.Value <<= aGluePoints;
2495 			aPathPropVec.push_back( aProp );
2496 		}
2497 		if ( IsProperty( DFF_Prop_connectorType ) )
2498 		{
2499 			sal_Int16 nGluePointType = (sal_uInt16)GetPropertyValue( DFF_Prop_connectorType );
2500 			const rtl::OUString	sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
2501 			aProp.Name = sGluePointType;
2502 			aProp.Value <<= nGluePointType;
2503 			aPathPropVec.push_back( aProp );
2504 		}
2505 		// pushing the whole Path element
2506 		if ( aPathPropVec.size() )
2507 		{
2508 			const rtl::OUString	sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
2509 			PropSeq aPathPropSeq( aPathPropVec.size() );
2510 			aIter = aPathPropVec.begin();
2511 			aEnd = aPathPropVec.end();
2512 			beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
2513 			while ( aIter != aEnd )
2514 				*pPathValues++ = *aIter++;
2515 			aProp.Name = sPath;
2516 			aProp.Value <<= aPathPropSeq;
2517 			aPropVec.push_back( aProp );
2518 		}
2519 	}
2520 	/////////////////////////////////////////
2521 	// "TextPath" PropertySequence element //
2522 	/////////////////////////////////////////
2523 	sal_Bool bTextPathOn = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x4000 ) != 0;
2524 	if ( bTextPathOn )
2525 	{
2526 		PropVec aTextPathPropVec;
2527 
2528 		// TextPath
2529 		const rtl::OUString	sTextPathOn( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
2530 		aProp.Name = sTextPathOn;
2531 		aProp.Value <<= bTextPathOn;
2532 		aTextPathPropVec.push_back( aProp );
2533 
2534 		// TextPathMode
2535 		const rtl::OUString	sTextPathMode( RTL_CONSTASCII_USTRINGPARAM ( "TextPathMode" ) );
2536 		sal_Bool bTextPathFitPath = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x100 ) != 0;
2537 
2538 		sal_Bool bTextPathFitShape;
2539 		if ( IsHardAttribute( DFF_Prop_gtextFStretch ) )
2540 			bTextPathFitShape = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x400 ) != 0;
2541 		else
2542 		{
2543 			bTextPathFitShape = true;
2544 			switch( rObjData.eShapeType )
2545 			{
2546 				case mso_sptTextArchUpCurve :
2547 				case mso_sptTextArchDownCurve :
2548 				case mso_sptTextCircleCurve :
2549 				case mso_sptTextButtonCurve :
2550 					bTextPathFitShape = false;
2551 				default : break;
2552 			}
2553 		}
2554 		EnhancedCustomShapeTextPathMode eTextPathMode( EnhancedCustomShapeTextPathMode_NORMAL );
2555 		if ( bTextPathFitShape )
2556 			eTextPathMode = EnhancedCustomShapeTextPathMode_SHAPE;
2557 		else if ( bTextPathFitPath )
2558 			eTextPathMode = EnhancedCustomShapeTextPathMode_PATH;
2559 		aProp.Name = sTextPathMode;
2560 		aProp.Value <<= eTextPathMode;
2561 		aTextPathPropVec.push_back( aProp );
2562 
2563 		// ScaleX
2564 		const rtl::OUString	sTextPathScaleX( RTL_CONSTASCII_USTRINGPARAM ( "ScaleX" ) );
2565 		sal_Bool bTextPathScaleX = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x40 ) != 0;
2566 		aProp.Name = sTextPathScaleX;
2567 		aProp.Value <<= bTextPathScaleX;
2568 		aTextPathPropVec.push_back( aProp );
2569 		// SameLetterHeights
2570 		const rtl::OUString sSameLetterHeight( RTL_CONSTASCII_USTRINGPARAM ( "SameLetterHeights" ) );
2571 		sal_Bool bSameLetterHeight = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x80 ) != 0;
2572 		aProp.Name = sSameLetterHeight;
2573 		aProp.Value <<= bSameLetterHeight;
2574 		aTextPathPropVec.push_back( aProp );
2575 
2576 		// pushing the whole TextPath element
2577 		const rtl::OUString	sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
2578 		PropSeq aTextPathPropSeq( aTextPathPropVec.size() );
2579 		aIter = aTextPathPropVec.begin();
2580 		aEnd = aTextPathPropVec.end();
2581 		beans::PropertyValue* pTextPathValues = aTextPathPropSeq.getArray();
2582 		while ( aIter != aEnd )
2583 			*pTextPathValues++ = *aIter++;
2584 		aProp.Name = sTextPath;
2585 		aProp.Value <<= aTextPathPropSeq;
2586 		aPropVec.push_back( aProp );
2587 	}
2588 	////////////////////////
2589 	// "AdjustmentValues" // The AdjustmentValues are imported at last, because depending to the type of the
2590 	//////////////////////// handle (POLAR) we will convert the adjustment value from a fixed float to double
2591 
2592 	// checking the last used adjustment handle, so we can determine how many handles are to allocate
2593 	sal_Int32 i = DFF_Prop_adjust10Value;
2594 	while ( ( i >= DFF_Prop_adjustValue ) && !IsProperty( i ) )
2595 		i--;
2596 	sal_Int32 nAdjustmentValues = ( i - DFF_Prop_adjustValue ) + 1;
2597 	if ( nAdjustmentValues )
2598 	{
2599 		uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq( nAdjustmentValues );
2600 		while( --nAdjustmentValues >= 0 )
2601 		{
2602 			sal_Int32 nValue = 0;
2603 			beans::PropertyState ePropertyState = beans::PropertyState_DEFAULT_VALUE;
2604 			if ( IsProperty( i ) )
2605 			{
2606 				nValue = GetPropertyValue( i );
2607 				ePropertyState = beans::PropertyState_DIRECT_VALUE;
2608 			}
2609 			if ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << ( i - DFF_Prop_adjustValue ) ) )
2610 			{
2611 				double fValue = nValue;
2612 				fValue /= 65536;
2613 				aAdjustmentSeq[ nAdjustmentValues ].Value <<= fValue;
2614 			}
2615 			else
2616 				aAdjustmentSeq[ nAdjustmentValues ].Value <<= nValue;
2617 			aAdjustmentSeq[ nAdjustmentValues ].State = ePropertyState;
2618 			i--;
2619 		}
2620 		const rtl::OUString	sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
2621 		aProp.Name = sAdjustmentValues;
2622 		aProp.Value <<= aAdjustmentSeq;
2623 		aPropVec.push_back( aProp );
2624 	}
2625 
2626 	// creating the whole property set
2627 	PropSeq aSeq( aPropVec.size() );
2628 	beans::PropertyValue* pValues = aSeq.getArray();
2629 	aIter = aPropVec.begin();
2630 	aEnd = aPropVec.end();
2631 	while ( aIter != aEnd )
2632 		*pValues++ = *aIter++;
2633 	rSet.Put( SdrCustomShapeGeometryItem( aSeq ) );
2634 }
2635 
2636 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet ) const
2637 {
2638 	Rectangle aEmptyRect;
2639 	DffRecordHeader aHdTemp;
2640 	DffObjData aDffObjTemp( aHdTemp, aEmptyRect, 0 );
2641 	ApplyAttributes( rIn, rSet, aDffObjTemp );
2642 }
2643 
2644 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, DffObjData& rObjData ) const
2645 {
2646 	sal_Bool bHasShadow = sal_False;
2647 	if ( IsProperty( DFF_Prop_gtextSize ) )
2648 		rSet.Put( SvxFontHeightItem( rManager.ScalePt( GetPropertyValue( DFF_Prop_gtextSize ) ), 100, EE_CHAR_FONTHEIGHT ) );
2649 	sal_uInt32 nFontAttributes = GetPropertyValue( DFF_Prop_gtextFStrikethrough );
2650 	if ( nFontAttributes & 0x20 )
2651         rSet.Put( SvxWeightItem( nFontAttributes & 0x20 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
2652 	if ( nFontAttributes & 0x10 )
2653         rSet.Put( SvxPostureItem( nFontAttributes & 0x10 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
2654 	if ( nFontAttributes & 0x08 )
2655         rSet.Put( SvxUnderlineItem( nFontAttributes & 0x08 ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
2656 	if ( nFontAttributes & 0x40 )
2657         rSet.Put( SvxShadowedItem( (nFontAttributes & 0x40) != 0, EE_CHAR_SHADOW ) );
2658 //	if ( nFontAttributes & 0x02 )
2659 //		rSet.Put( SvxCaseMapItem( nFontAttributes & 0x02 ? SVX_CASEMAP_KAPITAELCHEN : SVX_CASEMAP_NOT_MAPPED ) );
2660 	if ( nFontAttributes & 0x01 )
2661         rSet.Put( SvxCrossedOutItem( nFontAttributes & 0x01 ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) );
2662 	if ( IsProperty( DFF_Prop_fillColor ) )
2663 		rSet.Put( XFillColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor ) ) );
2664 	if ( IsProperty( DFF_Prop_shadowColor ) )
2665 		rSet.Put( SdrShadowColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_shadowColor ), DFF_Prop_shadowColor ) ) );
2666 	else
2667 	{
2668 		//The default value for this property is 0x00808080
2669 		rSet.Put( SdrShadowColorItem( String(),  rManager.MSO_CLR_ToColor( 0x00808080, DFF_Prop_shadowColor ) ) );
2670 	}
2671 	if ( IsProperty( DFF_Prop_shadowOpacity ) )
2672         rSet.Put( SdrShadowTransparenceItem( (sal_uInt16)( ( 0x10000 - GetPropertyValue( DFF_Prop_shadowOpacity ) ) / 655 ) ) );
2673 	if ( IsProperty( DFF_Prop_shadowOffsetX ) )
2674 	{
2675 		sal_Int32 nVal = static_cast< sal_Int32 >( GetPropertyValue( DFF_Prop_shadowOffsetX ) );
2676 		rManager.ScaleEmu( nVal );
2677 		rSet.Put( SdrShadowXDistItem( nVal ) );
2678 	}
2679 	if ( IsProperty( DFF_Prop_shadowOffsetY ) )
2680 	{
2681 		sal_Int32 nVal = static_cast< sal_Int32 >( GetPropertyValue( DFF_Prop_shadowOffsetY ) );
2682 		rManager.ScaleEmu( nVal );
2683 		rSet.Put( SdrShadowYDistItem( nVal ) );
2684 	}
2685 	if ( IsProperty( DFF_Prop_fshadowObscured ) )
2686 	{
2687         bHasShadow = ( GetPropertyValue( DFF_Prop_fshadowObscured ) & 2 ) != 0;
2688 		if ( bHasShadow )
2689         {
2690 			if ( !IsProperty( DFF_Prop_shadowOffsetX ) )
2691 				rSet.Put( SdrShadowXDistItem( 35 ) );
2692 			if ( !IsProperty( DFF_Prop_shadowOffsetY ) )
2693 				rSet.Put( SdrShadowYDistItem( 35 ) );
2694 		}
2695 	}
2696 	if ( IsProperty( DFF_Prop_shadowType ) )
2697 	{
2698 		MSO_ShadowType eShadowType = static_cast< MSO_ShadowType >( GetPropertyValue( DFF_Prop_shadowType ) );
2699 		if( eShadowType != mso_shadowOffset )
2700 		{
2701 			//0.12'' == 173 twip == 302 100mm
2702 			sal_uInt32 nDist = rManager.pSdrModel->GetScaleUnit() == MAP_TWIP ? 173: 302;
2703 			rSet.Put( SdrShadowXDistItem( nDist ) );
2704 			rSet.Put( SdrShadowYDistItem( nDist ) );
2705 		}
2706 	}
2707 	if ( bHasShadow )
2708 	{
2709 		// #160376# sj: activating shadow only if fill and or linestyle is used
2710 		// this is required because of the latest drawing layer core changes.
2711 		// Issue i104085 is related to this.
2712 		sal_uInt32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
2713 		if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( rObjData.eShapeType ))
2714 			nLineFlags &= ~0x08;
2715 		sal_uInt32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
2716 		if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType ))
2717 			nFillFlags &= ~0x10;
2718 		if ( nFillFlags & 0x10 )
2719 		{
2720 			MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
2721 			switch( eMSO_FillType )
2722 			{
2723 				case mso_fillSolid :
2724 				case mso_fillPattern :
2725 				case mso_fillTexture :
2726 				case mso_fillPicture :
2727 				case mso_fillShade :
2728 				case mso_fillShadeCenter :
2729 				case mso_fillShadeShape :
2730 				case mso_fillShadeScale :
2731 				case mso_fillShadeTitle :
2732 				break;
2733 				// case mso_fillBackground :
2734 				default:
2735 					nFillFlags &=~0x10;			// no fillstyle used
2736 				break;
2737 			}
2738 		}
2739 		if ( ( ( nLineFlags & 0x08 ) == 0 ) && ( ( nFillFlags & 0x10 ) == 0 ) && ( rObjData.eShapeType != mso_sptPictureFrame ))	// if there is no fillstyle and linestyle
2740 			bHasShadow = sal_False;												// we are turning shadow off.
2741 
2742 		if ( bHasShadow )
2743 			rSet.Put( SdrShadowItem( bHasShadow ) );
2744 	}
2745 	ApplyLineAttributes( rSet, rObjData.eShapeType ); // #i28269#
2746 	ApplyFillAttributes( rIn, rSet, rObjData );
2747 	if ( rObjData.eShapeType != mso_sptNil || IsProperty( DFF_Prop_pVertices ) )
2748 	{
2749 		ApplyCustomShapeGeometryAttributes( rIn, rSet, rObjData );
2750 		ApplyCustomShapeTextAttributes( rSet );
2751 		if ( rManager.GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_EXCEL )
2752 		{
2753 			if ( mnFix16Angle || ( rObjData.nSpFlags & SP_FFLIPV ) )
2754 				CheckAndCorrectExcelTextRotation( rIn, rSet, rObjData );
2755 		}
2756 	}
2757 }
2758 
2759 void DffPropertyReader::CheckAndCorrectExcelTextRotation( SvStream& rIn, SfxItemSet& rSet, DffObjData& rObjData ) const
2760 {
2761 	sal_Bool bRotateTextWithShape = rObjData.bRotateTextWithShape;
2762 	if ( rObjData.bOpt2 )		// sj: #158494# is the second property set available ? if then we have to check the xml data of
2763 	{							// the shape, because the textrotation of Excel 2003 and greater versions is stored there
2764 								// (upright property of the textbox)
2765 		if ( rManager.pSecPropSet->SeekToContent( DFF_Prop_metroBlob, rIn ) )
2766 		{
2767 			sal_uInt32 nLen = rManager.pSecPropSet->GetPropertyValue( DFF_Prop_metroBlob );
2768 			if ( nLen )
2769 			{
2770 				::com::sun::star::uno::Sequence< sal_Int8 > aXMLDataSeq( nLen );
2771 				rIn.Read( aXMLDataSeq.getArray(), nLen );
2772 				::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInputStream
2773 					( new ::comphelper::SequenceInputStream( aXMLDataSeq ) );
2774 				try
2775 				{
2776 					::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
2777 					if ( xFactory.is() )
2778 					{
2779 						::com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage
2780 							( ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(
2781 								OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xFactory, sal_True ) );
2782 						if ( xStorage.is() )
2783 						{
2784 							const rtl::OUString sDRS( RTL_CONSTASCII_USTRINGPARAM ( "drs" ) );
2785 							::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
2786 								xStorageDRS( xStorage->openStorageElement( sDRS, ::com::sun::star::embed::ElementModes::SEEKABLEREAD ) );
2787 							if ( xStorageDRS.is() )
2788 							{
2789 								const rtl::OUString sShapeXML( RTL_CONSTASCII_USTRINGPARAM ( "shapexml.xml" ) );
2790 								::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xShapeXMLStream( xStorageDRS->openStreamElement( sShapeXML, ::com::sun::star::embed::ElementModes::SEEKABLEREAD ) );
2791 								if ( xShapeXMLStream.is() )
2792 								{
2793 									::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xShapeXMLInputStream( xShapeXMLStream->getInputStream() );
2794 									if ( xShapeXMLInputStream.is() )
2795 									{
2796 										::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
2797 										sal_Int32 nBytesRead = xShapeXMLInputStream->readBytes( aSeq, 0x7fffffff );
2798 										if ( nBytesRead )
2799 										{	// for only one property I spare to use a XML parser at this point, this
2800 											// should be enhanced if needed
2801 
2802 											bRotateTextWithShape = sal_True;	// using the correct xml default
2803 											const char* pArry = reinterpret_cast< char* >( aSeq.getArray() );
2804 											const char* pUpright = "upright=";
2805 											const char* pEnd = pArry + nBytesRead;
2806 											const char* pPtr = pArry;
2807 											while( ( pPtr + 12 ) < pEnd )
2808 											{
2809 												if ( !memcmp( pUpright, pPtr, 8 ) )
2810 												{
2811 													bRotateTextWithShape = ( pPtr[ 9 ] != '1' ) && ( pPtr[ 9 ] != 't' );
2812 													break;
2813 												}
2814 												else
2815 													pPtr++;
2816 											}
2817 										}
2818 									}
2819 								}
2820 							}
2821 						}
2822 					}
2823 				}
2824 				catch( com::sun::star::uno::Exception& )
2825 				{
2826 				}
2827 			}
2828 		}
2829 	}
2830 	if ( !bRotateTextWithShape )
2831 	{
2832 		const com::sun::star::uno::Any* pAny, aAny;
2833 		SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)rSet.Get( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
2834 		const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
2835 		pAny = aGeometryItem.GetPropertyValueByName( sTextRotateAngle );
2836 		double fExtraTextRotateAngle = 0.0;
2837 		if ( pAny )
2838 			*pAny >>= fExtraTextRotateAngle;
2839 
2840 		if ( rManager.mnFix16Angle )
2841 			fExtraTextRotateAngle += mnFix16Angle / 100.0;
2842 		if ( rObjData.nSpFlags & SP_FFLIPV )
2843 			fExtraTextRotateAngle -= 180.0;
2844 
2845 		com::sun::star::beans::PropertyValue aTextRotateAngle;
2846 		aTextRotateAngle.Name = sTextRotateAngle;
2847 		aTextRotateAngle.Value <<= fExtraTextRotateAngle;
2848 		aGeometryItem.SetPropertyValue( aTextRotateAngle );
2849 		rSet.Put( aGeometryItem );
2850 	}
2851 }
2852 
2853 
2854 void DffPropertyReader::ImportGradientColor( SfxItemSet& aSet,MSO_FillType eMSO_FillType, double dTrans , double dBackTrans) const
2855 {
2856 	//MS Focus prop will impact the start and end color position. And AOO does not
2857 	//support this prop. So need some swap for the two color to keep fidelity with AOO and MS shape.
2858 	//So below var is defined.
2859 	sal_Int32 nChgColors = 0;
2860 	sal_Int32 nAngle = GetPropertyValue( DFF_Prop_fillAngle, 0 );
2861 	sal_Int32 nRotateAngle = 0;
2862 	if(nAngle >= 0)
2863 		nChgColors ^= 1;
2864 
2865 	//Translate a MS clockwise(+) or count clockwise angle(-) into a AOO count clock wise angle
2866 	nAngle=3600 - ( ( Fix16ToAngle(nAngle) + 5 ) / 10 );
2867 	//Make sure this angle belongs to 0~3600
2868 	while ( nAngle >= 3600 ) nAngle -= 3600;
2869 	while ( nAngle < 0 ) nAngle += 3600;
2870 
2871 	//Rotate angle
2872 	if ( mbRotateGranientFillWithAngle )
2873 	{
2874 		nRotateAngle = GetPropertyValue( DFF_Prop_Rotation, 0 );
2875 		if(nRotateAngle)//fixed point number
2876 			nRotateAngle = ( (sal_Int16)( nRotateAngle >> 16) * 100L ) + ( ( ( nRotateAngle & 0x0000ffff) * 100L ) >> 16 );
2877 		nRotateAngle = ( nRotateAngle + 5 ) / 10 ;//round up
2878 		//nAngle is a clockwise angle. If nRotateAngle is a clockwise angle, then gradient need be rotated a little less
2879 		//Or it need be rotated a little more
2880 		nAngle -=  nRotateAngle;
2881 	}
2882 	while ( nAngle >= 3600 ) nAngle -= 3600;
2883 	while ( nAngle < 0 ) nAngle += 3600;
2884 
2885 	XGradientStyle eGrad = XGRAD_LINEAR;
2886 
2887 	sal_Int32 nFocus = GetPropertyValue( DFF_Prop_fillFocus, 0 );
2888 	if ( !nFocus )
2889 		nChgColors ^= 1;
2890 	else if ( nFocus < 0 )//If it is a negative focus, the color will be swapped
2891 	{
2892 		nFocus = -nFocus;
2893 		nChgColors ^= 1;
2894 	}
2895 
2896 	if( nFocus > 40 && nFocus < 60 )
2897 	{
2898 		eGrad = XGRAD_AXIAL;//A axial gradient other than linear
2899 		nChgColors ^= 1;
2900 	}
2901 	//if the type is linear or axial, just save focus to nFocusX and nFocusY for export
2902 	//Core function does no need them. They serves for rect gradient(CenterXY).
2903 	sal_uInt16 nFocusX = (sal_uInt16)nFocus;
2904 	sal_uInt16 nFocusY = (sal_uInt16)nFocus;
2905 
2906 	switch( eMSO_FillType )
2907 	{
2908 	case mso_fillShadeShape :
2909 		{
2910 			eGrad = XGRAD_RECT;
2911 			nFocusY = nFocusX = 50;
2912 			nChgColors ^= 1;
2913 		}
2914 		break;
2915 	case mso_fillShadeCenter :
2916 		{
2917 			eGrad = XGRAD_RECT;
2918 			//A MS fillTo prop specifies the relative position of the left boundary
2919 			//of the center rectangle in a concentric shaded fill. Use 100 or 0 to keep fidelity
2920 			nFocusX=(GetPropertyValue( DFF_Prop_fillToRight, 0 )==0x10000) ? 100 : 0;
2921 			nFocusY=(GetPropertyValue( DFF_Prop_fillToBottom,0 )==0x10000) ? 100 : 0;
2922 			nChgColors ^= 1;
2923 		}
2924 		break;
2925 		default: break;
2926 	}
2927 
2928 	Color aCol1( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ) );
2929 	Color aCol2( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ) );
2930 	if ( nChgColors )
2931 	{
2932 		//Swap start and end color
2933 		Color aZwi( aCol1 );
2934 		aCol1 = aCol2;
2935 		aCol2 = aZwi;
2936 		//Swap two colors' transparency
2937 		double dTemp = dTrans;
2938 		dTrans = dBackTrans;
2939 		dBackTrans = dTemp;
2940 	}
2941 
2942 	//Construct gradient item
2943 	XGradient aGrad( aCol2, aCol1, eGrad, nAngle, nFocusX, nFocusY );
2944 	//Intensity has been merged into color. So here just set is as 100
2945 	aGrad.SetStartIntens( 100 );
2946 	aGrad.SetEndIntens( 100 );
2947 	aSet.Put( XFillGradientItem( String(), aGrad ) );
2948 	//Construct tranparency item. This item can coodinate with both solid and gradient.
2949 	if ( dTrans < 1.0 || dBackTrans < 1.0 )
2950 	{
2951 		sal_uInt8 nStartCol = (sal_uInt8)( (1 - dTrans )* 255 );
2952 		sal_uInt8 nEndCol = (sal_uInt8)( ( 1- dBackTrans ) * 255 );
2953 		aCol1 = Color(nStartCol, nStartCol, nStartCol);
2954 		aCol2 = Color(nEndCol, nEndCol, nEndCol);
2955 
2956 		XGradient aGrad2( aCol2 ,  aCol1 , eGrad, nAngle, nFocusX, nFocusY );
2957 		aSet.Put( XFillFloatTransparenceItem( String(), aGrad2 ) );
2958 	}
2959 }
2960 
2961 //---------------------------------------------------------------------------
2962 //- Record Manager ----------------------------------------------------------
2963 //---------------------------------------------------------------------------
2964 
2965 DffRecordList::DffRecordList( DffRecordList* pList ) :
2966 	nCount					( 0 ),
2967 	nCurrent				( 0 ),
2968 	pPrev					( pList ),
2969 	pNext					( NULL )
2970 {
2971 	if ( pList )
2972 		pList->pNext = this;
2973 }
2974 
2975 DffRecordList::~DffRecordList()
2976 {
2977 	delete pNext;
2978 }
2979 
2980 DffRecordManager::DffRecordManager() :
2981 	DffRecordList	( NULL ),
2982 	pCList			( (DffRecordList*)this )
2983 {
2984 }
2985 
2986 DffRecordManager::DffRecordManager( SvStream& rIn ) :
2987 	DffRecordList	( NULL ),
2988 	pCList			( (DffRecordList*)this )
2989 {
2990 	Consume( rIn );
2991 }
2992 
2993 DffRecordManager::~DffRecordManager()
2994 {
2995 };
2996 
2997 
2998 void DffRecordManager::Consume( SvStream& rIn, sal_Bool bAppend, sal_uInt32 nStOfs )
2999 {
3000 	if ( !bAppend )
3001 		Clear();
3002 	sal_uInt32 nOldPos = rIn.Tell();
3003 	if ( !nStOfs )
3004 	{
3005 		DffRecordHeader aHd;
3006 		rIn >> aHd;
3007 		if ( aHd.nRecVer == DFF_PSFLAG_CONTAINER )
3008 			nStOfs = aHd.GetRecEndFilePos();
3009 	}
3010 	if ( nStOfs )
3011 	{
3012 		pCList = (DffRecordList*)this;
3013 		while ( pCList->pNext )
3014 			pCList = pCList->pNext;
3015 		while ( ( rIn.GetError() == 0 ) && ( ( rIn.Tell() + 8 ) <=  nStOfs ) )
3016 		{
3017 			if ( pCList->nCount == DFF_RECORD_MANAGER_BUF_SIZE )
3018 				pCList = new DffRecordList( pCList );
3019 			rIn >> pCList->mHd[ pCList->nCount ];
3020 			pCList->mHd[ pCList->nCount++ ].SeekToEndOfRecord( rIn );
3021 		}
3022 		rIn.Seek( nOldPos );
3023 	}
3024 }
3025 
3026 void DffRecordManager::Clear()
3027 {
3028 	pCList = (DffRecordList*)this;
3029 	delete pNext, pNext = NULL;
3030 	nCurrent = 0;
3031 	nCount = 0;
3032 }
3033 
3034 DffRecordHeader* DffRecordManager::Current()
3035 {
3036 	DffRecordHeader* pRet = NULL;
3037 	if ( pCList->nCurrent < pCList->nCount )
3038 		pRet = &pCList->mHd[ pCList->nCurrent ];
3039 	return pRet;
3040 }
3041 
3042 DffRecordHeader* DffRecordManager::First()
3043 {
3044 	DffRecordHeader* pRet = NULL;
3045 	pCList = (DffRecordList*)this;
3046 	if ( pCList->nCount )
3047 	{
3048 		pCList->nCurrent = 0;
3049 		pRet = &pCList->mHd[ 0 ];
3050 	}
3051 	return pRet;
3052 }
3053 
3054 DffRecordHeader* DffRecordManager::Next()
3055 {
3056 	DffRecordHeader* pRet = NULL;
3057 	sal_uInt32 nC = pCList->nCurrent + 1;
3058 	if ( nC < pCList->nCount )
3059 	{
3060 		pCList->nCurrent++;
3061 		pRet = &pCList->mHd[ nC ];
3062 	}
3063 	else if ( pCList->pNext )
3064 	{
3065 		pCList = pCList->pNext;
3066 		pCList->nCurrent = 0;
3067 		pRet = &pCList->mHd[ 0 ];
3068 	}
3069 	return pRet;
3070 }
3071 
3072 DffRecordHeader* DffRecordManager::Prev()
3073 {
3074 	DffRecordHeader* pRet = NULL;
3075 	sal_uInt32 nCur = pCList->nCurrent;
3076 	if ( !nCur && pCList->pPrev )
3077 	{
3078 		pCList = pCList->pPrev;
3079 		nCur = pCList->nCount;
3080 	}
3081 	if ( nCur-- )
3082 	{
3083 		pCList->nCurrent = nCur;
3084 		pRet = &pCList->mHd[ nCur ];
3085 	}
3086 	return pRet;
3087 }
3088 
3089 DffRecordHeader* DffRecordManager::Last()
3090 {
3091 	DffRecordHeader* pRet = NULL;
3092 	while ( pCList->pNext )
3093 		pCList = pCList->pNext;
3094 	sal_uInt32 nCnt = pCList->nCount;
3095 	if ( nCnt-- )
3096 	{
3097 		pCList->nCurrent = nCnt;
3098 		pRet = &pCList->mHd[ nCnt ];
3099 	}
3100 	return pRet;
3101 }
3102 
3103 sal_Bool DffRecordManager::SeekToContent( SvStream& rIn, sal_uInt16 nRecId, DffSeekToContentMode eMode )
3104 {
3105 	DffRecordHeader* pHd = GetRecordHeader( nRecId, eMode );
3106 	if ( pHd )
3107 	{
3108 		pHd->SeekToContent( rIn );
3109 		return sal_True;
3110 	}
3111 	else
3112 		return sal_False;
3113 }
3114 
3115 DffRecordHeader* DffRecordManager::GetRecordHeader( sal_uInt16 nRecId, DffSeekToContentMode eMode )
3116 {
3117 	sal_uInt32 nOldCurrent = pCList->nCurrent;
3118 	DffRecordList* pOldList = pCList;
3119 	DffRecordHeader* pHd;
3120 
3121 	if ( eMode == SEEK_FROM_BEGINNING )
3122 		pHd = First();
3123 	else
3124 		pHd = Next();
3125 
3126 	while ( pHd )
3127 	{
3128 		if ( pHd->nRecType == nRecId )
3129 			break;
3130 		pHd = Next();
3131 	}
3132 	if ( !pHd && eMode == SEEK_FROM_CURRENT_AND_RESTART )
3133 	{
3134 		DffRecordHeader* pBreak = &pOldList->mHd[ nOldCurrent ];
3135 		pHd = First();
3136 		if ( pHd )
3137 		{
3138 			while ( pHd != pBreak )
3139 			{
3140 				if ( pHd->nRecType == nRecId )
3141 					break;
3142 				pHd = Next();
3143 			}
3144 			if ( pHd->nRecType != nRecId )
3145 				pHd = NULL;
3146 		}
3147 	}
3148 	if ( !pHd )
3149 	{
3150 		pCList = pOldList;
3151 		pOldList->nCurrent = nOldCurrent;
3152 	}
3153 	return pHd;
3154 }
3155 
3156 //---------------------------------------------------------------------------
3157 //  private Methoden
3158 //---------------------------------------------------------------------------
3159 
3160 struct EscherBlipCacheEntry
3161 {
3162 	ByteString	aUniqueID;
3163     sal_uInt32  nBlip;
3164 
3165     EscherBlipCacheEntry( sal_uInt32 nBlipId, const ByteString& rUniqueID ) :
3166 		aUniqueID( rUniqueID ),
3167 		nBlip( nBlipId ) {}
3168 };
3169 
3170 void SvxMSDffManager::Scale( sal_Int32& rVal ) const
3171 {
3172 	if ( bNeedMap )
3173 		rVal = BigMulDiv( rVal, nMapMul, nMapDiv );
3174 }
3175 
3176 void SvxMSDffManager::Scale( Point& rPos ) const
3177 {
3178 	rPos.X() += nMapXOfs;
3179 	rPos.Y() += nMapYOfs;
3180 	if ( bNeedMap )
3181 	{
3182 		rPos.X() = BigMulDiv( rPos.X(), nMapMul, nMapDiv );
3183 		rPos.Y() = BigMulDiv( rPos.Y(), nMapMul, nMapDiv );
3184 	}
3185 }
3186 
3187 void SvxMSDffManager::Scale( Size& rSiz ) const
3188 {
3189 	if ( bNeedMap )
3190 	{
3191 		rSiz.Width() = BigMulDiv( rSiz.Width(), nMapMul, nMapDiv );
3192 		rSiz.Height() = BigMulDiv( rSiz.Height(), nMapMul, nMapDiv );
3193 	}
3194 }
3195 
3196 void SvxMSDffManager::Scale( Rectangle& rRect ) const
3197 {
3198 	rRect.Move( nMapXOfs, nMapYOfs );
3199 	if ( bNeedMap )
3200 	{
3201 		rRect.Left()  =BigMulDiv( rRect.Left()  , nMapMul, nMapDiv );
3202 		rRect.Top()   =BigMulDiv( rRect.Top()   , nMapMul, nMapDiv );
3203 		rRect.Right() =BigMulDiv( rRect.Right() , nMapMul, nMapDiv );
3204 		rRect.Bottom()=BigMulDiv( rRect.Bottom(), nMapMul, nMapDiv );
3205 	}
3206 }
3207 
3208 void SvxMSDffManager::Scale( Polygon& rPoly ) const
3209 {
3210 	if ( !bNeedMap )
3211 		return;
3212 	sal_uInt16 nPointAnz = rPoly.GetSize();
3213 	for ( sal_uInt16 nPointNum = 0; nPointNum < nPointAnz; nPointNum++ )
3214 		Scale( rPoly[ nPointNum ] );
3215 }
3216 
3217 void SvxMSDffManager::Scale( PolyPolygon& rPoly ) const
3218 {
3219 	if ( !bNeedMap )
3220 		return;
3221 	sal_uInt16 nPolyAnz = rPoly.Count();
3222 	for ( sal_uInt16 nPolyNum = 0; nPolyNum < nPolyAnz; nPolyNum++ )
3223 		Scale( rPoly[ nPolyNum ] );
3224 }
3225 
3226 void SvxMSDffManager::ScaleEmu( sal_Int32& rVal ) const
3227 {
3228 	rVal = BigMulDiv( rVal, nEmuMul, nEmuDiv );
3229 }
3230 
3231 sal_uInt32 SvxMSDffManager::ScalePt( sal_uInt32 nVal ) const
3232 {
3233 	MapUnit eMap = pSdrModel->GetScaleUnit();
3234 	Fraction aFact( GetMapFactor( MAP_POINT, eMap ).X() );
3235 	long aMul = aFact.GetNumerator();
3236 	long aDiv = aFact.GetDenominator() * 65536;
3237 	aFact = Fraction( aMul, aDiv ); // nochmal versuchen zu kuerzen
3238 	return BigMulDiv( nVal, aFact.GetNumerator(), aFact.GetDenominator() );
3239 }
3240 
3241 sal_Int32 SvxMSDffManager::ScalePoint( sal_Int32 nVal ) const
3242 {
3243 	return BigMulDiv( nVal, nPntMul, nPntDiv );
3244 };
3245 
3246 void SvxMSDffManager::SetModel(SdrModel* pModel, long nApplicationScale)
3247 {
3248 	pSdrModel = pModel;
3249 	if( pModel && (0 < nApplicationScale) )
3250 	{
3251 		// PPT arbeitet nur mit Einheiten zu 576DPI
3252 		// WW hingegen verwendet twips, dh. 1440DPI.
3253 		MapUnit eMap = pSdrModel->GetScaleUnit();
3254 		Fraction aFact( GetMapFactor(MAP_INCH, eMap).X() );
3255 		long nMul=aFact.GetNumerator();
3256 		long nDiv=aFact.GetDenominator()*nApplicationScale;
3257 		aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3258 		// Bei 100TH_MM -> 2540/576=635/144
3259 		// Bei Twip     -> 1440/576=5/2
3260 		nMapMul  = aFact.GetNumerator();
3261 		nMapDiv  = aFact.GetDenominator();
3262 		bNeedMap = nMapMul!=nMapDiv;
3263 
3264 		// MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
3265 		// 1mm=36000emu, 1twip=635emu
3266 		aFact=GetMapFactor(MAP_100TH_MM,eMap).X();
3267 		nMul=aFact.GetNumerator();
3268 		nDiv=aFact.GetDenominator()*360;
3269 		aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3270 		// Bei 100TH_MM ->                            1/360
3271 		// Bei Twip     -> 14,40/(25,4*360)=144/91440=1/635
3272 		nEmuMul=aFact.GetNumerator();
3273 		nEmuDiv=aFact.GetDenominator();
3274 
3275 		// Und noch was fuer typografische Points
3276 		aFact=GetMapFactor(MAP_POINT,eMap).X();
3277 		nPntMul=aFact.GetNumerator();
3278 		nPntDiv=aFact.GetDenominator();
3279 	}
3280 	else
3281 	{
3282 		pModel = 0;
3283 		nMapMul = nMapDiv = nMapXOfs = nMapYOfs = nEmuMul = nEmuDiv = nPntMul = nPntDiv = 0;
3284 		bNeedMap = sal_False;
3285 	}
3286 }
3287 
3288 sal_Bool SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, sal_uInt32 nId ) const
3289 {
3290 	sal_Bool bRet = sal_False;
3291 	if ( mpFidcls )
3292 	{
3293 		sal_uInt32 nMerk = rSt.Tell();
3294 		sal_uInt32 nShapeId, nSec = ( nId >> 10 ) - 1;
3295 		if ( nSec < mnIdClusters )
3296 		{
3297 			sal_IntPtr nOfs = (sal_IntPtr)maDgOffsetTable.Get( mpFidcls[ nSec ].dgid );
3298 			if ( nOfs )
3299 			{
3300 				rSt.Seek( nOfs );
3301 				DffRecordHeader aEscherF002Hd;
3302 				rSt >> aEscherF002Hd;
3303 				sal_uLong nEscherF002End = aEscherF002Hd.GetRecEndFilePos();
3304 				DffRecordHeader aEscherObjListHd;
3305 				while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nEscherF002End ) )
3306 				{
3307 					rSt >> aEscherObjListHd;
3308 					if ( aEscherObjListHd.nRecVer != 0xf )
3309 						aEscherObjListHd.SeekToEndOfRecord( rSt );
3310 					else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer )
3311 					{
3312 						DffRecordHeader aShapeHd;
3313 						if ( SeekToRec( rSt, DFF_msofbtSp, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) )
3314 						{
3315 							rSt >> nShapeId;
3316 							if ( nId == nShapeId )
3317 							{
3318 								aEscherObjListHd.SeekToBegOfRecord( rSt );
3319 								bRet = sal_True;
3320 								break;
3321 							}
3322 						}
3323 						aEscherObjListHd.SeekToEndOfRecord( rSt );
3324 					}
3325 				}
3326 			}
3327 		}
3328 		if ( !bRet )
3329 			rSt.Seek( nMerk );
3330 	}
3331 	return bRet;
3332 }
3333 
3334 FASTBOOL SvxMSDffManager::SeekToRec( SvStream& rSt, sal_uInt16 nRecId, sal_uLong nMaxFilePos, DffRecordHeader* pRecHd, sal_uLong nSkipCount ) const
3335 {
3336 	FASTBOOL bRet = sal_False;
3337 	sal_uLong nFPosMerk = rSt.Tell(); // store FilePos to restore it later if necessary
3338 	DffRecordHeader aHd;
3339 	do
3340 	{
3341 		rSt >> aHd;
3342 
3343         // check potential error reading and if seeking to the end of record is possible at all.
3344         // It is probably cheaper instead of doing the file seek operation
3345         if ( rSt.GetError() || ( aHd.GetRecEndFilePos() >  nMaxFilePos ) )
3346         {
3347             bRet= sal_False;
3348             break;
3349         }
3350 
3351 		if ( aHd.nRecType == nRecId )
3352 		{
3353 			if ( nSkipCount )
3354 				nSkipCount--;
3355 			else
3356 			{
3357 				bRet = sal_True;
3358 				if ( pRecHd != NULL )
3359 					*pRecHd = aHd;
3360 				else
3361 					aHd.SeekToBegOfRecord( rSt );
3362 			}
3363 		}
3364 		if ( !bRet )
3365 			aHd.SeekToEndOfRecord( rSt );
3366 	}
3367 	while ( rSt.GetError() == 0 && rSt.Tell() < nMaxFilePos && !bRet );
3368 	if ( !bRet )
3369 		rSt.Seek( nFPosMerk );	// restore orginal FilePos
3370 	return bRet;
3371 }
3372 
3373 FASTBOOL SvxMSDffManager::SeekToRec2( sal_uInt16 nRecId1, sal_uInt16 nRecId2, sal_uLong nMaxFilePos, DffRecordHeader* pRecHd, sal_uLong nSkipCount ) const
3374 {
3375 	FASTBOOL bRet = sal_False;
3376 	sal_uLong nFPosMerk = rStCtrl.Tell();	// FilePos merken fuer ggf. spaetere Restauration
3377 	DffRecordHeader aHd;
3378 	do
3379 	{
3380 		rStCtrl >> aHd;
3381 		if ( aHd.nRecType == nRecId1 || aHd.nRecType == nRecId2 )
3382 		{
3383 			if ( nSkipCount )
3384 				nSkipCount--;
3385 			else
3386 			{
3387 				bRet = sal_True;
3388 				if ( pRecHd )
3389 					*pRecHd = aHd;
3390 				else
3391 					aHd.SeekToBegOfRecord( rStCtrl );
3392 			}
3393 		}
3394 		if ( !bRet )
3395 			aHd.SeekToEndOfRecord( rStCtrl );
3396 	}
3397 	while ( rStCtrl.GetError() == 0 && rStCtrl.Tell() < nMaxFilePos && !bRet );
3398 	if ( !bRet )
3399 		rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
3400 	return bRet;
3401 }
3402 
3403 
3404 FASTBOOL SvxMSDffManager::GetColorFromPalette( sal_uInt16 /* nNum */, Color& rColor ) const
3405 {
3406 	// diese Methode ist in der zum Excel-Import
3407 	// abgeleiteten Klasse zu ueberschreiben...
3408 	rColor.SetColor( COL_WHITE );
3409 	return sal_True;
3410 }
3411 
3412 // sj: the documentation is not complete, especially in ppt the normal rgb for text
3413 // color is written as 0xfeRRGGBB, this can't be explained by the documentation, nearly
3414 // every bit in the upper code is set -> so there seems to be a special handling for
3415 // ppt text colors, i decided not to fix this in MSO_CLR_ToColor because of possible
3416 // side effects, instead MSO_TEXT_CLR_ToColor is called for PPT text colors, to map
3417 // the color code to something that behaves like the other standard color codes used by
3418 // fill and line color
3419 Color SvxMSDffManager::MSO_TEXT_CLR_ToColor( sal_uInt32 nColorCode ) const
3420 {
3421 	// Fuer Textfarben: Header ist 0xfeRRGGBB
3422 	if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 )
3423 		nColorCode &= 0x00ffffff;
3424 	else
3425 	{
3426 		// for colorscheme colors the color index are the lower three bits of the upper byte
3427 		if ( ( nColorCode & 0xf8000000 ) == 0 ) // this must be a colorscheme index
3428 		{
3429 			nColorCode >>= 24;
3430 			nColorCode |= 0x8000000;
3431 		}
3432 	}
3433 	return MSO_CLR_ToColor( nColorCode );
3434 }
3435 
3436 Color SvxMSDffManager::MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContentProperty ) const
3437 {
3438 	Color aColor( mnDefaultColor );
3439 
3440 	// Fuer Textfarben: Header ist 0xfeRRGGBB
3441 	if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 )	// sj: it needs to be checked if 0xfe is used in
3442 		nColorCode &= 0x00ffffff;						// other cases than ppt text -> if not this code can be removed
3443 
3444 	sal_uInt8 nUpper = (sal_uInt8)( nColorCode >> 24 );
3445 
3446 	// sj: below change from 0x1b to 0x19 was done because of i84812 (0x02 -> rgb color),
3447 	// now I have some problems to fix i104685 (there the color value is 0x02000000 whichs requires
3448 	// a 0x2 scheme color to be displayed properly), the color docu seems to be incomplete
3449 	if( nUpper & 0x19 )      // if( nUpper & 0x1f )
3450 	{
3451 		if( ( nUpper & 0x08 ) || ( ( nUpper & 0x10 ) == 0 ) )
3452 		{
3453 			// SCHEMECOLOR
3454 			if ( !GetColorFromPalette( ( nUpper & 8 ) ? (sal_uInt16)nColorCode : nUpper, aColor ) )
3455 			{
3456 				switch( nContentProperty )
3457 				{
3458 					case DFF_Prop_pictureTransparent :
3459 					case DFF_Prop_shadowColor :
3460 					case DFF_Prop_fillBackColor :
3461 					case DFF_Prop_fillColor :
3462 						aColor = Color( COL_WHITE );
3463 					break;
3464 					case DFF_Prop_lineColor :
3465 					{
3466 						aColor = Color( COL_BLACK );
3467 					}
3468 					break;
3469 				}
3470 			}
3471 		}
3472 		else	// SYSCOLOR
3473 		{
3474 			const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
3475 
3476 //			sal_uInt16 nParameter = (sal_uInt8)( nColorCode >> 16);					// SJ: nice compiler optimization bug on windows, though downcasting
3477 			sal_uInt16 nParameter = sal_uInt16(( nColorCode >> 16 ) & 0x00ff);	// the HiByte of nParameter is not zero, an exclusive AND is helping :o
3478 			sal_uInt16 nFunctionBits = (sal_uInt16)( ( nColorCode & 0x00000f00 ) >> 8 );
3479 			sal_uInt16 nAdditionalFlags = (sal_uInt16)( ( nColorCode & 0x0000f000) >> 8 );
3480 			sal_uInt16 nColorIndex = sal_uInt16(nColorCode & 0x00ff);
3481 			sal_uInt32 nPropColor = 0;
3482 
3483 			sal_uInt16	nCProp = 0;
3484 
3485 			switch ( nColorIndex )
3486 			{
3487 				case mso_syscolorButtonFace :			aColor = rStyleSettings.GetFaceColor(); break;
3488 				case mso_syscolorWindowText :			aColor = rStyleSettings.GetWindowTextColor(); break;
3489 				case mso_syscolorMenu :					aColor = rStyleSettings.GetMenuColor(); break;
3490 				case mso_syscolor3DLight :
3491 				case mso_syscolorButtonHighlight :
3492 				case mso_syscolorHighlight :			aColor = rStyleSettings.GetHighlightColor(); break;
3493 				case mso_syscolorHighlightText :		aColor = rStyleSettings.GetHighlightTextColor(); break;
3494 				case mso_syscolorCaptionText :			aColor = rStyleSettings.GetMenuTextColor(); break;
3495 				case mso_syscolorActiveCaption :		aColor = rStyleSettings.GetHighlightColor(); break;
3496 				case mso_syscolorButtonShadow :			aColor = rStyleSettings.GetShadowColor(); break;
3497 				case mso_syscolorButtonText :			aColor = rStyleSettings.GetButtonTextColor(); break;
3498 				case mso_syscolorGrayText :				aColor = rStyleSettings.GetDeactiveColor(); break;
3499 				case mso_syscolorInactiveCaption :		aColor = rStyleSettings.GetDeactiveColor(); break;
3500 				case mso_syscolorInactiveCaptionText :	aColor = rStyleSettings.GetDeactiveColor(); break;
3501 				case mso_syscolorInfoBackground :		aColor = rStyleSettings.GetFaceColor(); break;
3502 				case mso_syscolorInfoText :				aColor = rStyleSettings.GetInfoTextColor(); break;
3503 				case mso_syscolorMenuText :				aColor = rStyleSettings.GetMenuTextColor(); break;
3504 				case mso_syscolorScrollbar :			aColor = rStyleSettings.GetFaceColor(); break;
3505 				case mso_syscolorWindow :				aColor = rStyleSettings.GetWindowColor(); break;
3506 				case mso_syscolorWindowFrame :			aColor = rStyleSettings.GetWindowColor(); break;
3507 
3508 				case mso_colorFillColor :
3509 				{
3510 					nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3511 					nCProp = DFF_Prop_fillColor;
3512 				}
3513 				break;
3514 				case mso_colorLineOrFillColor :		// ( use the line color only if there is a line )
3515 				{
3516 					if ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 )
3517 					{
3518 						nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3519 						nCProp = DFF_Prop_lineColor;
3520 					}
3521 					else
3522 					{
3523 						nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3524 						nCProp = DFF_Prop_fillColor;
3525 					}
3526 				}
3527 				break;
3528 				case mso_colorLineColor :
3529 				{
3530 					nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3531 					nCProp = DFF_Prop_lineColor;
3532 				}
3533 				break;
3534 				case mso_colorShadowColor :
3535 				{
3536 					nPropColor = GetPropertyValue( DFF_Prop_shadowColor, 0x808080 );
3537 					nCProp = DFF_Prop_shadowColor;
3538 				}
3539 				break;
3540 				case mso_colorThis :				// ( use this color ... )
3541 				{
3542 					nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );	//?????????????
3543 					nCProp = DFF_Prop_fillColor;
3544 				}
3545 				break;
3546 				case mso_colorFillBackColor :
3547 				{
3548 					nPropColor = GetPropertyValue( DFF_Prop_fillBackColor, 0xffffff );
3549 					nCProp = DFF_Prop_fillBackColor;
3550 				}
3551 				break;
3552 				case mso_colorLineBackColor :
3553 				{
3554 					nPropColor = GetPropertyValue( DFF_Prop_lineBackColor, 0xffffff );
3555 					nCProp = DFF_Prop_lineBackColor;
3556 				}
3557 				break;
3558 				case mso_colorFillThenLine :		// ( use the fillcolor unless no fill and line )
3559 				{
3560 					nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );	//?????????????
3561 					nCProp = DFF_Prop_fillColor;
3562 				}
3563 				break;
3564 				case mso_colorIndexMask :			// ( extract the color index ) ?
3565 				{
3566 					nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );	//?????????????
3567 					nCProp = DFF_Prop_fillColor;
3568 				}
3569 				break;
3570 			}
3571 			if ( nCProp && ( nPropColor & 0x10000000 ) == 0 )		// beware of looping recursive
3572 				aColor = MSO_CLR_ToColor( nPropColor, nCProp );
3573 
3574 			if( nAdditionalFlags & 0x80 )			// make color gray
3575 			{
3576 				sal_uInt8 nZwi = aColor.GetLuminance();
3577 				aColor = Color( nZwi, nZwi, nZwi );
3578 			}
3579 			switch( nFunctionBits )
3580 			{
3581 				case 0x01 :		// darken color by parameter
3582 				{
3583 					aColor.SetRed( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetRed() ) >> 8 ) );
3584 					aColor.SetGreen( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetGreen() ) >> 8 ) );
3585 					aColor.SetBlue( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetBlue() ) >> 8 ) );
3586 				}
3587 				break;
3588 				case 0x02 :		// lighten color by parameter
3589 				{
3590 					sal_uInt16 nInvParameter = ( 0x00ff - nParameter ) * 0xff;
3591 					aColor.SetRed( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetRed() ) ) >> 8 ) );
3592 					aColor.SetGreen( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetGreen() ) ) >> 8 ) );
3593 					aColor.SetBlue( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetBlue() ) ) >> 8 ) );
3594 				}
3595 				break;
3596 				case 0x03 :		// add grey level RGB(p,p,p)
3597 				{
3598 					sal_Int16 nR = (sal_Int16)aColor.GetRed() + (sal_Int16)nParameter;
3599 					sal_Int16 nG = (sal_Int16)aColor.GetGreen() + (sal_Int16)nParameter;
3600 					sal_Int16 nB = (sal_Int16)aColor.GetBlue() + (sal_Int16)nParameter;
3601 					if ( nR > 0x00ff )
3602 						nR = 0x00ff;
3603 					if ( nG > 0x00ff )
3604 						nG = 0x00ff;
3605 					if ( nB > 0x00ff )
3606 						nB = 0x00ff;
3607 					aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB );
3608 				}
3609 				break;
3610 				case 0x04 :		// substract grey level RGB(p,p,p)
3611 				{
3612 					sal_Int16 nR = (sal_Int16)aColor.GetRed() - (sal_Int16)nParameter;
3613 					sal_Int16 nG = (sal_Int16)aColor.GetGreen() - (sal_Int16)nParameter;
3614 					sal_Int16 nB = (sal_Int16)aColor.GetBlue() - (sal_Int16)nParameter;
3615 					if ( nR < 0 )
3616 						nR = 0;
3617 					if ( nG < 0 )
3618 						nG = 0;
3619 					if ( nB < 0 )
3620 						nB = 0;
3621 					aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB );
3622 				}
3623 				break;
3624 				case 0x05 :		// substract from grey level RGB(p,p,p)
3625 				{
3626 					sal_Int16 nR = (sal_Int16)nParameter - (sal_Int16)aColor.GetRed();
3627 					sal_Int16 nG = (sal_Int16)nParameter - (sal_Int16)aColor.GetGreen();
3628 					sal_Int16 nB = (sal_Int16)nParameter - (sal_Int16)aColor.GetBlue();
3629 					if ( nR < 0 )
3630 						nR = 0;
3631 					if ( nG < 0 )
3632 						nG = 0;
3633 					if ( nB < 0 )
3634 						nB = 0;
3635 					aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB );
3636 				}
3637 				break;
3638 				case 0x06 :		// per component: black if < p, white if >= p
3639 				{
3640 					aColor.SetRed( aColor.GetRed() < nParameter ? 0x00 : 0xff );
3641 					aColor.SetGreen( aColor.GetGreen() < nParameter ? 0x00 : 0xff );
3642 					aColor.SetBlue( aColor.GetBlue() < nParameter ? 0x00 : 0xff );
3643 				}
3644 				break;
3645 			}
3646 			if ( nAdditionalFlags & 0x40 )					// top-bit invert
3647 				aColor = Color( aColor.GetRed() ^ 0x80, aColor.GetGreen() ^ 0x80, aColor.GetBlue() ^ 0x80 );
3648 
3649 			if ( nAdditionalFlags & 0x20 )					// invert color
3650 				aColor = Color(0xff - aColor.GetRed(), 0xff - aColor.GetGreen(), 0xff - aColor.GetBlue());
3651 		}
3652 	}
3653 	else if ( ( nUpper & 4 ) && ( ( nColorCode & 0xfffff8 ) == 0 ) )
3654 	{	// case of nUpper == 4 powerpoint takes this as agrument for a colorschemecolor
3655 		GetColorFromPalette( nUpper, aColor );
3656 	}
3657 	else	// hart attributiert, eventuell mit Hinweis auf SYSTEMRGB
3658 		aColor = Color( (sal_uInt8)nColorCode, (sal_uInt8)( nColorCode >> 8 ), (sal_uInt8)( nColorCode >> 16 ) );
3659 	return aColor;
3660 }
3661 
3662 // sj: I just want to set a string for a text object that may contain multiple
3663 // paragraphs. If I now take a look at the follwing code I get the impression that
3664 // our outliner is too complicate to be used properly,
3665 void SvxMSDffManager::ReadObjText( const String& rText, SdrObject* pObj ) const
3666 {
3667 	SdrTextObj* pText = PTR_CAST( SdrTextObj, pObj );
3668 	if ( pText )
3669 	{
3670         SdrOutliner& rOutliner = pText->ImpGetDrawOutliner();
3671 		rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
3672 
3673 		sal_Bool bOldUpdateMode = rOutliner.GetUpdateMode();
3674 		rOutliner.SetUpdateMode( sal_False );
3675 		rOutliner.SetVertical( pText->IsVerticalWriting() );
3676 
3677 		sal_uInt16 nParaIndex = 0;
3678 		sal_uInt32 nParaSize;
3679 		const sal_Unicode* pCurrent, *pBuf = rText.GetBuffer();
3680 		const sal_Unicode* pEnd = rText.GetBuffer() + rText.Len();
3681 
3682 		while( pBuf < pEnd )
3683 		{
3684 			pCurrent = pBuf;
3685 
3686 			for ( nParaSize = 0; pBuf < pEnd; )
3687 			{
3688 				sal_Unicode nChar = *pBuf++;
3689 				if ( nChar == 0xa )
3690 				{
3691 					if ( ( pBuf < pEnd ) && ( *pBuf == 0xd ) )
3692 						pBuf++;
3693 					break;
3694 				}
3695 				else if ( nChar == 0xd )
3696 				{
3697 					if ( ( pBuf < pEnd ) && ( *pBuf == 0xa ) )
3698 						pBuf++;
3699 					break;
3700 				}
3701 				else
3702 					nParaSize++;
3703 			}
3704 			ESelection aSelection( nParaIndex, 0, nParaIndex, 0 );
3705 			String aParagraph( pCurrent, (sal_uInt16)nParaSize );
3706 			if ( !nParaIndex && !aParagraph.Len() )					// SJ: we are crashing if the first paragraph is empty ?
3707 				aParagraph += (sal_Unicode)' ';						// otherwise these two lines can be removed.
3708 			rOutliner.Insert( aParagraph, nParaIndex, 0 );
3709 			rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() );
3710 
3711 			SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() );
3712 			if ( !aSelection.nStartPos )
3713 				aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, sal_False ) );
3714 			aSelection.nStartPos = 0;
3715 			rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection );
3716 			nParaIndex++;
3717 		}
3718 		OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
3719         rOutliner.Clear();
3720 		rOutliner.SetUpdateMode( bOldUpdateMode );
3721 		pText->SetOutlinerParaObject( pNewText );
3722 	}
3723 }
3724 
3725 //static
3726 void SvxMSDffManager::MSDFFReadZString( SvStream& rIn, String& rStr,
3727 									sal_uLong nRecLen, FASTBOOL bUniCode )
3728 {
3729 	sal_uInt16 nLen = (sal_uInt16)nRecLen;
3730 	if( nLen )
3731 	{
3732 		if ( bUniCode )
3733 			nLen >>= 1;
3734 
3735 		String sBuf;
3736 		sal_Unicode* pBuf = sBuf.AllocBuffer( nLen );
3737 
3738 		if( bUniCode )
3739 		{
3740 			rIn.Read( (sal_Char*)pBuf, nLen << 1 );
3741 
3742 #ifdef OSL_BIGENDIAN
3743 			for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf )
3744     	    	*pBuf = SWAPSHORT( *pBuf );
3745 #endif // ifdef OSL_BIGENDIAN
3746 		}
3747 		else
3748 		{
3749 			// use the String-Data as buffer for the 8bit characters and
3750 			// change then all to unicode
3751 			sal_Char* pReadPos = ((sal_Char*)pBuf) + nLen;
3752 			rIn.Read( (sal_Char*)pReadPos, nLen );
3753 			for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf, ++pReadPos )
3754 				*pBuf = ByteString::ConvertToUnicode( *pReadPos, RTL_TEXTENCODING_MS_1252 );
3755 		}
3756 
3757 		rStr = sBuf.EraseTrailingChars( 0 );
3758 	}
3759 	else
3760 		rStr.Erase();
3761 }
3762 
3763 SdrObject* SvxMSDffManager::ImportFontWork( SvStream& rStCt, SfxItemSet& rSet, Rectangle& rBoundRect ) const
3764 {
3765 	SdrObject*	pRet = NULL;
3766 	String		aObjectText;
3767 	String		aFontName;
3768 	sal_Bool		bTextRotate = sal_False;
3769 
3770 	((SvxMSDffManager*)this)->mnFix16Angle = 0;	// we don't want to use this property in future
3771 	if ( SeekToContent( DFF_Prop_gtextUNICODE, rStCt ) )
3772 		MSDFFReadZString( rStCt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), sal_True );
3773 	if ( SeekToContent( DFF_Prop_gtextFont, rStCt ) )
3774 		MSDFFReadZString( rStCt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), sal_True );
3775 	if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 )
3776 	{
3777 		// Text ist senkrecht formatiert, Box Kippen
3778 		sal_Int32 nHalfWidth = ( rBoundRect.GetWidth() + 1) >> 1;
3779 		sal_Int32 nHalfHeight = ( rBoundRect.GetHeight() + 1) >> 1;
3780 		Point aTopLeft( rBoundRect.Left() + nHalfWidth - nHalfHeight,
3781 				rBoundRect.Top() + nHalfHeight - nHalfWidth);
3782 		Size aNewSize( rBoundRect.GetHeight(), rBoundRect.GetWidth() );
3783 		Rectangle aNewRect( aTopLeft, aNewSize );
3784 		rBoundRect = aNewRect;
3785 
3786 		String aSrcText( aObjectText );
3787 		aObjectText.Erase();
3788 		for( sal_uInt16 a = 0; a < aSrcText.Len(); a++ )
3789 		{
3790 			aObjectText += aSrcText.GetChar( a );
3791 			aObjectText += '\n';
3792 		}
3793 		rSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) );
3794 		bTextRotate = sal_True;
3795 	}
3796 	if ( aObjectText.Len() )
3797 	{	// FontWork-Objekt Mit dem Text in aObjectText erzeugen
3798 		SdrObject* pNewObj = new SdrRectObj( OBJ_TEXT, rBoundRect );
3799 		if( pNewObj )
3800 		{
3801 			pNewObj->SetModel( pSdrModel );
3802 			((SdrRectObj*)pNewObj)->SetText( aObjectText );
3803 			SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
3804 			rSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
3805 			rSet.Put( SdrTextAutoGrowHeightItem( sal_False ) );
3806 			rSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
3807             rSet.Put( SvxFontItem( FAMILY_DONTKNOW, aFontName, String(),
3808                             PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
3809 
3810             pNewObj->SetMergedItemSet(rSet);
3811 
3812 			pRet = pNewObj->ConvertToPolyObj( sal_False, sal_False );
3813 			if( !pRet )
3814 				pRet = pNewObj;
3815 			else
3816 			{
3817 				pRet->NbcSetSnapRect( rBoundRect );
3818                 SdrObject::Free( pNewObj );
3819 			}
3820 			if( bTextRotate )
3821 			{
3822 				double a = 9000 * nPi180;
3823 				pRet->NbcRotate( rBoundRect.Center(), 9000, sin( a ), cos( a ) );
3824 			}
3825 		}
3826 	}
3827 	return pRet;
3828 }
3829 
3830 static Size lcl_GetPrefSize(const Graphic& rGraf, MapMode aWanted)
3831 {
3832     MapMode aPrefMapMode(rGraf.GetPrefMapMode());
3833     if (aPrefMapMode == aWanted)
3834         return rGraf.GetPrefSize();
3835     Size aRetSize;
3836     if (aPrefMapMode == MAP_PIXEL)
3837     {
3838         aRetSize = Application::GetDefaultDevice()->PixelToLogic(
3839             rGraf.GetPrefSize(), aWanted);
3840     }
3841     else
3842     {
3843 	    aRetSize = Application::GetDefaultDevice()->LogicToLogic(
3844 		    rGraf.GetPrefSize(), rGraf.GetPrefMapMode(), aWanted);
3845     }
3846     return aRetSize;
3847 }
3848 
3849 // sj: if the parameter pSet is null, then the resulting crop bitmap will be stored in rGraf,
3850 // otherwise rGraf is untouched and pSet is used to store the corresponding SdrGrafCropItem
3851 static void lcl_ApplyCropping( const DffPropSet& rPropSet, SfxItemSet* pSet, Graphic& rGraf )
3852 {
3853 	sal_Int32 nCropTop		= (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromTop, 0 );
3854 	sal_Int32 nCropBottom	= (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromBottom, 0 );
3855 	sal_Int32 nCropLeft		= (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromLeft, 0 );
3856 	sal_Int32 nCropRight	= (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromRight, 0 );
3857 
3858 	if( nCropTop || nCropBottom || nCropLeft || nCropRight )
3859 	{
3860 		double      fFactor;
3861 		Size        aCropSize;
3862 		BitmapEx    aCropBitmap;
3863 		sal_uInt32  nTop( 0 ),  nBottom( 0 ), nLeft( 0 ), nRight( 0 );
3864 
3865 		if ( pSet )	// use crop attributes ?
3866 			aCropSize = lcl_GetPrefSize( rGraf, MAP_100TH_MM );
3867 		else
3868 		{
3869 			aCropBitmap = rGraf.GetBitmapEx();
3870 			aCropSize = aCropBitmap.GetSizePixel();
3871 		}
3872 		if ( nCropTop )
3873 		{
3874 			fFactor = (double)nCropTop / 65536.0;
3875 			nTop = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
3876 		}
3877 		if ( nCropBottom )
3878 		{
3879 			fFactor = (double)nCropBottom / 65536.0;
3880 			nBottom = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
3881 		}
3882 		if ( nCropLeft )
3883 		{
3884 			fFactor = (double)nCropLeft / 65536.0;
3885 			nLeft = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
3886 		}
3887 		if ( nCropRight )
3888 		{
3889 			fFactor = (double)nCropRight / 65536.0;
3890 			nRight = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
3891 		}
3892 		if ( pSet )	// use crop attributes ?
3893 			pSet->Put( SdrGrafCropItem( nLeft, nTop, nRight, nBottom ) );
3894 		else
3895 		{
3896     		Rectangle aCropRect( nLeft, nTop, aCropSize.Width() - nRight, aCropSize.Height() - nBottom );
3897 	    	aCropBitmap.Crop( aCropRect );
3898 		    rGraf = aCropBitmap;
3899 		}
3900 	}
3901 }
3902 
3903 SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, const DffObjData& rObjData ) const
3904 {
3905 	SdrObject*  pRet = NULL;
3906 	String      aFileName;
3907 	String      aLinkFileName, aLinkFilterName;
3908 	Rectangle	aVisArea;
3909 
3910 	MSO_BlipFlags eFlags = (MSO_BlipFlags)GetPropertyValue( DFF_Prop_pibFlags, mso_blipflagDefault );
3911 	sal_uInt32 nBlipId = GetPropertyValue( DFF_Prop_pib, 0 );
3912 	sal_Bool bGrfRead = sal_False,
3913 
3914 	// Grafik verlinkt
3915 	bLinkGrf = 0 != ( eFlags & mso_blipflagLinkToFile );
3916 	{
3917 		Graphic aGraf;	// be sure this graphic is deleted before swapping out
3918 		if( SeekToContent( DFF_Prop_pibName, rSt ) )
3919 			MSDFFReadZString( rSt, aFileName, GetPropertyValue( DFF_Prop_pibName ), sal_True );
3920 
3921 		//   UND, ODER folgendes:
3922 		if( !( eFlags & mso_blipflagDoNotSave ) ) // Grafik embedded
3923 		{
3924             bGrfRead = GetBLIP( nBlipId, aGraf, &aVisArea );
3925 			if ( !bGrfRead )
3926 			{
3927 				/*
3928 				Still no luck, lets look at the end of this record for a FBSE pool,
3929 				this fallback is a specific case for how word does it sometimes
3930 				*/
3931 				rObjData.rSpHd.SeekToEndOfRecord( rSt );
3932 				DffRecordHeader aHd;
3933 				rSt >> aHd;
3934 				if( DFF_msofbtBSE == aHd.nRecType )
3935 				{
3936 					const sal_uLong nSkipBLIPLen = 20;
3937 					const sal_uLong nSkipShapePos = 4;
3938 					const sal_uLong nSkipBLIP = 4;
3939 					const sal_uLong nSkip =
3940 						nSkipBLIPLen + 4 + nSkipShapePos + 4 + nSkipBLIP;
3941 
3942 					if (nSkip <= aHd.nRecLen)
3943 					{
3944 						rSt.SeekRel(nSkip);
3945 						if (0 == rSt.GetError())
3946 							bGrfRead = GetBLIPDirect( rSt, aGraf, &aVisArea );
3947 					}
3948 				}
3949 			}
3950 		}
3951 		if ( bGrfRead )
3952 		{
3953 			// the writer is doing it's own cropping, so this part affects only impress and calc
3954 			if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_CROP_BITMAPS )
3955 				lcl_ApplyCropping( *this, ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ? &rSet : NULL, aGraf );
3956 
3957 			if ( IsProperty( DFF_Prop_pictureTransparent ) )
3958 			{
3959 				sal_uInt32 nTransColor = GetPropertyValue( DFF_Prop_pictureTransparent, 0 );
3960 
3961 				if ( aGraf.GetType() == GRAPHIC_BITMAP )
3962 				{
3963 					BitmapEx	aBitmapEx( aGraf.GetBitmapEx() );
3964 					Bitmap		aBitmap( aBitmapEx.GetBitmap() );
3965 					Bitmap		aMask( aBitmap.CreateMask( MSO_CLR_ToColor( nTransColor, DFF_Prop_pictureTransparent ), 9 ) );
3966 					if ( aBitmapEx.IsTransparent() )
3967 						aMask.CombineSimple( aBitmapEx.GetMask(), BMP_COMBINE_OR );
3968 					aGraf = BitmapEx( aBitmap, aMask );
3969 				}
3970 			}
3971 
3972 			sal_Int32 nContrast = GetPropertyValue( DFF_Prop_pictureContrast, 0x10000 );
3973 			/*
3974 			0x10000 is msoffice 50%
3975 			< 0x10000 is in units of 1/50th of 0x10000 per 1%
3976 			> 0x10000 is in units where
3977 			a msoffice x% is stored as 50/(100-x) * 0x10000
3978 
3979 			plus, a (ui) microsoft % ranges from 0 to 100, OOO
3980 			from -100 to 100, so also normalize into that range
3981 			*/
3982 			if ( nContrast > 0x10000 )
3983 			{
3984 				double fX = nContrast;
3985 				fX /= 0x10000;
3986 				fX /= 51;	// 50 + 1 to round
3987 				fX = 1/fX;
3988 				nContrast = static_cast<sal_Int32>(fX);
3989 				nContrast -= 100;
3990 				nContrast = -nContrast;
3991 				nContrast = (nContrast-50)*2;
3992 			}
3993 			else if ( nContrast == 0x10000 )
3994 				nContrast = 0;
3995 			else
3996 			{
3997 				nContrast *= 101;	//100 + 1 to round
3998 				nContrast /= 0x10000;
3999 				nContrast -= 100;
4000 			}
4001 			sal_Int16	nBrightness		= (sal_Int16)( (sal_Int32)GetPropertyValue( DFF_Prop_pictureBrightness, 0 ) / 327 );
4002 			sal_Int32	nGamma			= GetPropertyValue( DFF_Prop_pictureGamma, 0x10000 );
4003 			GraphicDrawMode eDrawMode	= GRAPHICDRAWMODE_STANDARD;
4004 			switch ( GetPropertyValue( DFF_Prop_pictureActive ) & 6 )
4005 			{
4006 				case 4 : eDrawMode = GRAPHICDRAWMODE_GREYS; break;
4007 				case 6 : eDrawMode = GRAPHICDRAWMODE_MONO; break;
4008 				case 0 :
4009 				{
4010 					//office considers the converted values of (in OOo) 70 to be the
4011 					//"watermark" values, which can vary slightly due to rounding from the
4012 					//above values
4013 					if (( nContrast == -70 ) && ( nBrightness == 70 ))
4014 					{
4015 						nContrast = 0;
4016 						nBrightness = 0;
4017 						eDrawMode = GRAPHICDRAWMODE_WATERMARK;
4018 					};
4019 				}
4020 				break;
4021 			}
4022 
4023 			if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) )
4024 			{
4025 				if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 )
4026 				{
4027 					if ( nBrightness )
4028 						rSet.Put( SdrGrafLuminanceItem( nBrightness ) );
4029 					if ( nContrast )
4030 						rSet.Put( SdrGrafContrastItem( (sal_Int16)nContrast ) );
4031 					if ( nGamma != 0x10000 )
4032 						rSet.Put( SdrGrafGamma100Item( nGamma / 655 ) );
4033 					if ( eDrawMode != GRAPHICDRAWMODE_STANDARD )
4034 						rSet.Put( SdrGrafModeItem( eDrawMode ) );
4035 				}
4036 				else
4037 				{
4038 					if ( eDrawMode == GRAPHICDRAWMODE_WATERMARK )
4039 					{
4040 						nContrast = 60;
4041 						nBrightness = 70;
4042 						eDrawMode = GRAPHICDRAWMODE_STANDARD;
4043 					}
4044 					switch ( aGraf.GetType() )
4045 					{
4046 						case GRAPHIC_BITMAP :
4047 						{
4048 							BitmapEx	aBitmapEx( aGraf.GetBitmapEx() );
4049 							if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
4050 								aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False );
4051 							if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
4052 								aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
4053 							else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
4054 								aBitmapEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
4055 							aGraf = aBitmapEx;
4056 
4057 						}
4058 						break;
4059 
4060 						case GRAPHIC_GDIMETAFILE :
4061 						{
4062 							GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() );
4063 							if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
4064 								aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False );
4065 							if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
4066 								aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS );
4067 							else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
4068 								aGdiMetaFile.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
4069 							aGraf = aGdiMetaFile;
4070 						}
4071 						break;
4072 						default: break;
4073 					}
4074 				}
4075 			}
4076 		}
4077 
4078 		// sollte es ein OLE-Object sein?
4079 		if( bGrfRead && !bLinkGrf && IsProperty( DFF_Prop_pictureId ) )
4080         {
4081 			// TODO/LATER: in future probably the correct aspect should be provided here
4082 			sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
4083             // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method
4084             pRet = ImportOLE( GetPropertyValue( DFF_Prop_pictureId ), aGraf, rObjData.aBoundRect, aVisArea, rObjData.nCalledByGroup, nAspect );
4085             // <--
4086         }
4087 		if( !pRet )
4088 		{
4089 			pRet = new SdrGrafObj;
4090 			if( bGrfRead )
4091 				((SdrGrafObj*)pRet)->SetGraphic( aGraf );
4092 
4093 			if( bLinkGrf && !bGrfRead )		// sj: #i55484# if the graphic was embedded ( bGrfRead == true ) then
4094 			{								// we do not need to set a link. TODO: not to lose the information where the graphic is linked from
4095 				INetURLObject aAbsURL;
4096 				if ( !INetURLObject( maBaseURL ).GetNewAbsURL( ByteString( aFileName, RTL_TEXTENCODING_UTF8 ), &aAbsURL ) )
4097 				{
4098 		    		String aValidURL;
4099 			    	if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aFileName, aValidURL ) )
4100 				    	aAbsURL = INetURLObject( aValidURL );
4101 				}
4102 				if( aAbsURL.GetProtocol() != INET_PROT_NOT_VALID )
4103 				{
4104 					GraphicFilter* pGrfFilter = GraphicFilter::GetGraphicFilter();
4105 					aLinkFilterName = pGrfFilter->GetImportFormatName(
4106 					                pGrfFilter->GetImportFormatNumberForShortName( aAbsURL.getExtension() ) );
4107 					aLinkFileName = aAbsURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
4108 				}
4109 				else
4110 					aLinkFileName = aFileName;
4111 			}
4112 		}
4113 
4114 		// set the size from BLIP if there is one
4115 		if ( pRet && bGrfRead && !aVisArea.IsEmpty() )
4116 			pRet->SetBLIPSizeRectangle( aVisArea );
4117 
4118 		if ( !pRet->GetName().Len() )					// SJ 22.02.00 : PPT OLE IMPORT:
4119 		{												// name is already set in ImportOLE !!
4120 			// JP 01.12.99: SetName before SetModel - because in the other order the Bug 70098 is active
4121 			if ( ( eFlags & mso_blipflagType ) != mso_blipflagComment )
4122 			{
4123 				INetURLObject aURL;
4124 				aURL.SetSmartURL( aFileName );
4125 				pRet->SetName( aURL.getBase() );
4126 			}
4127 			else
4128 				pRet->SetName( aFileName );
4129 		}
4130 	}
4131 	pRet->SetModel( pSdrModel ); // fuer GraphicLink erforderlich
4132 	pRet->SetLogicRect( rObjData.aBoundRect );
4133 
4134 	if ( pRet->ISA( SdrGrafObj ) )
4135 	{
4136 		if( aLinkFileName.Len() )
4137 		    ((SdrGrafObj*)pRet)->SetGraphicLink( aLinkFileName, aLinkFilterName );
4138 
4139 		if ( bLinkGrf && !bGrfRead )
4140 		{
4141 			((SdrGrafObj*)pRet)->ForceSwapIn();
4142 			Graphic aGraf(((SdrGrafObj*)pRet)->GetGraphic());
4143 			lcl_ApplyCropping( *this, &rSet, aGraf );
4144 		}
4145 		((SdrGrafObj*)pRet)->ForceSwapOut();
4146 	}
4147 
4148 	return pRet;
4149 }
4150 
4151 // PptSlidePersistEntry& rPersistEntry, SdPage* pPage
4152 SdrObject* SvxMSDffManager::ImportObj( SvStream& rSt, void* pClientData,
4153     Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup, sal_Int32* pShapeId )
4154 {
4155     SdrObject* pRet = NULL;
4156     DffRecordHeader aObjHd;
4157     rSt >> aObjHd;
4158 	if ( aObjHd.nRecType == DFF_msofbtSpgrContainer )
4159 	{
4160 		pRet = ImportGroup( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4161     }
4162     else if ( aObjHd.nRecType == DFF_msofbtSpContainer )
4163 	{
4164 		pRet = ImportShape( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4165     }
4166     aObjHd.SeekToBegOfRecord( rSt );	// FilePos restaurieren
4167     return pRet;
4168 }
4169 
4170 SdrObject* SvxMSDffManager::ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4171                                             Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4172 												int nCalledByGroup, sal_Int32* pShapeId )
4173 {
4174 	SdrObject* pRet = NULL;
4175 
4176 	if( pShapeId )
4177 		*pShapeId = 0;
4178 
4179 	rHd.SeekToContent( rSt );
4180 	DffRecordHeader aRecHd;		// the first atom has to be the SpContainer for the GroupObject
4181     rSt >> aRecHd;
4182 	if ( aRecHd.nRecType == DFF_msofbtSpContainer )
4183 	{
4184 		sal_Int32 nGroupRotateAngle = 0;
4185 		sal_Int32 nSpFlags = 0;
4186 		mnFix16Angle = 0;
4187 		aRecHd.SeekToBegOfRecord( rSt );
4188 		pRet = ImportObj( rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup + 1, pShapeId );
4189 		if ( pRet )
4190 		{
4191 			nSpFlags = nGroupShapeFlags;
4192 			nGroupRotateAngle = mnFix16Angle;
4193 
4194 			Rectangle aClientRect( rClientRect );
4195 
4196 			Rectangle aGlobalChildRect;
4197 			if ( !nCalledByGroup || rGlobalChildRect.IsEmpty() )
4198 				aGlobalChildRect = GetGlobalChildAnchor( rHd, rSt, aClientRect );
4199 			else
4200 				aGlobalChildRect = rGlobalChildRect;
4201 
4202 			if ( ( nGroupRotateAngle > 4500 && nGroupRotateAngle <= 13500 )
4203 				|| ( nGroupRotateAngle > 22500 && nGroupRotateAngle <= 31500 ) )
4204 			{
4205 				sal_Int32 nHalfWidth = ( aClientRect.GetWidth() + 1 ) >> 1;
4206 				sal_Int32 nHalfHeight = ( aClientRect.GetHeight() + 1 ) >> 1;
4207 				Point aTopLeft( aClientRect.Left() + nHalfWidth - nHalfHeight,
4208 								aClientRect.Top() + nHalfHeight - nHalfWidth );
4209 				Size aNewSize( aClientRect.GetHeight(), aClientRect.GetWidth() );
4210 				Rectangle aNewRect( aTopLeft, aNewSize );
4211 				aClientRect = aNewRect;
4212 			}
4213 
4214 			// now importing the inner objects of the group
4215 			aRecHd.SeekToEndOfRecord( rSt );
4216 			while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4217 			{
4218 				DffRecordHeader aRecHd2;
4219 				rSt >> aRecHd2;
4220 				if ( aRecHd2.nRecType == DFF_msofbtSpgrContainer )
4221 				{
4222 					Rectangle aGroupClientAnchor, aGroupChildAnchor;
4223 					GetGroupAnchors( aRecHd2, rSt, aGroupClientAnchor, aGroupChildAnchor, aClientRect, aGlobalChildRect );
4224 					aRecHd2.SeekToBegOfRecord( rSt );
4225 					sal_Int32 nShapeId;
4226 					SdrObject* pTmp = ImportGroup( aRecHd2, rSt, pClientData, aGroupClientAnchor, aGroupChildAnchor, nCalledByGroup + 1, &nShapeId );
4227 					if ( pTmp )
4228 					{
4229 						((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4230 						if( nShapeId )
4231 							insertShapeId( nShapeId, pTmp );
4232 					}
4233 				}
4234 				else if ( aRecHd2.nRecType == DFF_msofbtSpContainer )
4235 				{
4236 					aRecHd2.SeekToBegOfRecord( rSt );
4237 					sal_Int32 nShapeId;
4238 					SdrObject* pTmp = ImportShape( aRecHd2, rSt, pClientData, aClientRect, aGlobalChildRect, nCalledByGroup + 1, &nShapeId );
4239 					if ( pTmp )
4240 					{
4241 						((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4242 						if( nShapeId )
4243 							insertShapeId( nShapeId, pTmp );
4244 					}
4245 				}
4246 				aRecHd2.SeekToEndOfRecord( rSt );
4247 			}
4248 
4249 	//		pRet->NbcSetSnapRect( aGroupBound );
4250 			if ( nGroupRotateAngle )
4251 			{
4252 				double a = nGroupRotateAngle * nPi180;
4253 				pRet->NbcRotate( aClientRect.Center(), nGroupRotateAngle, sin( a ), cos( a ) );
4254 			}
4255 			if ( nSpFlags & SP_FFLIPV )		// Vertikal gespiegelt?
4256 			{	// BoundRect in aBoundRect
4257 				Point aLeft( aClientRect.Left(), ( aClientRect.Top() + aClientRect.Bottom() ) >> 1 );
4258 				Point aRight( aLeft.X() + 1000, aLeft.Y() );
4259 				pRet->NbcMirror( aLeft, aRight );
4260 			}
4261 			if ( nSpFlags & SP_FFLIPH )		// Horizontal gespiegelt?
4262 			{	// BoundRect in aBoundRect
4263 				Point aTop( ( aClientRect.Left() + aClientRect.Right() ) >> 1, aClientRect.Top() );
4264 				Point aBottom( aTop.X(), aTop.Y() + 1000 );
4265 				pRet->NbcMirror( aTop, aBottom );
4266 			}
4267 		}
4268 	}
4269 	return pRet;
4270 }
4271 
4272 SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4273                                             Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4274 											int nCalledByGroup, sal_Int32* pShapeId )
4275 {
4276 	SdrObject* pRet = NULL;
4277 
4278 	if( pShapeId )
4279 		*pShapeId = 0;
4280 
4281 	rHd.SeekToBegOfRecord( rSt );
4282 	DffObjData aObjData( rHd, rClientRect, nCalledByGroup );
4283 	aObjData.bRotateTextWithShape = ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_EXCEL ) == 0;
4284 	maShapeRecords.Consume( rSt, sal_False );
4285 	if( maShapeRecords.SeekToContent( rSt,
4286 		DFF_msofbtUDefProp,
4287 		SEEK_FROM_BEGINNING ) )
4288 	{
4289 		sal_uInt32  nBytesLeft = maShapeRecords.Current()->nRecLen;
4290 		sal_uInt32	nUDData;
4291 		sal_uInt16  nPID;
4292 		while( 5 < nBytesLeft )
4293 		{
4294 			rSt >> nPID;
4295 			if ( rSt.GetError() != 0 )
4296 				break;
4297 			rSt >> nUDData;
4298 			if ( rSt.GetError() != 0 )
4299 				break;
4300 			if ( nPID == 447 ) //
4301 			{
4302 				mbRotateGranientFillWithAngle = nUDData & 0x20;
4303 				break;
4304 			}
4305 			nBytesLeft  -= 6;
4306 		}
4307 	}
4308 	aObjData.bShapeType = maShapeRecords.SeekToContent( rSt, DFF_msofbtSp, SEEK_FROM_BEGINNING );
4309 	if ( aObjData.bShapeType )
4310 	{
4311 		rSt >> aObjData.nShapeId
4312 			>> aObjData.nSpFlags;
4313 		aObjData.eShapeType = (MSO_SPT)maShapeRecords.Current()->nRecInstance;
4314 	}
4315 	else
4316 	{
4317 		aObjData.nShapeId = 0;
4318 		aObjData.nSpFlags = 0;
4319 		aObjData.eShapeType = mso_sptNil;
4320 	}
4321 
4322 	if( pShapeId )
4323 		*pShapeId = aObjData.nShapeId;
4324 
4325 	if ( mbTracing )
4326 		mpTracer->AddAttribute( aObjData.nSpFlags & SP_FGROUP
4327 								? rtl::OUString::createFromAscii( "GroupShape" )
4328 								: rtl::OUString::createFromAscii( "Shape" ),
4329 								rtl::OUString::valueOf( (sal_Int32)aObjData.nShapeId ) );
4330 	aObjData.bOpt = maShapeRecords.SeekToContent( rSt, DFF_msofbtOPT, SEEK_FROM_CURRENT_AND_RESTART );
4331 	if ( aObjData.bOpt )
4332 	{
4333         maShapeRecords.Current()->SeekToBegOfRecord( rSt );
4334 #ifdef DBG_AUTOSHAPE
4335 		ReadPropSet( rSt, pClientData, (sal_uInt32)aObjData.eShapeType );
4336 #else
4337 		ReadPropSet( rSt, pClientData );
4338 #endif
4339 	}
4340 	else
4341 	{
4342 		InitializePropSet( DFF_msofbtOPT );		// get the default PropSet
4343 		( (DffPropertyReader*) this )->mnFix16Angle = 0;
4344 	}
4345 	aObjData.bOpt2 = maShapeRecords.SeekToContent( rSt, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART );
4346 	if ( aObjData.bOpt2 )
4347 	{
4348 		maShapeRecords.Current()->SeekToBegOfRecord( rSt );
4349 		pSecPropSet = new DffPropertyReader( *this );
4350 		pSecPropSet->ReadPropSet( rSt, NULL );
4351 	}
4352 
4353 	aObjData.bChildAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtChildAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4354 	if ( aObjData.bChildAnchor )
4355 	{
4356         sal_Int32 l, o, r, u;
4357         rSt >> l >> o >> r >> u;
4358         Scale( l );
4359         Scale( o );
4360         Scale( r );
4361         Scale( u );
4362         aObjData.aChildAnchor = Rectangle( l, o, r, u );
4363 		if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
4364 		{
4365 			double fl = l;
4366 			double fo = o;
4367 			double fWidth = r - l;
4368 			double fHeight= u - o;
4369 			double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
4370 			double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
4371 			fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
4372 			fo = ( ( o - rGlobalChildRect.Top()  ) * fYScale ) + rClientRect.Top();
4373 			fWidth *= fXScale;
4374 			fHeight *= fYScale;
4375 			aObjData.aChildAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
4376 		}
4377 	}
4378 
4379 	aObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtClientAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4380 	if ( aObjData.bClientAnchor )
4381 		ProcessClientAnchor2( rSt, *maShapeRecords.Current(), pClientData, aObjData );
4382 
4383 	if ( aObjData.bChildAnchor )
4384 		aObjData.aBoundRect = aObjData.aChildAnchor;
4385 
4386 	if ( aObjData.nSpFlags & SP_FBACKGROUND )
4387 		aObjData.aBoundRect = Rectangle( Point(), Size( 1, 1 ) );
4388 
4389 	Rectangle aTextRect;
4390     if ( !aObjData.aBoundRect.IsEmpty() )
4391 	{	// Rotation auf BoundingBox anwenden, BEVOR ien Objekt generiert wurde
4392 		if( mnFix16Angle )
4393 		{
4394 			long nAngle = mnFix16Angle;
4395 			if ( ( nAngle > 4500 && nAngle <= 13500 ) || ( nAngle > 22500 && nAngle <= 31500 ) )
4396 			{
4397 				sal_Int32 nHalfWidth = ( aObjData.aBoundRect.GetWidth() + 1 ) >> 1;
4398 				sal_Int32 nHalfHeight = ( aObjData.aBoundRect.GetHeight() + 1 ) >> 1;
4399 				Point aTopLeft( aObjData.aBoundRect.Left() + nHalfWidth - nHalfHeight,
4400 								aObjData.aBoundRect.Top() + nHalfHeight - nHalfWidth );
4401 				Size aNewSize( aObjData.aBoundRect.GetHeight(), aObjData.aBoundRect.GetWidth() );
4402 				Rectangle aNewRect( aTopLeft, aNewSize );
4403 				aObjData.aBoundRect = aNewRect;
4404 			}
4405 		}
4406 		aTextRect = aObjData.aBoundRect;
4407 		FASTBOOL bGraphic = IsProperty( DFF_Prop_pib ) ||
4408 							IsProperty( DFF_Prop_pibName ) ||
4409 							IsProperty( DFF_Prop_pibFlags );
4410 
4411 		if ( aObjData.nSpFlags & SP_FGROUP )
4412 		{
4413 			pRet = new SdrObjGroup;
4414             /*  After CWS aw033 has been integrated, an empty group object
4415                 cannot store its resulting bounding rectangle anymore. We have
4416                 to return this rectangle via rClientRect now, but only, if
4417                 caller has not passed an own bounding ractangle. */
4418             if ( rClientRect.IsEmpty() )
4419                  rClientRect = aObjData.aBoundRect;
4420 			nGroupShapeFlags = aObjData.nSpFlags;		// #73013#
4421 		}
4422 		else if ( ( aObjData.eShapeType != mso_sptNil ) || IsProperty( DFF_Prop_pVertices ) || bGraphic )
4423 		{
4424 			SfxItemSet	aSet( pSdrModel->GetItemPool() );
4425 
4426 			sal_Bool	bIsConnector = ( ( aObjData.eShapeType >= mso_sptStraightConnector1 ) && ( aObjData.eShapeType <= mso_sptCurvedConnector5 ) );
4427 			sal_Bool	bIsCustomShape = sal_False;
4428 			sal_Int32	nObjectRotation = mnFix16Angle;
4429 			sal_uInt32	nSpFlags = aObjData.nSpFlags;
4430 
4431 			if ( bGraphic )
4432 			{
4433 				pRet = ImportGraphic( rSt, aSet, aObjData );		// SJ: #68396# is no longer true (fixed in ppt2000)
4434 				ApplyAttributes( rSt, aSet, aObjData );
4435 				pRet->SetMergedItemSet(aSet);
4436 			}
4437 			else if ( aObjData.eShapeType == mso_sptLine && !( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 8 ) )
4438 			{
4439 				basegfx::B2DPolygon aPoly;
4440 				aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Left(), aObjData.aBoundRect.Top()));
4441 				aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Right(), aObjData.aBoundRect.Bottom()));
4442 				pRet = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly));
4443 				pRet->SetModel( pSdrModel );
4444 				ApplyAttributes( rSt, aSet, aObjData );
4445 				pRet->SetMergedItemSet(aSet);
4446 			}
4447 			else
4448 			{
4449 				if ( GetCustomShapeContent( aObjData.eShapeType ) || IsProperty( DFF_Prop_pVertices ) )
4450 				{
4451 
4452 					ApplyAttributes( rSt, aSet, aObjData );
4453 
4454 // the com.sun.star.drawing.EnhancedCustomShapeEngine is default, so we do not need to set a hard attribute
4455 //						aSet.Put( SdrCustomShapeEngineItem( String::CreateFromAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) );
4456 					pRet = new SdrObjCustomShape();
4457 					pRet->SetModel( pSdrModel );
4458 
4459 					sal_Bool bIsFontwork = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) != 0;
4460 
4461 					// in case of a FontWork, the text is set by the escher import
4462 					if ( bIsFontwork )
4463 					{
4464 						String				aObjectText;
4465 						String				aFontName;
4466 						MSO_GeoTextAlign	eGeoTextAlign;
4467 
4468 						if ( SeekToContent( DFF_Prop_gtextFont, rSt ) )
4469 						{
4470                             SvxFontItem aLatin(EE_CHAR_FONTINFO), aAsian(EE_CHAR_FONTINFO_CJK), aComplex(EE_CHAR_FONTINFO_CTL);
4471 							GetDefaultFonts( aLatin, aAsian, aComplex );
4472 
4473 							MSDFFReadZString( rSt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), sal_True );
4474                             aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4475                                         PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
4476 							aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4477 										PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CJK ) );
4478 							aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4479 										PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CTL ) );
4480 						}
4481 
4482 						// SJ: applying fontattributes for Fontwork :
4483 						if ( IsHardAttribute( DFF_Prop_gtextFItalic ) )
4484                             aSet.Put( SvxPostureItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0010 ) != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
4485 
4486 						if ( IsHardAttribute( DFF_Prop_gtextFBold ) )
4487                             aSet.Put( SvxWeightItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0020 ) != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
4488 
4489 						// SJ TODO: Vertical Writing is not correct, instead this should be
4490 						// replaced through "CharacterRotation" by 90? therefore a new Item has to be
4491 						// supported by svx core, api and xml file format
4492 						((SdrObjCustomShape*)pRet)->SetVerticalWriting( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) != 0 );
4493 
4494 						if ( SeekToContent( DFF_Prop_gtextUNICODE, rSt ) )
4495 						{
4496 							MSDFFReadZString( rSt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), sal_True );
4497 							ReadObjText( aObjectText, pRet );
4498 						}
4499 
4500 						eGeoTextAlign = ( (MSO_GeoTextAlign)GetPropertyValue( DFF_Prop_gtextAlign, mso_alignTextCenter ) );
4501 						{
4502 							SdrTextHorzAdjust eHorzAdjust;
4503 							switch( eGeoTextAlign )
4504 							{
4505 								case mso_alignTextLetterJust :
4506 								case mso_alignTextWordJust :
4507 								case mso_alignTextStretch : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break;
4508 								default:
4509 								case mso_alignTextInvalid :
4510 								case mso_alignTextCenter : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break;
4511 								case mso_alignTextLeft : eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break;
4512 								case mso_alignTextRight : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break;
4513 							}
4514 							aSet.Put( SdrTextHorzAdjustItem( eHorzAdjust ) );
4515 
4516 							SdrFitToSizeType eFTS = SDRTEXTFIT_NONE;
4517 							if ( eGeoTextAlign == mso_alignTextStretch )
4518 								eFTS = SDRTEXTFIT_ALLLINES;
4519 							aSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
4520 						}
4521 						if ( IsProperty( DFF_Prop_gtextSpacing ) )
4522 						{
4523 							sal_Int32 nTextWidth = GetPropertyValue( DFF_Prop_gtextSpacing, 100 < 16 ) / 655;
4524 							if ( nTextWidth != 100 )
4525 								aSet.Put( SvxCharScaleWidthItem( (sal_uInt16)nTextWidth, EE_CHAR_FONTWIDTH ) );
4526 						}
4527 						if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x1000 )	// SJ: Font Kerning On ?
4528 							aSet.Put( SvxKerningItem( 1, EE_CHAR_KERNING ) );
4529 
4530                         // #119496# the resize autoshape to fit text attr of word art in MS PPT is always false
4531 						aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) );
4532 						aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
4533 					}
4534                     pRet->SetMergedItemSet( aSet );
4535 
4536 					// sj: taking care of rtl, ltr. In case of fontwork mso. seems not to be able to set
4537 					// proper text directions, instead the text default is depending to the string.
4538 					// so we have to calculate the a text direction from string:
4539 					if ( bIsFontwork )
4540 					{
4541 						OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pRet)->GetOutlinerParaObject();
4542 						if ( pParaObj )
4543 						{
4544 							SdrOutliner& rOutliner = ((SdrObjCustomShape*)pRet)->ImpGetDrawOutliner();
4545 							sal_Bool bOldUpdateMode = rOutliner.GetUpdateMode();
4546 							SdrModel* pModel = pRet->GetModel();
4547 							if ( pModel )
4548 								rOutliner.SetStyleSheetPool( (SfxStyleSheetPool*)pModel->GetStyleSheetPool() );
4549 							rOutliner.SetUpdateMode( sal_False );
4550 							rOutliner.SetText( *pParaObj );
4551 							VirtualDevice aVirDev( 1 );
4552 							aVirDev.SetMapMode( MAP_100TH_MM );
4553 							sal_uInt32 i, nParagraphs = rOutliner.GetParagraphCount();
4554 							if ( nParagraphs )
4555 							{
4556 								sal_Bool bCreateNewParaObject = sal_False;
4557 								for ( i = 0; i < nParagraphs; i++ )
4558 								{
4559 									sal_Bool bIsRTL = aVirDev.GetTextIsRTL( rOutliner.GetText( rOutliner.GetParagraph( i ) ), 0, STRING_LEN );
4560 									if ( bIsRTL )
4561 									{
4562 										SfxItemSet aSet2( rOutliner.GetParaAttribs( (sal_uInt16)i ) );
4563 										aSet2.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
4564 										rOutliner.SetParaAttribs( (sal_uInt16)i, aSet2 );
4565 										bCreateNewParaObject = sal_True;
4566 									}
4567 								}
4568 								if  ( bCreateNewParaObject )
4569 								{
4570 									OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
4571 									rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
4572 									((SdrObjCustomShape*)pRet)->NbcSetOutlinerParaObject( pNewText );
4573 								}
4574 							}
4575 					        rOutliner.Clear();
4576 							rOutliner.SetUpdateMode( bOldUpdateMode );
4577 						}
4578 					}
4579 
4580 					// mso_sptArc special treating:
4581 					// sj: since we actually can't render the arc because of its weird SnapRect settings,
4582 					// we will create a new CustomShape, that can be saved/loaded without problems.
4583 					// We will change the shape type, so this code applys only if importing arcs from msoffice.
4584 					if ( aObjData.eShapeType == mso_sptArc )
4585 					{
4586 						const rtl::OUString	sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
4587 						const rtl::OUString	sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
4588 						const rtl::OUString	sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
4589 						const rtl::OUString	sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
4590 						const rtl::OUString	sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
4591 						const rtl::OUString	sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
4592 						const rtl::OUString	sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
4593 						SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
4594 						com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
4595 						com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
4596 
4597 						// before clearing the GeometryItem we have to store the current Coordinates
4598 						const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
4599 						Rectangle aPolyBoundRect;
4600 						Point aStartPt( 0,0 );
4601 						if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) )
4602 						{
4603 							sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength();
4604 							XPolygon aXP( (sal_uInt16)nNumElemVert );
4605 //								const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
4606 							for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ )
4607 							{
4608 								Point aP;
4609 								sal_Int32 nX = 0, nY = 0;
4610 								seqCoordinates[ nPtNum ].First.Value >>= nX;
4611 								seqCoordinates[ nPtNum ].Second.Value >>= nY;
4612 								aP.X() = nX;
4613 								aP.Y() = nY;
4614 								aXP[ (sal_uInt16)nPtNum ] = aP;
4615 							}
4616 							aPolyBoundRect = Rectangle( aXP.GetBoundRect() );
4617 							if ( nNumElemVert >= 3 )
4618 							{ // arc first command is always wr -- clockwise arc
4619 								// the parameters are : (left,top),(right,bottom),start(x,y),end(x,y)
4620 								aStartPt = aXP[2];
4621 							}
4622 						}
4623 						else
4624 							aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 );	// defaulting
4625 
4626 						// clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry
4627 						aGeometryItem.ClearPropertyValue( sHandles );
4628 						aGeometryItem.ClearPropertyValue( sEquations );
4629 						aGeometryItem.ClearPropertyValue( sViewBox );
4630 						aGeometryItem.ClearPropertyValue( sPath );
4631 
4632 						sal_Int32 nEndAngle = 9000;
4633 						sal_Int32 nStartAngle = 0;
4634 						pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
4635 						if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 )
4636 						{
4637 							double fNumber;
4638 							if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
4639 							{
4640 								seqAdjustmentValues[ 0 ].Value >>= fNumber;
4641 								nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4642 							}
4643 							else
4644 							{
4645 								fNumber = 270.0;
4646 								//normal situation:if endAngle != 90,there will be a direct_value,but for damaged curve,the endAngle need to recalculate.
4647 								Point cent = aPolyBoundRect.Center();
4648 								if ( aStartPt.Y() == cent.Y() )
4649 									fNumber = ( aStartPt.X() >= cent.X() ) ? 0:180.0;
4650 								else if ( aStartPt.X() == cent.X() )
4651 									fNumber = ( aStartPt.Y() >= cent.Y() ) ? 90.0: 270.0;
4652 								else
4653 								{
4654 									fNumber = atan2( double( aStartPt.X() - cent.X() ),double( aStartPt.Y() - cent.Y() ) )+ F_PI; // 0..2PI
4655 									fNumber /= F_PI180; // 0..360.0
4656 								}
4657 								nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4658 								seqAdjustmentValues[ 0 ].Value <<= fNumber;
4659 								seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;		// so this value will properly be stored
4660 							}
4661 
4662 							if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
4663 							{
4664 								seqAdjustmentValues[ 1 ].Value >>= fNumber;
4665 								nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4666 							}
4667 							else
4668 							{
4669 								fNumber = 0.0;
4670 								seqAdjustmentValues[ 1 ].Value <<= fNumber;
4671 								seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
4672 							}
4673 
4674 							PropertyValue aPropVal;
4675 							aPropVal.Name = sAdjustmentValues;
4676 							aPropVal.Value <<= seqAdjustmentValues;
4677 							aGeometryItem.SetPropertyValue( aPropVal );		// storing the angle attribute
4678 						}
4679 						if ( nStartAngle != nEndAngle )
4680 						{
4681 							XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2,
4682 								(sal_uInt16)nStartAngle / 10, (sal_uInt16)nEndAngle / 10, sal_True );
4683 							Rectangle aPolyPieRect( aXPoly.GetBoundRect() );
4684 
4685 							double	fYScale, fXScale;
4686 							double	fYOfs, fXOfs;
4687 
4688 							Point aP( aObjData.aBoundRect.Center() );
4689 							Size aS( aObjData.aBoundRect.GetSize() );
4690 							aP.X() -= aS.Width() / 2;
4691 							aP.Y() -= aS.Height() / 2;
4692 							Rectangle aLogicRect( aP, aS );
4693 
4694 							fYOfs = fXOfs = 0.0;
4695 
4696 							if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() )
4697 							{
4698 								fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth();
4699 								if ( nSpFlags & SP_FFLIPH )
4700 									fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale;
4701 								else
4702 									fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale;
4703 							}
4704 							if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() )
4705 							{
4706 								fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight();
4707 								if ( nSpFlags & SP_FFLIPV )
4708 									fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale;
4709 								else
4710 									fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale;
4711 							}
4712 
4713 							fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth();
4714 							fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight();
4715 
4716 							Rectangle aOldBoundRect( aObjData.aBoundRect );
4717 							aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ),
4718 							 	Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) );
4719 
4720 							// creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system
4721 							double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth();
4722 							double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight();
4723 							sal_Int32 nLeft  = (sal_Int32)(( aPolyPieRect.Left()  - aPolyBoundRect.Left() ) * fTextFrameScaleX );
4724 							sal_Int32 nTop   = (sal_Int32)(( aPolyPieRect.Top()   - aPolyBoundRect.Top() )  * fTextFrameScaleY );
4725 							sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
4726 							sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() )  * fTextFrameScaleY );
4727 							com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 );
4728 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First,	   nLeft );
4729 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second,    nTop );
4730 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight );
4731 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom );
4732 							PropertyValue aProp;
4733 							aProp.Name = sTextFrames;
4734 							aProp.Value <<= aTextFrame;
4735 							aGeometryItem.SetPropertyValue( sPath, aProp );
4736 
4737 							// sj: taking care of the different rotation points, since the new arc is having a bigger snaprect
4738 							if ( mnFix16Angle )
4739 							{
4740 								sal_Int32 nAngle = mnFix16Angle;
4741 								if ( nSpFlags & SP_FFLIPH )
4742 									nAngle = 36000 - nAngle;
4743 								if ( nSpFlags & SP_FFLIPV )
4744 									nAngle = -nAngle;
4745 								double a = nAngle * F_PI18000;
4746 								double ss = sin( a );
4747 								double cc = cos( a );
4748 								Point aP1( aOldBoundRect.TopLeft() );
4749 								Point aC1( aObjData.aBoundRect.Center() );
4750 								Point aP2( aOldBoundRect.TopLeft() );
4751 								Point aC2( aOldBoundRect.Center() );
4752 								RotatePoint( aP1, aC1, ss, cc );
4753 								RotatePoint( aP2, aC2, ss, cc );
4754 								aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() );
4755 							}
4756 						}
4757 						((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem );
4758 						((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
4759 
4760 						// now setting a new name, so the above correction is only done once when importing from ms
4761 						SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
4762 						const rtl::OUString	sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
4763 						const rtl::OUString	sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) );
4764 						PropertyValue aPropVal;
4765 						aPropVal.Name = sType;
4766 						aPropVal.Value <<= sName;
4767 						aGeoName.SetPropertyValue( aPropVal );
4768 						((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName );
4769 					}
4770 					else
4771 						((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
4772 
4773 					pRet->SetSnapRect( aObjData.aBoundRect );
4774 					EnhancedCustomShape2d aCustomShape2d( pRet );
4775 					aTextRect = aCustomShape2d.GetTextRect();
4776 
4777 					bIsCustomShape = sal_True;
4778 
4779 					if( bIsConnector )
4780 					{
4781 						if( nObjectRotation )
4782 						{
4783 							double a = nObjectRotation * nPi180;
4784 							pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
4785 						}
4786 						// Horizontal gespiegelt?
4787 						if ( nSpFlags & SP_FFLIPH )
4788 						{
4789 							Rectangle aBndRect( pRet->GetSnapRect() );
4790 							Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
4791 							Point aBottom( aTop.X(), aTop.Y() + 1000 );
4792 							pRet->NbcMirror( aTop, aBottom );
4793 						}
4794 						// Vertikal gespiegelt?
4795 						if ( nSpFlags & SP_FFLIPV )
4796 						{
4797 							Rectangle aBndRect( pRet->GetSnapRect() );
4798 							Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
4799 							Point aRight( aLeft.X() + 1000, aLeft.Y() );
4800 							pRet->NbcMirror( aLeft, aRight );
4801 						}
4802 						basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) );
4803                         SdrObject::Free( pRet );
4804 
4805 						pRet = new SdrEdgeObj();
4806 						ApplyAttributes( rSt, aSet, aObjData );
4807 						pRet->SetLogicRect( aObjData.aBoundRect );
4808 						pRet->SetMergedItemSet(aSet);
4809 
4810 						// Konnektoren
4811 						MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight );
4812 
4813 						((SdrEdgeObj*)pRet)->ConnectToNode(sal_True, NULL);
4814 						((SdrEdgeObj*)pRet)->ConnectToNode(sal_False, NULL);
4815 
4816 						Point aPoint1( aObjData.aBoundRect.TopLeft() );
4817 						Point aPoint2( aObjData.aBoundRect.BottomRight() );
4818 
4819 						// Rotationen beachten
4820 						if ( nObjectRotation )
4821 						{
4822 							double a = nObjectRotation * nPi180;
4823 							Point aCenter( aObjData.aBoundRect.Center() );
4824 							double ss = sin(a);
4825 							double cc = cos(a);
4826 
4827 							RotatePoint(aPoint1, aCenter, ss, cc);
4828 							RotatePoint(aPoint2, aCenter, ss, cc);
4829 
4830                             // #120437# reset rotation, it is part of the path and shall not be applied again
4831                             nObjectRotation = 0;
4832 						}
4833 
4834 						// Linie innerhalb des Bereiches zurechtdrehen/spiegeln
4835 						if ( nSpFlags & SP_FFLIPH )
4836 						{
4837 							sal_Int32 n = aPoint1.X();
4838 							aPoint1.X() = aPoint2.X();
4839 							aPoint2.X() = n;
4840 
4841                             // #120437# reset hor filp
4842                             nSpFlags &= ~SP_FFLIPH;
4843 						}
4844 						if ( nSpFlags & SP_FFLIPV )
4845 						{
4846 							sal_Int32 n = aPoint1.Y();
4847 							aPoint1.Y() = aPoint2.Y();
4848 							aPoint2.Y() = n;
4849 
4850                             // #120437# reset ver filp
4851                             nSpFlags &= ~SP_FFLIPV;
4852 						}
4853 
4854 						pRet->NbcSetPoint(aPoint1, 0L);	// Startpunkt
4855 						pRet->NbcSetPoint(aPoint2, 1L);	// Endpunkt
4856 
4857 						sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist;
4858 						n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0;
4859 						switch( eConnectorStyle )
4860 						{
4861 							case mso_cxstyleBent:
4862 							{
4863 								aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) );
4864 								n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630;
4865 							}
4866 							break;
4867 							case mso_cxstyleCurved:
4868 								aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) );
4869 							break;
4870 							default: // mso_cxstyleStraight || mso_cxstyleNone
4871 								aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) );
4872 							break;
4873 						}
4874 						aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) );
4875 						aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) );
4876 						aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) );
4877 						aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) );
4878 
4879 						((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly );
4880 						pRet->SetMergedItemSet( aSet );
4881 					}
4882 					if ( aObjData.eShapeType == mso_sptLine )
4883 					{
4884 						pRet->SetMergedItemSet(aSet);
4885 						((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
4886 					}
4887 				}
4888 			}
4889 
4890 			if ( pRet )
4891 			{
4892 				if( nObjectRotation )
4893 				{
4894 					double a = nObjectRotation * nPi180;
4895 					pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
4896 				}
4897 				// Horizontal gespiegelt?
4898 				if ( nSpFlags & SP_FFLIPH )
4899 				{
4900 					Rectangle aBndRect( pRet->GetSnapRect() );
4901 					Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
4902 					Point aBottom( aTop.X(), aTop.Y() + 1000 );
4903 					pRet->NbcMirror( aTop, aBottom );
4904 				}
4905 				// Vertikal gespiegelt?
4906 				if ( nSpFlags & SP_FFLIPV )
4907 				{
4908 					Rectangle aBndRect( pRet->GetSnapRect() );
4909 					Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
4910 					Point aRight( aLeft.X() + 1000, aLeft.Y() );
4911 					pRet->NbcMirror( aLeft, aRight );
4912 				}
4913 			}
4914 		}
4915 	}
4916 
4917     // #i51348# #118052# name of the shape
4918     if( pRet )
4919     {
4920         ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt );
4921         if( aObjName.getLength() > 0 )
4922             pRet->SetName( aObjName );
4923     }
4924 
4925 	pRet =
4926 		ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet);
4927 
4928 	if ( pRet )
4929 	{
4930 		sal_Int32 nGroupProperties( GetPropertyValue( DFF_Prop_fPrint ) );
4931 		pRet->SetVisible( ( nGroupProperties & 2 ) == 0 );
4932 		pRet->SetPrintable( ( nGroupProperties & 1 ) != 0 );
4933 	}
4934 
4935 	if ( mbTracing )
4936 		mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP
4937 									? rtl::OUString::createFromAscii( "GroupShape" )
4938 									: rtl::OUString::createFromAscii( "Shape" ) );
4939     //Import alt text as description
4940 	if ( pRet && SeekToContent( DFF_Prop_wzDescription, rSt ) )
4941 	{
4942 		String aAltText;
4943 		MSDFFReadZString( rSt, aAltText, GetPropertyValue( DFF_Prop_wzDescription ), sal_True );
4944 		pRet->SetDescription( aAltText );
4945 	}
4946 
4947 	return pRet;
4948 }
4949 
4950 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect )
4951 {
4952 	Rectangle aChildAnchor;
4953 	rHd.SeekToContent( rSt );
4954 	sal_Bool bIsClientRectRead = sal_False;
4955 	while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4956 	{
4957 		DffRecordHeader aShapeHd;
4958 		rSt >> aShapeHd;
4959 		if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
4960 				( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
4961 		{
4962 			DffRecordHeader aShapeHd2( aShapeHd );
4963 			if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
4964 				rSt >> aShapeHd2;
4965 			while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
4966 			{
4967 				DffRecordHeader aShapeAtom;
4968 				rSt >> aShapeAtom;
4969 
4970 				if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor )
4971 				{
4972 					if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT )
4973 					{
4974 						sal_Int32 l, t, r, b;
4975 						if ( aShapeAtom.nRecLen == 16 )
4976 						{
4977 							rSt >> l >> t >> r >> b;
4978 						}
4979 						else
4980 						{
4981 							sal_Int16 ls, ts, rs, bs;
4982 							rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ...
4983 							l = ls, t = ts, r = rs, b = bs;
4984 						}
4985 						Scale( l );
4986 						Scale( t );
4987 						Scale( r );
4988 						Scale( b );
4989 						if ( bIsClientRectRead )
4990 						{
4991 							Rectangle aChild( l, t, r, b );
4992 							aChildAnchor.Union( aChild );
4993 						}
4994 						else
4995 						{
4996 							aClientRect = Rectangle( l, t, r, b );
4997 							bIsClientRectRead = sal_True;
4998 						}
4999 					}
5000 					break;
5001 				}
5002 				else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
5003 				{
5004 					sal_Int32 l, o, r, u;
5005 					rSt >> l >> o >> r >> u;
5006 					Scale( l );
5007 					Scale( o );
5008 					Scale( r );
5009 					Scale( u );
5010 					Rectangle aChild( l, o, r, u );
5011 					aChildAnchor.Union( aChild );
5012 					break;
5013 				}
5014 				aShapeAtom.SeekToEndOfRecord( rSt );
5015 			}
5016 		}
5017 		aShapeHd.SeekToEndOfRecord( rSt );
5018 	}
5019 	return aChildAnchor;
5020 }
5021 
5022 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt,
5023 							Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor,
5024 								const Rectangle& rClientRect, const Rectangle& rGlobalChildRect )
5025 {
5026 	sal_Bool bFirst = sal_True;
5027 	rHd.SeekToContent( rSt );
5028 	DffRecordHeader aShapeHd;
5029 	while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
5030 	{
5031 		rSt >> aShapeHd;
5032 		if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
5033 				( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
5034 		{
5035 			DffRecordHeader aShapeHd2( aShapeHd );
5036 			if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
5037 				rSt >> aShapeHd2;
5038 			while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
5039 			{
5040 				DffRecordHeader aShapeAtom;
5041 				rSt >> aShapeAtom;
5042 				if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
5043 				{
5044 					sal_Int32 l, o, r, u;
5045 					rSt >> l >> o >> r >> u;
5046 					Scale( l );
5047 					Scale( o );
5048 					Scale( r );
5049 					Scale( u );
5050 					Rectangle aChild( l, o, r, u );
5051 
5052 					if ( bFirst )
5053 					{
5054 						if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
5055 						{
5056 							double fl = l;
5057 							double fo = o;
5058 							double fWidth = r - l;
5059 							double fHeight= u - o;
5060 							double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
5061 							double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
5062 							fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
5063 							fo = ( ( o - rGlobalChildRect.Top()  ) * fYScale ) + rClientRect.Top();
5064 							fWidth *= fXScale;
5065 							fHeight *= fYScale;
5066 							rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
5067 						}
5068 						bFirst = sal_False;
5069 					}
5070 					else
5071 						rGroupChildAnchor.Union( aChild );
5072 					break;
5073 				}
5074 				aShapeAtom.SeekToEndOfRecord( rSt );
5075 			}
5076 		}
5077 		aShapeHd.SeekToEndOfRecord( rSt );
5078 	}
5079 }
5080 
5081 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt,
5082 									   DffObjData& rObjData,
5083 									   void* pData,
5084 									   Rectangle& rTextRect,
5085 									   SdrObject* pObj
5086 									   )
5087 {
5088 	if( !rTextRect.IsEmpty() )
5089 	{
5090 		SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
5091 		SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
5092 		SvxMSDffImportRec* pTextImpRec = pImpRec;
5093 
5094 		// fill Import Record with data
5095 		pImpRec->nShapeId   = rObjData.nShapeId;
5096 		pImpRec->eShapeType = rObjData.eShapeType;
5097 
5098 		MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue(
5099 															DFF_Prop_WrapText,
5100 															mso_wrapSquare ) );
5101 		rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
5102 											DFF_msofbtClientAnchor,
5103 											SEEK_FROM_CURRENT_AND_RESTART );
5104 		if( rObjData.bClientAnchor )
5105 			ProcessClientAnchor( rSt,
5106 					maShapeRecords.Current()->nRecLen,
5107 					pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
5108 
5109 		rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
5110 											DFF_msofbtClientData,
5111 											SEEK_FROM_CURRENT_AND_RESTART );
5112 		if( rObjData.bClientData )
5113 			ProcessClientData( rSt,
5114 					maShapeRecords.Current()->nRecLen,
5115 					pImpRec->pClientDataBuffer, pImpRec->nClientDataLen );
5116 
5117 
5118 		// process user (== Winword) defined parameters in 0xF122 record
5119 		if(    maShapeRecords.SeekToContent( rSt,
5120 											 DFF_msofbtUDefProp,
5121 											 SEEK_FROM_CURRENT_AND_RESTART )
5122 			&& maShapeRecords.Current()->nRecLen )
5123 		{
5124 			sal_uInt32  nBytesLeft = maShapeRecords.Current()->nRecLen;
5125 			sal_uInt32	nUDData;
5126 			sal_uInt16  nPID;
5127 			while( 5 < nBytesLeft )
5128 			{
5129 				rSt >> nPID;
5130 				if ( rSt.GetError() != 0 )
5131 					break;
5132 				rSt >> nUDData;
5133 				switch( nPID )
5134 				{
5135 					case 0x038F: pImpRec->nXAlign = nUDData; break;
5136 					case 0x0390: pImpRec->nXRelTo = nUDData; break;
5137 					case 0x0391: pImpRec->nYAlign = nUDData; break;
5138 					case 0x0392: pImpRec->nYRelTo = nUDData; break;
5139                     case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break;
5140 				}
5141 				if ( rSt.GetError() != 0 )
5142 					break;
5143 				pImpRec->bHasUDefProp = sal_True;
5144 				nBytesLeft  -= 6;
5145 			}
5146 		}
5147 
5148 		//  Textrahmen, auch Title oder Outline
5149 		SdrObject*  pOrgObj  = pObj;
5150 		SdrRectObj* pTextObj = 0;
5151 		sal_uInt32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
5152 		if( nTextId )
5153 		{
5154 			SfxItemSet aSet( pSdrModel->GetItemPool() );
5155 
5156             //Originally anything that as a mso_sptTextBox was created as a
5157             //textbox, this was changed for #88277# to be created as a simple
5158             //rect to keep impress happy. For the rest of us we'd like to turn
5159             //it back into a textbox again.
5160             FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox);
5161             if (!bTextFrame)
5162             {
5163                 //Either
5164                 //a) its a simple text object or
5165                 //b) its a rectangle with text and square wrapping.
5166                 bTextFrame =
5167                 (
5168                     (pImpRec->eShapeType == mso_sptTextSimple) ||
5169                     (
5170                         (pImpRec->eShapeType == mso_sptRectangle)
5171                         && (eWrapMode == mso_wrapSquare)
5172                         && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
5173                     )
5174                 );
5175             }
5176 
5177             if (bTextFrame)
5178             {
5179                 SdrObject::Free( pObj );
5180                 pObj = pOrgObj = 0;
5181             }
5182 
5183             // Distance of Textbox to it's surrounding Customshape
5184 			sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
5185 			sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
5186 			sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L  );
5187 			sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
5188 
5189 			ScaleEmu( nTextLeft );
5190 			ScaleEmu( nTextRight );
5191 			ScaleEmu( nTextTop );
5192 			ScaleEmu( nTextBottom );
5193 
5194             sal_Int32 nTextRotationAngle=0;
5195             bool bVerticalText = false;
5196             if ( IsProperty( DFF_Prop_txflTextFlow ) )
5197             {
5198                 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue(
5199                     DFF_Prop_txflTextFlow) & 0xFFFF);
5200                 switch( eTextFlow )
5201                 {
5202                     case mso_txflBtoT:
5203                         nTextRotationAngle = 9000;
5204                     break;
5205                     case mso_txflVertN:
5206                     case mso_txflTtoBN:
5207                         nTextRotationAngle = 27000;
5208                         break;
5209                     case mso_txflTtoBA:
5210                         bVerticalText = true;
5211                     break;
5212                     case mso_txflHorzA:
5213                         bVerticalText = true;
5214                         nTextRotationAngle = 9000;
5215                     case mso_txflHorzN:
5216                     default :
5217                         break;
5218                 }
5219             }
5220 
5221             if (nTextRotationAngle)
5222 			{
5223                 while (nTextRotationAngle > 360000)
5224                     nTextRotationAngle-=9000;
5225                 switch (nTextRotationAngle)
5226                 {
5227                     case 9000:
5228                         {
5229                             long nWidth = rTextRect.GetWidth();
5230                             rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5231                             rTextRect.Bottom() = rTextRect.Top() + nWidth;
5232 
5233                             sal_Int32 nOldTextLeft = nTextLeft;
5234                             sal_Int32 nOldTextRight = nTextRight;
5235                             sal_Int32 nOldTextTop = nTextTop;
5236                             sal_Int32 nOldTextBottom = nTextBottom;
5237 
5238                             nTextLeft = nOldTextBottom;
5239                             nTextRight = nOldTextTop;
5240                             nTextTop = nOldTextLeft;
5241                             nTextBottom = nOldTextRight;
5242                         }
5243                         break;
5244                     case 27000:
5245                         {
5246                             long nWidth = rTextRect.GetWidth();
5247                             rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5248                             rTextRect.Bottom() = rTextRect.Top() + nWidth;
5249 
5250                             sal_Int32 nOldTextLeft = nTextLeft;
5251                             sal_Int32 nOldTextRight = nTextRight;
5252                             sal_Int32 nOldTextTop = nTextTop;
5253                             sal_Int32 nOldTextBottom = nTextBottom;
5254 
5255                             nTextLeft = nOldTextTop;
5256                             nTextRight = nOldTextBottom;
5257                             nTextTop = nOldTextRight;
5258                             nTextBottom = nOldTextLeft;
5259                         }
5260                         break;
5261                     default:
5262                         break;
5263                 }
5264 			}
5265 
5266             pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect);
5267             pTextImpRec = new SvxMSDffImportRec(*pImpRec);
5268 
5269             // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
5270             // hier rausrechnen
5271             Rectangle aNewRect(rTextRect);
5272 			aNewRect.Bottom() -= nTextTop + nTextBottom;
5273             aNewRect.Right() -= nTextLeft + nTextRight;
5274 
5275 			// Nur falls es eine einfache Textbox ist, darf der Writer
5276 			// das Objekt durch einen Rahmen ersetzen, ansonsten
5277 			if( bTextFrame )
5278 			{
5279 				SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId );
5280 				aTmpRec.bSortByShapeId = sal_True;
5281 
5282 				sal_uInt16 nFound;
5283 				if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) )
5284 				{
5285 					SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound);
5286 					pTextImpRec->bReplaceByFly   = rInfo.bReplaceByFly;
5287 					pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain;
5288 				}
5289 			}
5290 
5291 			if( !pObj )
5292 				ApplyAttributes( rSt, aSet, rObjData );
5293 
5294             bool bFitText = false;
5295             if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2)
5296             {
5297                 aSet.Put( SdrTextAutoGrowHeightItem( sal_True ) );
5298                 aSet.Put( SdrTextMinFrameHeightItem(
5299                     aNewRect.Bottom() - aNewRect.Top() ) );
5300                 aSet.Put( SdrTextMinFrameWidthItem(
5301                     aNewRect.Right() - aNewRect.Left() ) );
5302                 bFitText = true;
5303             }
5304             else
5305             {
5306                 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) );
5307                 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
5308             }
5309 
5310 			switch ( (MSO_WrapMode)
5311                 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) )
5312 			{
5313 				case mso_wrapNone :
5314     				aSet.Put( SdrTextAutoGrowWidthItem( sal_True ) );
5315                     if (bFitText)
5316                     {
5317                         //can't do autowidth in flys #i107184#
5318 					    pTextImpRec->bReplaceByFly = false;
5319                     }
5320 				break;
5321 				case mso_wrapByPoints :
5322 					aSet.Put( SdrTextContourFrameItem( sal_True ) );
5323 				break;
5324 				default: break;
5325 			}
5326 
5327 			// Abstaende an den Raendern der Textbox setzen
5328 			aSet.Put( SdrTextLeftDistItem( nTextLeft ) );
5329 			aSet.Put( SdrTextRightDistItem( nTextRight ) );
5330 			aSet.Put( SdrTextUpperDistItem( nTextTop ) );
5331 			aSet.Put( SdrTextLowerDistItem( nTextBottom ) );
5332 			pTextImpRec->nDxTextLeft	= nTextLeft;
5333 			pTextImpRec->nDyTextTop		= nTextTop;
5334 			pTextImpRec->nDxTextRight	= nTextRight;
5335 			pTextImpRec->nDyTextBottom	= nTextBottom;
5336 
5337 			// Textverankerung lesen
5338 			if ( IsProperty( DFF_Prop_anchorText ) )
5339 			{
5340 				MSO_Anchor eTextAnchor =
5341                     (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText );
5342 
5343 				SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER;
5344 				sal_Bool bTVASet(sal_False);
5345 				SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER;
5346 				sal_Bool bTHASet(sal_False);
5347 
5348 				switch( eTextAnchor )
5349 				{
5350 					case mso_anchorTop:
5351 					{
5352 						eTVA = SDRTEXTVERTADJUST_TOP;
5353 						bTVASet = sal_True;
5354 					}
5355 					break;
5356 					case mso_anchorTopCentered:
5357 					{
5358 						eTVA = SDRTEXTVERTADJUST_TOP;
5359 						bTVASet = sal_True;
5360 						bTHASet = sal_True;
5361 					}
5362 					break;
5363 
5364 					case mso_anchorMiddle:
5365 						bTVASet = sal_True;
5366 					break;
5367 					case mso_anchorMiddleCentered:
5368 					{
5369 						bTVASet = sal_True;
5370 						bTHASet = sal_True;
5371 					}
5372 					break;
5373 					case mso_anchorBottom:
5374 					{
5375 						eTVA = SDRTEXTVERTADJUST_BOTTOM;
5376 						bTVASet = sal_True;
5377 					}
5378 					break;
5379 					case mso_anchorBottomCentered:
5380 					{
5381 						eTVA = SDRTEXTVERTADJUST_BOTTOM;
5382 						bTVASet = sal_True;
5383 						bTHASet = sal_True;
5384 					}
5385 					break;
5386 	/*
5387 					case mso_anchorTopBaseline:
5388 					case mso_anchorBottomBaseline:
5389 					case mso_anchorTopCenteredBaseline:
5390 					case mso_anchorBottomCenteredBaseline:
5391 					break;
5392 	*/
5393 					default : break;
5394 				}
5395 				// Einsetzen
5396 				if ( bTVASet )
5397 					aSet.Put( SdrTextVertAdjustItem( eTVA ) );
5398 				if ( bTHASet )
5399 					aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
5400 			}
5401 
5402 			pTextObj->SetMergedItemSet(aSet);
5403             pTextObj->SetModel(pSdrModel);
5404 
5405             if (bVerticalText)
5406                 pTextObj->SetVerticalWriting(sal_True);
5407 
5408             if (nTextRotationAngle)
5409 			{
5410                 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ?
5411                     rTextRect.GetWidth() : rTextRect.GetHeight();
5412                 nMinWH /= 2;
5413                 Point aPivot(rTextRect.TopLeft());
5414                 aPivot.X() += nMinWH;
5415                 aPivot.Y() += nMinWH;
5416 				double a = nTextRotationAngle * nPi180;
5417 				pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a));
5418 			}
5419 
5420 			// rotate text with shape ?
5421 			if ( mnFix16Angle )
5422 			{
5423 				double a = mnFix16Angle * nPi180;
5424 				pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle,
5425                     sin( a ), cos( a ) );
5426 			}
5427 
5428 			if( !pObj )
5429 			{
5430 				pObj = pTextObj;
5431 			}
5432 			else
5433 			{
5434 				if( pTextObj != pObj )
5435 				{
5436 					SdrObject* pGroup = new SdrObjGroup;
5437 					pGroup->GetSubList()->NbcInsertObject( pObj );
5438 					pGroup->GetSubList()->NbcInsertObject( pTextObj );
5439                     if (pOrgObj == pObj)
5440                         pOrgObj = pGroup;
5441                     else
5442 					    pOrgObj = pObj;
5443                     pObj = pGroup;
5444 				}
5445 			}
5446 		}
5447 		else if( !pObj )
5448 		{
5449 			// simple rectangular objects are ignored by ImportObj()  :-(
5450 			// this is OK for Draw but not for Calc and Writer
5451 			// cause here these objects have a default border
5452 			pObj = new SdrRectObj(rTextRect);
5453 			pOrgObj = pObj;
5454 			pObj->SetModel( pSdrModel );
5455             SfxItemSet aSet( pSdrModel->GetItemPool() );
5456 			ApplyAttributes( rSt, aSet, rObjData );
5457 
5458 			const SfxPoolItem* pPoolItem=NULL;
5459 			SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
5460 													 sal_False, &pPoolItem );
5461 			if( SFX_ITEM_DEFAULT == eState )
5462 				aSet.Put( XFillColorItem( String(),
5463 						  Color( mnDefaultColor ) ) );
5464 			pObj->SetMergedItemSet(aSet);
5465 		}
5466 
5467         //Means that fBehindDocument is set
5468         if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
5469 		    pImpRec->bDrawHell = sal_True;
5470         else
5471 		    pImpRec->bDrawHell = sal_False;
5472         if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
5473             pImpRec->bHidden = sal_True;
5474 		pTextImpRec->bDrawHell	= pImpRec->bDrawHell;
5475 		pTextImpRec->bHidden = pImpRec->bHidden;
5476 		pImpRec->nNextShapeId	= GetPropertyValue( DFF_Prop_hspNext, 0 );
5477 		pTextImpRec->nNextShapeId=pImpRec->nNextShapeId;
5478 
5479 		if ( nTextId )
5480 		{
5481 			pTextImpRec->aTextId.nTxBxS = (sal_uInt16)( nTextId >> 16 );
5482 			pTextImpRec->aTextId.nSequence = (sal_uInt16)nTextId;
5483 		}
5484 
5485 		pTextImpRec->nDxWrapDistLeft = GetPropertyValue(
5486 									DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
5487 		pTextImpRec->nDyWrapDistTop = GetPropertyValue(
5488 									DFF_Prop_dyWrapDistTop, 0 ) / 635L;
5489 		pTextImpRec->nDxWrapDistRight = GetPropertyValue(
5490 									DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
5491 		pTextImpRec->nDyWrapDistBottom = GetPropertyValue(
5492 									DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
5493         // 16.16 fraction times total image width or height, as appropriate.
5494 
5495         if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt))
5496         {
5497             delete pTextImpRec->pWrapPolygon;
5498             sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
5499             rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
5500             if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
5501             {
5502                 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert);
5503                 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
5504                 {
5505                     sal_Int32 nX, nY;
5506                     if (nElemSizeVert == 8)
5507                         rSt >> nX >> nY;
5508                     else
5509                     {
5510                         sal_Int16 nSmallX, nSmallY;
5511                         rSt >> nSmallX >> nSmallY;
5512                         nX = nSmallX;
5513                         nY = nSmallY;
5514                     }
5515                     (*(pTextImpRec->pWrapPolygon))[i].X() = nX;
5516                     (*(pTextImpRec->pWrapPolygon))[i].Y() = nY;
5517                 }
5518             }
5519         }
5520 
5521 		pImpRec->nCropFromTop = GetPropertyValue(
5522 									DFF_Prop_cropFromTop, 0 );
5523 		pImpRec->nCropFromBottom = GetPropertyValue(
5524 									DFF_Prop_cropFromBottom, 0 );
5525 		pImpRec->nCropFromLeft = GetPropertyValue(
5526 									DFF_Prop_cropFromLeft, 0 );
5527 		pImpRec->nCropFromRight = GetPropertyValue(
5528 									DFF_Prop_cropFromRight, 0 );
5529 
5530         pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false;
5531         pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false;
5532 
5533 		sal_uInt32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
5534 		pImpRec->eLineStyle = (nLineFlags & 8)
5535 							? (MSO_LineStyle)GetPropertyValue(
5536 												DFF_Prop_lineStyle,
5537 												mso_lineSimple )
5538 							: (MSO_LineStyle)USHRT_MAX;
5539 		pTextImpRec->eLineStyle = pImpRec->eLineStyle;
5540 
5541 		if( pImpRec->nShapeId )
5542 		{
5543 			// Import-Record-Liste ergaenzen
5544 			if( pOrgObj )
5545 			{
5546 				pImpRec->pObj = pOrgObj;
5547 				rImportData.aRecords.Insert( pImpRec );
5548 			}
5549 
5550 			if( pTextObj && (pOrgObj != pTextObj) )
5551 			{
5552 				// Modify ShapeId (must be unique)
5553 				pImpRec->nShapeId |= 0x8000000;
5554 				pTextImpRec->pObj = pTextObj;
5555 				rImportData.aRecords.Insert( pTextImpRec );
5556 			}
5557 
5558 			// Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen
5559 			/*Only store objects which are not deep inside the tree*/
5560 			if( ( rObjData.nCalledByGroup == 0 )
5561 				||
5562 				( (rObjData.nSpFlags & SP_FGROUP)
5563 				 && (rObjData.nCalledByGroup < 2) )
5564 			  )
5565 				StoreShapeOrder( pImpRec->nShapeId,
5566 								( ( (sal_uLong)pImpRec->aTextId.nTxBxS ) << 16 )
5567 									+ pImpRec->aTextId.nSequence, pObj );
5568 		}
5569 		else
5570 			delete pImpRec;
5571 	}
5572 
5573 	return pObj;
5574 };
5575 
5576 void SvxMSDffManager::StoreShapeOrder(sal_uLong			nId,
5577 									  sal_uLong			nTxBx,
5578 									  SdrObject*	pObject,
5579 									  SwFlyFrmFmt*	pFly,
5580 									  short			nHdFtSection) const
5581 {
5582 	sal_uInt16 nShpCnt = pShapeOrders->Count();
5583 	for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5584 	{
5585 		SvxMSDffShapeOrder& rOrder
5586 			= *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5587 
5588 		if( rOrder.nShapeId == nId )
5589 		{
5590 			rOrder.nTxBxComp = nTxBx;
5591 			rOrder.pObj      = pObject;
5592 			rOrder.pFly      = pFly;
5593 			rOrder.nHdFtSection = nHdFtSection;
5594 		}
5595 	}
5596 }
5597 
5598 
5599 void SvxMSDffManager::ExchangeInShapeOrder(	SdrObject*   pOldObject,
5600 											sal_uLong        nTxBx,
5601 											SwFlyFrmFmt* pFly,
5602 											SdrObject*   pObject) const
5603 {
5604 	sal_uInt16 nShpCnt = pShapeOrders->Count();
5605 	for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5606 	{
5607 		SvxMSDffShapeOrder& rOrder
5608 			= *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5609 
5610 		if( rOrder.pObj == pOldObject )
5611 		{
5612 			rOrder.pFly      = pFly;
5613 			rOrder.pObj      = pObject;
5614 			rOrder.nTxBxComp = nTxBx;
5615 		}
5616 	}
5617 }
5618 
5619 
5620 void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const
5621 {
5622 	sal_uInt16 nShpCnt = pShapeOrders->Count();
5623 	for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5624 	{
5625 		SvxMSDffShapeOrder& rOrder
5626 			= *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5627 
5628 		if( rOrder.pObj == pObject )
5629 		{
5630 			rOrder.pObj      = 0;
5631 			rOrder.pFly      = 0;
5632 			rOrder.nTxBxComp = 0;
5633 		}
5634 	}
5635 }
5636 
5637 
5638 
5639 
5640 //---------------------------------------------------------------------------
5641 //  Hilfs Deklarationen
5642 //---------------------------------------------------------------------------
5643 
5644 /*struct SvxMSDffBLIPInfo                       -> in's Header-File
5645 {
5646 	sal_uInt16 nBLIPType;       // Art des BLIP: z.B. 6 fuer PNG
5647 	sal_uLong  nFilePos;        // Offset des BLIP im Daten-Stream
5648 	sal_uLong  nBLIPSize;       // Anzahl Bytes, die der BLIP im Stream einnimmt
5649 	SvxMSDffBLIPInfo(sal_uInt16 nBType, sal_uLong nFPos, sal_uLong nBSize):
5650 		nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){}
5651 };
5652 */
5653 
5654 SV_IMPL_PTRARR(			SvxMSDffBLIPInfos,		SvxMSDffBLIPInfo_Ptr	);
5655 
5656 SV_IMPL_PTRARR(			SvxMSDffShapeOrders,	SvxMSDffShapeOrder_Ptr	);
5657 
5658 SV_IMPL_OP_PTRARR_SORT(	SvxMSDffShapeInfos,		SvxMSDffShapeInfo_Ptr	);
5659 
5660 SV_IMPL_OP_PTRARR_SORT(	SvxMSDffShapeTxBxSort,	SvxMSDffShapeOrder_Ptr	);
5661 
5662 
5663 // Liste aller SvxMSDffImportRec fuer eine Gruppe
5664 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr)
5665 
5666 //---------------------------------------------------------------------------
5667 //  exportierte Klasse: oeffentliche Methoden
5668 //---------------------------------------------------------------------------
5669 
5670 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_,
5671                                  const String& rBaseURL,
5672 								 long      nOffsDgg_,
5673 								 SvStream* pStData_,
5674 								 SdrModel* pSdrModel_,// s. unten: SetModel()
5675 								 long      nApplicationScale,
5676 								 ColorData mnDefaultColor_,
5677 								 sal_uLong     nDefaultFontHeight_,
5678 								 SvStream* pStData2_,
5679 								 MSFilterTracer* pTracer )
5680 	:DffPropertyReader( *this ),
5681 	 pFormModel( NULL ),
5682 	 pBLIPInfos( new SvxMSDffBLIPInfos  ),
5683 	 pShapeInfos(  new SvxMSDffShapeInfos ),
5684 	 pShapeOrders( new SvxMSDffShapeOrders ),
5685 	 nDefaultFontHeight( nDefaultFontHeight_),
5686 	 nOffsDgg( nOffsDgg_ ),
5687 	 nBLIPCount(  USHRT_MAX ),				// mit Error initialisieren, da wir erst pruefen,
5688 	 nShapeCount( USHRT_MAX ),              // ob Kontroll-Stream korrekte Daten enthaellt
5689      maBaseURL( rBaseURL ),
5690 	 mpFidcls( NULL ),
5691 	 rStCtrl(  rStCtrl_  ),
5692 	 pStData(  pStData_  ),
5693 	 pStData2( pStData2_ ),
5694 	 nSvxMSDffSettings( 0 ),
5695 	 nSvxMSDffOLEConvFlags( 0 ),
5696 	 pSecPropSet( NULL ),
5697      pEscherBlipCache( NULL ),
5698 	 mnDefaultColor( mnDefaultColor_),
5699 	 mpTracer( pTracer ),
5700      mbTracing( sal_False )
5701 {
5702 	if ( mpTracer )
5703 	{
5704 		uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
5705 		aAny >>= mbTracing;
5706 	}
5707 	SetModel( pSdrModel_, nApplicationScale );
5708 
5709 	// FilePos des/der Stream(s) merken
5710 	sal_uLong nOldPosCtrl = rStCtrl.Tell();
5711 	sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
5712 
5713 	// Falls kein Datenstream angegeben, gehen wir davon aus,
5714 	// dass die BLIPs im Steuerstream stehen.
5715 	if( !pStData )
5716 		pStData = &rStCtrl;
5717 
5718 	SetDefaultPropSet( rStCtrl, nOffsDgg );
5719 
5720 	// Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
5721 	GetCtrlData( nOffsDgg );
5722 
5723 	// Text-Box-Story-Ketten-Infos ueberpruefen
5724 	CheckTxBxStoryChain();
5725 
5726 	// alte FilePos des/der Stream(s) restaurieren
5727 	rStCtrl.Seek( nOldPosCtrl );
5728 	if( &rStCtrl != pStData )
5729 		pStData->Seek( nOldPosData );
5730 }
5731 
5732 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer )
5733 	:DffPropertyReader( *this ),
5734 	 pFormModel( NULL ),
5735 	 pBLIPInfos(   new SvxMSDffBLIPInfos  ),
5736 	 pShapeInfos(  new SvxMSDffShapeInfos ),
5737 	 pShapeOrders( new SvxMSDffShapeOrders ),
5738 	 nDefaultFontHeight( 24 ),
5739 	 nOffsDgg( 0 ),
5740 	 nBLIPCount(  USHRT_MAX ),				// mit Error initialisieren, da wir erst pruefen,
5741 	 nShapeCount( USHRT_MAX ),              // ob Kontroll-Stream korrekte Daten enthaellt
5742      maBaseURL( rBaseURL ),
5743 	 mpFidcls( NULL ),
5744 	 rStCtrl(  rStCtrl_  ),
5745 	 pStData( 0 ),
5746 	 pStData2( 0 ),
5747 	 nSvxMSDffSettings( 0 ),
5748 	 nSvxMSDffOLEConvFlags( 0 ),
5749 	 pSecPropSet( NULL ),
5750      pEscherBlipCache( NULL ),
5751 	 mnDefaultColor( COL_DEFAULT ),
5752 	 mpTracer( pTracer ),
5753      mbTracing( sal_False )
5754 {
5755 	if ( mpTracer )
5756 	{
5757 		uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
5758 		aAny >>= mbTracing;
5759 	}
5760 	SetModel( NULL, 0 );
5761 }
5762 
5763 SvxMSDffManager::~SvxMSDffManager()
5764 {
5765     if ( pEscherBlipCache )
5766     {
5767         void* pPtr;
5768         for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() )
5769             delete (EscherBlipCacheEntry*)pPtr;
5770         delete pEscherBlipCache;
5771     }
5772 	delete pSecPropSet;
5773 	delete pBLIPInfos;
5774 	delete pShapeInfos;
5775 	delete pShapeOrders;
5776 	delete pFormModel;
5777 	delete[] mpFidcls;
5778 }
5779 
5780 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags )
5781 {
5782 	nOffsDgg = nOffsDgg_;
5783 	pStData = pStData_;
5784 	nSvxMSDffOLEConvFlags = nOleConvFlags;
5785 
5786 	// FilePos des/der Stream(s) merken
5787 	sal_uLong nOldPosCtrl = rStCtrl.Tell();
5788 
5789 	SetDefaultPropSet( rStCtrl, nOffsDgg );
5790 
5791 	// insert fidcl cluster table
5792 	GetFidclData( nOffsDgg );
5793 
5794 	// Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
5795 	GetCtrlData( nOffsDgg );
5796 
5797 	// Text-Box-Story-Ketten-Infos ueberpruefen
5798 	CheckTxBxStoryChain();
5799 
5800 	// alte FilePos des/der Stream(s) restaurieren
5801 	rStCtrl.Seek( nOldPosCtrl );
5802 }
5803 
5804 void SvxMSDffManager::SetDgContainer( SvStream& rSt )
5805 {
5806 	sal_uInt32 nFilePos = rSt.Tell();
5807 	DffRecordHeader aDgContHd;
5808 	rSt >> aDgContHd;
5809 	// insert this container only if there is also a DgAtom
5810 	if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) )
5811 	{
5812 		DffRecordHeader aRecHd;
5813 		rSt >> aRecHd;
5814 		sal_uInt32 nDrawingId = aRecHd.nRecInstance;
5815 		maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos );
5816 		rSt.Seek( nFilePos );
5817 	}
5818 }
5819 
5820 void SvxMSDffManager::GetFidclData( long nOffsDggL )
5821 {
5822 	if ( nOffsDggL )
5823 	{
5824 		sal_uInt32 nDummy, nMerk = rStCtrl.Tell();
5825 		rStCtrl.Seek( nOffsDggL );
5826 
5827 		DffRecordHeader aRecHd;
5828 		rStCtrl >> aRecHd;
5829 
5830 		DffRecordHeader aDggAtomHd;
5831 		if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) )
5832 		{
5833 			aDggAtomHd.SeekToContent( rStCtrl );
5834 			rStCtrl >> mnCurMaxShapeId
5835 					>> mnIdClusters
5836 					>> nDummy
5837 					>> mnDrawingsSaved;
5838 
5839 			if ( mnIdClusters-- > 2 )
5840 			{
5841 				if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) )
5842 				{
5843 					//mpFidcls = new FIDCL[ mnIdClusters ];
5844                     mpFidcls = new (std::nothrow) FIDCL[ mnIdClusters ];
5845                     if ( mpFidcls ) {
5846                         for ( sal_uInt32 i = 0; i < mnIdClusters; i++ )
5847                         {
5848                             rStCtrl >> mpFidcls[ i ].dgid
5849                                     >> mpFidcls[ i ].cspidCur;
5850                         }
5851                     }
5852 				}
5853 			}
5854 		}
5855 		rStCtrl.Seek( nMerk );
5856 	}
5857 }
5858 
5859 void SvxMSDffManager::CheckTxBxStoryChain()
5860 {
5861 	SvxMSDffShapeInfos* pOld = pShapeInfos;
5862 	sal_uInt16 nCnt				= pOld->Count();
5863 	pShapeInfos				= new SvxMSDffShapeInfos( (nCnt < 255)
5864 													 ? nCnt
5865 													 : 255 );
5866 	// altes Info-Array ueberarbeiten
5867 	// (ist sortiert nach nTxBxComp)
5868 	sal_uLong nChain    = ULONG_MAX;
5869 	sal_uInt16 nObjMark = 0;
5870 	sal_Bool bSetReplaceFALSE = sal_False;
5871 	sal_uInt16 nObj;
5872 	for( nObj = 0; nObj < nCnt; ++nObj )
5873 	{
5874 		SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj );
5875 		if( pObj->nTxBxComp )
5876 		{
5877 			pObj->bLastBoxInChain = sal_False;
5878 			// Gruppenwechsel ?
5879             // --> OD 2008-07-28 #156763#
5880             // the text id also contains an internal drawing container id
5881             // to distinguish between text id of drawing objects in different
5882             // drawing containers.
5883 //            if( nChain != (pObj->nTxBxComp & 0xFFFF0000) )
5884             if( nChain != pObj->nTxBxComp )
5885             // <--
5886             {
5887 				// voriger war letzter seiner Gruppe
5888 				if( nObj )
5889 					pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True;
5890 				// Merker und Hilfs-Flag zuruecksetzen
5891 				nObjMark = nObj;
5892                 // --> OD 2008-07-28 #156763#
5893 //                nChain   = pObj->nTxBxComp & 0xFFFF0000;
5894                 nChain = pObj->nTxBxComp;
5895                 // <--
5896 				bSetReplaceFALSE = !pObj->bReplaceByFly;
5897 			}
5898 			else
5899 			if( !pObj->bReplaceByFly )
5900 			{
5901 				// Objekt, das NICHT durch Rahmen ersetzt werden darf ?
5902 				// Hilfs-Flag setzen
5903 				bSetReplaceFALSE = sal_True;
5904 				// ggfs Flag in Anfang der Gruppe austragen
5905 				for( sal_uInt16 nObj2 = nObjMark; nObj2 < nObj; ++nObj2 )
5906 					pOld->GetObject( nObj2 )->bReplaceByFly = sal_False;
5907 			}
5908 
5909 			if( bSetReplaceFALSE )
5910 			{
5911 				pObj->bReplaceByFly = sal_False;
5912 			}
5913 		}
5914 		// alle Shape-Info-Objekte in pShapeInfos umkopieren
5915 		// (aber nach nShapeId sortieren)
5916 		pObj->bSortByShapeId = sal_True;
5917         // --> OD 2008-07-28 #156763#
5918         pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000;
5919         // <--
5920 		pShapeInfos->Insert( pObj );
5921 	}
5922 	// voriger war letzter seiner Gruppe
5923 	if( nObj )
5924 		pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True;
5925 	// urspruengliches Array freigeben, ohne Objekte zu zerstoeren
5926 	pOld->Remove((sal_uInt16)0, nCnt);
5927 	delete pOld;
5928 }
5929 
5930 
5931 /*****************************************************************************
5932 
5933 	Einlesen der Shape-Infos im Ctor:
5934 	---------------------------------
5935 	merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos
5936 			   =========                  ============	   =============
5937 	und merken des File-Offsets fuer jedes Blip
5938 				   ============
5939 ******************************************************************************/
5940 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ )
5941 {
5942 	// Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen
5943 	long nOffsDggL = nOffsDgg_;
5944 
5945 	// Kontroll Stream positionieren
5946 	rStCtrl.Seek( nOffsDggL );
5947 
5948 	sal_uInt8   nVer;
5949 	sal_uInt16 nInst;
5950 	sal_uInt16 nFbt;
5951 	sal_uInt32  nLength;
5952 	if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return;
5953 
5954 	sal_Bool bOk;
5955 	sal_uLong nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE;
5956 
5957 	// Fall A: erst Drawing Group Container, dann n Mal Drawing Container
5958 	if( DFF_msofbtDggContainer == nFbt )
5959 	{
5960         GetDrawingGroupContainerData( rStCtrl, nLength );
5961 
5962 		 rStCtrl.Seek( STREAM_SEEK_TO_END );
5963 		sal_uInt32 nMaxStrPos = rStCtrl.Tell();
5964 
5965 		nPos += nLength;
5966         // --> OD 2008-07-28 #156763#
5967         unsigned long nDrawingContainerId = 1;
5968         // <--
5969         do
5970 		{
5971 			rStCtrl.Seek( nPos );
5972 
5973 			bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt );
5974 
5975 			if( !bOk )
5976 			{
5977 				nPos++;				// ????????? TODO: trying to get an one-hit wonder, this code code should be rewritten...
5978 				rStCtrl.Seek( nPos );
5979 				bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength )
5980 						&& ( DFF_msofbtDgContainer == nFbt );
5981 			}
5982 			if( bOk )
5983             {
5984                 // --> OD 2008-07-28 #156763#
5985                 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId );
5986                 // <--
5987             }
5988 			nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
5989             // --> OD 2008-07-28 #156763#
5990             ++nDrawingContainerId;
5991             // <--
5992 		}
5993 		while( ( rStCtrl.GetError() == 0 ) && ( nPos < nMaxStrPos ) && bOk );
5994 	}
5995 }
5996 
5997 
5998 // ab hier: Drawing Group Container  d.h. Dokument - weit gueltige Daten
5999 //                      =======================           ========
6000 //
6001 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, sal_uLong nLenDgg )
6002 {
6003 	sal_uInt8   nVer;
6004 	sal_uInt16 nInst;
6005 	sal_uInt16 nFbt;
6006 	sal_uInt32 nLength;
6007 
6008 	sal_uLong nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0;
6009 
6010 	// Nach einem BStore Container suchen
6011 	do
6012 	{
6013 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6014 		nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6015 		if( DFF_msofbtBstoreContainer == nFbt )
6016 		{
6017 			nLenBStoreCont = nLength;       break;
6018 		}
6019 		rSt.SeekRel( nLength );
6020 	}
6021 	while( nRead < nLenDgg );
6022 
6023 	if( !nLenBStoreCont ) return;
6024 
6025 	// Im BStore Container alle Header der Container und Atome auslesen und die
6026 	// relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen.
6027 	// Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit.
6028 
6029 	const sal_uLong nSkipBLIPLen = 20;  // bis zu nBLIPLen zu ueberspringende Bytes
6030 	const sal_uLong nSkipBLIPPos =  4;  // dahinter bis zu nBLIPPos zu skippen
6031 
6032 	sal_uInt32 nBLIPLen = 0, nBLIPPos = 0;
6033 
6034 	nRead = 0;
6035 	do
6036 	{
6037 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6038 		nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6039 		if( DFF_msofbtBSE == nFbt )
6040 		{
6041 			nLenFBSE = nLength;
6042 			// ist FBSE gross genug fuer unsere Daten
6043 			sal_Bool bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE );
6044 
6045 			if( bOk )
6046 			{
6047 				rSt.SeekRel( nSkipBLIPLen );
6048 				rSt >> nBLIPLen;
6049 				rSt.SeekRel( nSkipBLIPPos );
6050 				rSt >> nBLIPPos;
6051 				bOk = rSt.GetError() == 0;
6052 
6053 				nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4;
6054 			}
6055 
6056 			if( bOk )
6057 			{
6058 				// Besonderheit:
6059 				// Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist,
6060 				// nehmen wir an, dass das Bild IM FBSE drin steht!
6061 				if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) )
6062 					nBLIPPos = rSt.Tell() + 4;
6063 
6064 				// Das hat ja fein geklappt!
6065 				// Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben.
6066 				nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell());
6067 
6068 				if( USHRT_MAX == nBLIPCount )
6069 					nBLIPCount = 1;
6070 				else
6071 					nBLIPCount++;
6072 
6073 				// Jetzt die Infos fuer spaetere Zugriffe speichern
6074 				pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ),
6075 														  pBLIPInfos->Count() );
6076 			}
6077 		}
6078 		rSt.SeekRel( nLength );
6079 	}
6080 	while( nRead < nLenBStoreCont );
6081 }
6082 
6083 
6084 // ab hier: Drawing Container  d.h. Seiten (Blatt, Dia) - weit gueltige Daten
6085 //                      =================               ======
6086 //
6087 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, sal_uLong nLenDg,
6088                                                const unsigned long nDrawingContainerId )
6089 {
6090 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
6091 
6092 	sal_uLong nReadDg = 0;
6093 
6094 	// Wir stehen in einem Drawing Container (je einer pro Seite)
6095 	// und muessen nun
6096 	// alle enthaltenen Shape Group Container abklappern
6097 	do
6098 	{
6099 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6100 		nReadDg += DFF_COMMON_RECORD_HEADER_SIZE;
6101 		// Patriarch gefunden (der oberste Shape Group Container) ?
6102 		if( DFF_msofbtSpgrContainer == nFbt )
6103 		{
6104             if(!this->GetShapeGroupContainerData( rSt, nLength, sal_True, nDrawingContainerId )) return;
6105 		}
6106 		else
6107 		// blanker Shape Container ? (ausserhalb vom Shape Group Container)
6108 		if( DFF_msofbtSpContainer == nFbt )
6109 		{
6110             if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return;
6111 		}
6112 		else
6113 			rSt.SeekRel( nLength );
6114 		nReadDg += nLength;
6115 	}
6116 	while( nReadDg < nLenDg );
6117 }
6118 
6119 sal_Bool SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt,
6120 												  sal_uLong nLenShapeGroupCont,
6121                                                   sal_Bool bPatriarch,
6122                                                   const unsigned long nDrawingContainerId )
6123 {
6124 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
6125 	long nStartShapeGroupCont = rSt.Tell();
6126 	// Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite)
6127 	// und muessen nun
6128 	// alle enthaltenen Shape Container abklappern
6129 	sal_Bool  bFirst = !bPatriarch;
6130 	sal_uLong nReadSpGrCont = 0;
6131 	do
6132 	{
6133 		if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) )
6134 			return sal_False;
6135 		nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE;
6136 		// Shape Container ?
6137 		if( DFF_msofbtSpContainer == nFbt )
6138 		{
6139 			sal_uLong nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX;
6140             if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) )
6141 				return sal_False;
6142 			bFirst = sal_False;
6143 		}
6144 		else
6145 		// eingeschachtelter Shape Group Container ?
6146 		if( DFF_msofbtSpgrContainer == nFbt )
6147 		{
6148             if ( !this->GetShapeGroupContainerData( rSt, nLength, sal_False, nDrawingContainerId ) )
6149 				return sal_False;
6150 		}
6151 		else
6152 			rSt.SeekRel( nLength );
6153 		nReadSpGrCont += nLength;
6154 	}
6155 	while( nReadSpGrCont < nLenShapeGroupCont );
6156 	// den Stream wieder korrekt positionieren
6157 	rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont );
6158 	return sal_True;
6159 }
6160 
6161 sal_Bool SvxMSDffManager::GetShapeContainerData( SvStream& rSt,
6162                                              sal_uLong nLenShapeCont,
6163                                              sal_uLong nPosGroup,
6164                                              const unsigned long nDrawingContainerId )
6165 {
6166 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
6167 	long  nStartShapeCont = rSt.Tell();
6168 	// Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group)
6169 	// und muessen nun
6170 	// die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe)
6171 	// und den ersten BStore Verweis (falls vorhanden) entnehmen
6172 	sal_uLong nLenShapePropTbl = 0;
6173 	sal_uLong nReadSpCont = 0;
6174 
6175 	// File Offset des Shape-Containers bzw. der Gruppe(!) vermerken
6176 	//
6177 	sal_uLong nStartOffs = (ULONG_MAX > nPosGroup) ?
6178 							nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE;
6179 	SvxMSDffShapeInfo aInfo( nStartOffs );
6180 
6181 	// duerfte das Shape durch einen Rahmen ersetzt werden ?
6182 	// (vorausgesetzt, es zeigt sich, dass es eine TextBox ist,
6183 	//  und der Text nicht gedreht ist)
6184 	sal_Bool bCanBeReplaced = (ULONG_MAX > nPosGroup) ? sal_False : sal_True;
6185 
6186 	// wir wissen noch nicht, ob es eine TextBox ist
6187 	MSO_SPT			eShapeType		= mso_sptNil;
6188 	MSO_WrapMode	eWrapMode		= mso_wrapSquare;
6189 //	sal_Bool			bIsTextBox		= sal_False;
6190 
6191 	// Shape analysieren
6192 	//
6193 	do
6194 	{
6195 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return sal_False;
6196 		nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE;
6197 		// FSP ?
6198 		if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) )
6199 		{
6200 			// Wir haben den FSP gefunden: Shape Typ und Id vermerken!
6201 			eShapeType = (MSO_SPT)nInst;
6202 			rSt >> aInfo.nShapeId;
6203 			rSt.SeekRel( nLength - 4 );
6204 			nReadSpCont += nLength;
6205 		}
6206 		else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ?
6207 		{
6208 			// Wir haben die Property Table gefunden:
6209 			// nach der Blip Property suchen!
6210 			sal_uLong  nPropRead = 0;
6211 			sal_uInt16 nPropId;
6212 			sal_uInt32  nPropVal;
6213 			nLenShapePropTbl = nLength;
6214 //			sal_uInt32 nPropCount = nInst;
6215 			long nStartShapePropTbl = rSt.Tell();
6216 //			sal_uInt32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6);
6217 			do
6218 			{
6219 				rSt >> nPropId
6220 					>> nPropVal;
6221 				nPropRead += 6;
6222 
6223 				switch( nPropId )
6224 				{
6225 					case DFF_Prop_txflTextFlow :
6226                         //Writer can now handle vertical textflows in its
6227                         //native frames, to only need to do this for the
6228                         //other two formats
6229 
6230                         //Writer will handle all textflow except BtoT
6231 						if (GetSvxMSDffSettings() &
6232                             (SVXMSDFF_SETTINGS_IMPORT_PPT |
6233                              SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6234                         {
6235                             if( 0 != nPropVal )
6236                                 bCanBeReplaced = false;
6237                         }
6238                         else if (
6239                             (nPropVal != mso_txflHorzN) &&
6240                             (nPropVal != mso_txflTtoBA)
6241                                 )
6242                         {
6243                             bCanBeReplaced = false;
6244                         }
6245 					break;
6246 					case DFF_Prop_cdirFont :
6247                         //Writer can now handle right to left and left
6248                         //to right in its native frames, so only do
6249                         //this for the other two formats.
6250 						if (GetSvxMSDffSettings() &
6251                             (SVXMSDFF_SETTINGS_IMPORT_PPT |
6252                              SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6253                         {
6254                             if( 0 != nPropVal )
6255                                 bCanBeReplaced = sal_False;
6256                         }
6257                     break;
6258 					case DFF_Prop_Rotation :
6259 						if( 0 != nPropVal )
6260 							bCanBeReplaced = sal_False;
6261 					break;
6262 
6263 					case DFF_Prop_gtextFStrikethrough :
6264 						if( ( 0x20002000 & nPropVal )  == 0x20002000 )
6265 							bCanBeReplaced = sal_False;
6266 					break;
6267 
6268 					case DFF_Prop_fc3DLightFace :
6269 						if( ( 0x00080008 & nPropVal ) == 0x00080008 )
6270 							bCanBeReplaced = sal_False;
6271 					break;
6272 
6273 					case DFF_Prop_WrapText :
6274 						eWrapMode = (MSO_WrapMode)nPropVal;
6275 					break;
6276 
6277 					default:
6278 					{
6279 						// Bit gesetzt und gueltig?
6280 						if( 0x4000 == ( nPropId & 0xC000 ) )
6281 						{
6282 							// Blip Property gefunden: BStore Idx vermerken!
6283 							nPropRead = nLenShapePropTbl;
6284 						}
6285 						else if( 0x8000 & nPropId )
6286 						{
6287 							// komplexe Prop gefunden:
6288 							// Laenge ist immer 6, nur die Laenge der nach der
6289 							// eigentlichen Prop-Table anhaengenden Extra-Daten
6290 							// ist unterschiedlich
6291 							nPropVal = 6;
6292 						}
6293 					}
6294 					break;
6295 				}
6296 
6297 /*
6298 //JP 21.04.99: Bug 64510
6299 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge
6300 // Performance einbussen hat.
6301 
6302 				if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig?
6303 				{
6304 					// Blip Property gefunden: BStore Idx vermerken!
6305 					aInfo.nBStoreIdx = nPropVal;    // Index im BStore Container
6306 					break;
6307 				}
6308 				else
6309 				if(    (    (    (DFF_Prop_txflTextFlow   == nPropId)
6310 							  || (DFF_Prop_Rotation       == nPropId)
6311 							  || (DFF_Prop_cdirFont       == nPropId) )
6312 						 && (0 != nPropVal) )
6313 
6314 					|| (    (DFF_Prop_gtextFStrikethrough == nPropId)
6315 						 && ( (0x20002000 & nPropVal)  == 0x20002000) ) // also DFF_Prop_gtextFVertical
6316 					|| (    (DFF_Prop_fc3DLightFace       == nPropId)
6317 						 && ( (0x00080008 & nPropVal)  == 0x00080008) )	// also DFF_Prop_f3D
6318 				  )
6319 				{
6320 					bCanBeReplaced = sal_False;  // Mist: gedrehter Text oder 3D-Objekt!
6321 				}
6322 				else
6323 				if( DFF_Prop_WrapText == nPropId )
6324 				{
6325 					eWrapMode = (MSO_WrapMode)nPropVal;
6326 				}
6327 				////////////////////////////////////////////////////////////////
6328 				////////////////////////////////////////////////////////////////
6329 				// keine weitere Property-Auswertung: folge beim Shape-Import //
6330 				////////////////////////////////////////////////////////////////
6331 				////////////////////////////////////////////////////////////////
6332 				else
6333 				if( 0x8000 & nPropId )
6334 				{
6335 					// komplexe Prop gefunden: Laenge lesen und ueberspringen
6336 					if(!SkipBytes( rSt, nPropVal )) return sal_False;
6337 					nPropRead += nPropVal;
6338 				}
6339 */
6340 			}
6341 			while( nPropRead < nLenShapePropTbl );
6342 			rSt.Seek( nStartShapePropTbl + nLenShapePropTbl );
6343 			nReadSpCont += nLenShapePropTbl;
6344 		}
6345 		else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) )	// Text-Box-Story-Eintrag gefunden
6346 		{
6347 			rSt >> aInfo.nTxBxComp;
6348             // --> OD 2008-07-28 #156763#
6349             // Add internal drawing container id to text id.
6350             // Note: The text id uses the first two bytes, while the internal
6351             // drawing container id used the second two bytes.
6352             aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) +
6353                               nDrawingContainerId;
6354             DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId,
6355                         "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." );
6356             // <--
6357 		}
6358 		else
6359 		{
6360 			rSt.SeekRel( nLength );
6361 			nReadSpCont += nLength;
6362 		}
6363 	}
6364 	while( nReadSpCont < nLenShapeCont );
6365 
6366 	//
6367 	// Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern
6368 	//
6369 	if( aInfo.nShapeId )
6370 	{
6371 		// fuer Textboxen ggfs. ersetzen durch Rahmen erlauben
6372 		if(     bCanBeReplaced
6373 			 && aInfo.nTxBxComp
6374 			 && (
6375 					( eShapeType == mso_sptTextSimple )
6376 				 || ( eShapeType == mso_sptTextBox    )
6377 				 || (    (    ( eShapeType == mso_sptRectangle      )
6378 						   || ( eShapeType == mso_sptRoundRectangle )
6379 						 )
6380 				) ) )
6381 		{
6382 			aInfo.bReplaceByFly = sal_True;
6383 		}
6384 		pShapeInfos->Insert(  new SvxMSDffShapeInfo(  aInfo          ) );
6385 		pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ),
6386 							  pShapeOrders->Count() );
6387 	}
6388 
6389 	// und den Stream wieder korrekt positionieren
6390 	rSt.Seek( nStartShapeCont + nLenShapeCont );
6391 	return sal_True;
6392 }
6393 
6394 
6395 
6396 /*****************************************************************************
6397 
6398 	Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id)
6399 	----------------------------------
6400 ******************************************************************************/
6401 sal_Bool SvxMSDffManager::GetShape(sal_uLong nId, SdrObject*&         rpShape,
6402 										  SvxMSDffImportData& rData)
6403 {
6404 	SvxMSDffShapeInfo aTmpRec(0, nId);
6405 	aTmpRec.bSortByShapeId = sal_True;
6406 
6407 	sal_uInt16 nFound;
6408 	if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) )
6409 	{
6410 		SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound );
6411 
6412 		// eventuell altes Errorflag loeschen
6413 		if( rStCtrl.GetError() )
6414 			rStCtrl.ResetError();
6415 		// FilePos des/der Stream(s) merken
6416 		sal_uLong nOldPosCtrl = rStCtrl.Tell();
6417 		sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6418 		// das Shape im Steuer Stream anspringen
6419 		rStCtrl.Seek( rInfo.nFilePos );
6420 
6421 		// Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt!
6422 		if( rStCtrl.GetError() )
6423 			rStCtrl.ResetError();
6424 		else
6425 			rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect );
6426 
6427 		// alte FilePos des/der Stream(s) restaurieren
6428 		rStCtrl.Seek( nOldPosCtrl );
6429 		if( &rStCtrl != pStData )
6430 			pStData->Seek( nOldPosData );
6431 		return ( 0 != rpShape );
6432 	}
6433 	return sal_False;
6434 }
6435 
6436 
6437 
6438 /*      Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr)
6439 	---------------------------------
6440 ******************************************************************************/
6441 sal_Bool SvxMSDffManager::GetBLIP( sal_uLong nIdx_, Graphic& rData, Rectangle* pVisArea ) const
6442 {
6443 	sal_Bool bOk = sal_False;       // Ergebnisvariable initialisieren
6444 	if ( pStData )
6445 	{
6446         // check if a graphic for this blipId is already imported
6447         if ( nIdx_ && pEscherBlipCache )
6448         {
6449             EscherBlipCacheEntry* pEntry;
6450             for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry;
6451                     pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() )
6452             {
6453                 if ( pEntry->nBlip == nIdx_ )
6454                 {	/* if this entry is available, then it should be possible
6455 					to get the Graphic via GraphicObject */
6456 					GraphicObject aGraphicObject( pEntry->aUniqueID );
6457                     rData = aGraphicObject.GetGraphic();
6458 					if ( rData.GetType() != GRAPHIC_NONE )
6459 	                    bOk = sal_True;
6460 					else
6461 						delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove();
6462 					break;
6463                 }
6464             }
6465         }
6466         if ( !bOk )
6467         {
6468 		    sal_uInt16 nIdx = sal_uInt16( nIdx_ );
6469 		    if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return sal_False;
6470 
6471 		    // eventuell alte(s) Errorflag(s) loeschen
6472 		    if( rStCtrl.GetError() )
6473 			    rStCtrl.ResetError();
6474 		    if(    ( &rStCtrl != pStData )
6475 			    && pStData->GetError() )
6476 			    pStData->ResetError();
6477 
6478 		    // FilePos des/der Stream(s) merken
6479 		    sal_uLong nOldPosCtrl = rStCtrl.Tell();
6480 		    sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6481 
6482 		    // passende Info-Struct aus unserem Pointer Array nehmen
6483 		    SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ];
6484 
6485 		    // das BLIP Atom im Daten Stream anspringen
6486 		    pStData->Seek( rInfo.nFilePos );
6487 		    // ggfs. Fehlerstatus zuruecksetzen
6488 		    if( pStData->GetError() )
6489 			    pStData->ResetError();
6490 		    else
6491 			    bOk = GetBLIPDirect( *pStData, rData, pVisArea );
6492 		    if( pStData2 && !bOk )
6493 		    {
6494 			    // Fehler, aber zweite Chance: es gibt noch einen zweiten
6495 			    //         Datenstream, in dem die Grafik liegen koennte!
6496 			    if( pStData2->GetError() )
6497 				    pStData2->ResetError();
6498 			    sal_uLong nOldPosData2 = pStData2->Tell();
6499 			    // das BLIP Atom im zweiten Daten Stream anspringen
6500 			    pStData2->Seek( rInfo.nFilePos );
6501 			    // ggfs. Fehlerstatus zuruecksetzen
6502 			    if( pStData2->GetError() )
6503 				    pStData2->ResetError();
6504 			    else
6505 				    bOk = GetBLIPDirect( *pStData2, rData, pVisArea );
6506 			    // alte FilePos des zweiten Daten-Stream restaurieren
6507 			    pStData2->Seek( nOldPosData2 );
6508 		    }
6509 		    // alte FilePos des/der Stream(s) restaurieren
6510 		    rStCtrl.Seek( nOldPosCtrl );
6511 		    if( &rStCtrl != pStData )
6512 		      pStData->Seek( nOldPosData );
6513 
6514             if ( bOk )
6515             {
6516                 // create new BlipCacheEntry for this graphic
6517 				GraphicObject aGraphicObject( rData );
6518                 if ( !pEscherBlipCache )
6519                     const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List();
6520                 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() );
6521                 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND );
6522             }
6523         }
6524 	}
6525 	return bOk;
6526 }
6527 
6528 /*      Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream)
6529 	---------------------------------
6530 ******************************************************************************/
6531 sal_Bool SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const
6532 {
6533 	sal_uLong nOldPos = rBLIPStream.Tell();
6534 
6535 	int nRes = GRFILTER_OPENERROR;  // Fehlervariable initialisieren
6536 
6537 	// nachschauen, ob es sich auch wirklich um ein BLIP handelt
6538 	sal_uInt32 nLength;
6539 	sal_uInt16 nInst, nFbt( 0 );
6540 	sal_uInt8   nVer;
6541 	if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) )
6542 	{
6543 		Size		aMtfSize100;
6544 		sal_Bool		bMtfBLIP = sal_False;
6545 		sal_Bool		bZCodecCompression = sal_False;
6546 		// Nun exakt auf den Beginn der eingebetteten Grafik positionieren
6547 		sal_uLong nSkip = ( nInst & 0x0001 ) ? 32 : 16;
6548 
6549 		switch( nInst & 0xFFFE )
6550 		{
6551 			case 0x216 :			// Metafile header then compressed WMF
6552 			case 0x3D4 :			// Metafile header then compressed EMF
6553 			case 0x542 :			// Metafile hd. then compressed PICT
6554 			{
6555 				rBLIPStream.SeekRel( nSkip + 20 );
6556 
6557 				// read in size of metafile in EMUS
6558 				rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height();
6559 
6560 				// scale to 1/100mm
6561 				aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360;
6562 
6563 				if ( pVisArea )		// seem that we currently are skipping the visarea position
6564 					*pVisArea = Rectangle( Point(), aMtfSize100 );
6565 
6566 				// skip rest of header
6567 				nSkip = 6;
6568 				bMtfBLIP = bZCodecCompression = sal_True;
6569 			}
6570 			break;
6571 			case 0x46A :			// One byte tag then JPEG (= JFIF) data
6572 			case 0x6E0 :			// One byte tag then PNG data
6573 			case 0x6E2 :			// One byte tag then JPEG in CMYK color space
6574 			case 0x7A8 :
6575 				nSkip += 1;			// One byte tag then DIB data
6576 			break;
6577 		}
6578 		rBLIPStream.SeekRel( nSkip );
6579 
6580 		SvStream* pGrStream = &rBLIPStream;
6581 		SvMemoryStream* pOut = NULL;
6582 		if( bZCodecCompression )
6583 		{
6584 			pOut = new SvMemoryStream( 0x8000, 0x4000 );
6585 			ZCodec aZCodec( 0x8000, 0x8000 );
6586 			aZCodec.BeginCompression();
6587 			aZCodec.Decompress( rBLIPStream, *pOut );
6588 			aZCodec.EndCompression();
6589 			pOut->Seek( STREAM_SEEK_TO_BEGIN );
6590 			pOut->SetResizeOffset( 0 );	// sj: #i102257# setting ResizeOffset of 0 prevents from seeking
6591 										// behind the stream end (allocating too much memory)
6592 			pGrStream = pOut;
6593 		}
6594 
6595 //#define DBG_EXTRACTGRAPHICS
6596 #ifdef DBG_EXTRACTGRAPHICS
6597 
6598 		static sal_Int32 nCount;
6599 
6600 		String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) );
6601 		aFileName.Append( String::CreateFromInt32( nCount++ ) );
6602 		switch( nInst &~ 1 )
6603 		{
6604 			case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break;
6605 			case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break;
6606 			case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break;
6607 			case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
6608 			case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break;
6609 			case 0x6e2 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
6610 			case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break;
6611 		}
6612 
6613 		String aURLStr;
6614 
6615 		if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
6616 		{
6617 			INetURLObject aURL( aURLStr );
6618 
6619 			aURL.removeSegment();
6620 			aURL.removeFinalSlash();
6621 			aURL.Append( aFileName );
6622 
6623 			SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE );
6624 
6625 			if( pDbgOut )
6626 			{
6627 				if ( bZCodecCompression )
6628 				{
6629 					pOut->Seek( STREAM_SEEK_TO_END );
6630 					pDbgOut->Write( pOut->GetData(), pOut->Tell() );
6631 					pOut->Seek( STREAM_SEEK_TO_BEGIN );
6632 				}
6633 				else
6634 				{
6635 					sal_Int32 nDbgLen = nLength - nSkip;
6636 					if ( nDbgLen )
6637 					{
6638 						sal_Char* pDat = new sal_Char[ nDbgLen ];
6639 						pGrStream->Read( pDat, nDbgLen );
6640 						pDbgOut->Write( pDat, nDbgLen );
6641 						pGrStream->SeekRel( -nDbgLen );
6642 						delete[] pDat;
6643 					}
6644 				}
6645 
6646 				delete pDbgOut;
6647 			}
6648 		}
6649 #endif
6650 
6651 		if( ( nInst & 0xFFFE ) == 0x7A8 )
6652 		{	// DIBs direkt holen
6653 			Bitmap aNew;
6654 			if( ReadDIB(aNew, *pGrStream, false) )
6655 			{
6656 				rData = Graphic( aNew );
6657 				nRes = GRFILTER_OK;
6658 			}
6659 		}
6660 		else
6661 		{	// und unsere feinen Filter darauf loslassen
6662 			GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
6663 			String aEmptyStr;
6664 			nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW );
6665 
6666 			// SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems,
6667 			// then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the
6668 			// scaling has been implemented does not happen anymore.
6669 			//
6670 			// For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the
6671 			// dxarray is empty (this has been solved in wmf/emf but not for pict)
6672 			if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) )
6673 			{
6674 				if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) )
6675 				{	// #75956#, scaling does not work properly, if the graphic is less than 1cm
6676 					GDIMetaFile	aMtf( rData.GetGDIMetaFile() );
6677 					const Size	aOldSize( aMtf.GetPrefSize() );
6678 
6679 					if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) &&
6680 						aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) )
6681 					{
6682 						aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(),
6683 									(double) aMtfSize100.Height() / aOldSize.Height() );
6684 						aMtf.SetPrefSize( aMtfSize100 );
6685 						aMtf.SetPrefMapMode( MAP_100TH_MM );
6686 						rData = aMtf;
6687 					}
6688 				}
6689 			}
6690 		}
6691 		// ggfs. Fehlerstatus zuruecksetzen
6692 		if ( ERRCODE_IO_PENDING == pGrStream->GetError() )
6693 		  pGrStream->ResetError();
6694 		delete pOut;
6695 	}
6696 	rBLIPStream.Seek( nOldPos );    // alte FilePos des Streams restaurieren
6697 
6698 	return ( GRFILTER_OK == nRes ); // Ergebniss melden
6699 }
6700 
6701 /* static */
6702 sal_Bool SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn)
6703 {
6704 	rRec.nFilePos = rIn.Tell();
6705 	return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer,
6706 													rRec.nRecInstance,
6707 													rRec.nRecType,
6708 													rRec.nRecLen );
6709 }
6710 
6711 
6712 /* auch static */
6713 sal_Bool SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt,
6714 											  sal_uInt8&     rVer,
6715 											  sal_uInt16&   rInst,
6716 											  sal_uInt16&   rFbt,
6717 											  sal_uInt32&    rLength )
6718 {
6719 	sal_uInt16 nTmp;
6720 	rSt >> nTmp >> rFbt >> rLength;
6721 	rVer = sal::static_int_cast< sal_uInt8 >(nTmp & 15);
6722 	rInst = nTmp >> 4;
6723 	if ( rLength > ( SAL_MAX_UINT32 - rSt.Tell() ) )	// preserving overflow, optimal would be to check
6724 		rSt.SetError( SVSTREAM_FILEFORMAT_ERROR );		// the record size against the parent header
6725 	return rSt.GetError() == 0;
6726 }
6727 
6728 
6729 
6730 
6731 sal_Bool SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, sal_uLong nDatLen,
6732 										  char*& rpBuff, sal_uInt32& rBuffLen ) const
6733 {
6734 	if( nDatLen )
6735 	{
6736 		rpBuff = new (std::nothrow) char[ nDatLen ];
6737 		rBuffLen = nDatLen;
6738 		rStData.Read( rpBuff, nDatLen );
6739 	}
6740 	return sal_True;
6741 }
6742 
6743 sal_Bool SvxMSDffManager::ProcessClientData(SvStream& rStData, sal_uLong nDatLen,
6744 										char*& rpBuff, sal_uInt32& rBuffLen ) const
6745 {
6746 	if( nDatLen )
6747 	{
6748 		rpBuff = new (std::nothrow) char[ nDatLen ];
6749 		if ( rpBuff )
6750 		{
6751 			rBuffLen = nDatLen;
6752 			rStData.Read( rpBuff, nDatLen );
6753 		}
6754 	}
6755 	return sal_True;
6756 }
6757 
6758 
6759 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ )
6760 {
6761 	return;  // wird von SJ im Draw ueberladen
6762 }
6763 
6764 sal_uLong SvxMSDffManager::Calc_nBLIPPos( sal_uLong nOrgVal, sal_uLong /* nStreamPos */ ) const
6765 {
6766 	return nOrgVal;
6767 }
6768 
6769 sal_Bool SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const
6770 {
6771 	return sal_False;
6772 }
6773 
6774 sal_Bool SvxMSDffManager::ShapeHasText( sal_uLong /* nShapeId */, sal_uLong /* nFilePos */ ) const
6775 {
6776 	return sal_True;
6777 }
6778 
6779 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup>
6780 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId,
6781                                        const Graphic& rGrf,
6782                                        const Rectangle& rBoundRect,
6783 									   const Rectangle& rVisArea,
6784                                        const int /* _nCalledByGroup */,
6785 									   sal_Int64 nAspect ) const
6786 // <--
6787 {
6788     SdrObject* pRet = 0;
6789 	String sStorageName;
6790     SvStorageRef xSrcStg;
6791     ErrCode nError = ERRCODE_NONE;
6792     uno::Reference < embed::XStorage > xDstStg;
6793 	if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
6794 		pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg,
6795                                         rGrf, rBoundRect, rVisArea, pStData, nError,
6796 										nSvxMSDffOLEConvFlags, nAspect );
6797 	return pRet;
6798 }
6799 
6800 sal_Bool SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf )
6801 {
6802 	String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) );
6803 	SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream );
6804 	xStm->SetVersion( pStor->GetVersion() );
6805 	xStm->SetBufferSize( 8192 );
6806 
6807     sal_uInt16 nAspect = ASPECT_CONTENT;
6808     sal_uLong nAdviseModes = 2;
6809 
6810 	Impl_OlePres aEle( FORMAT_GDIMETAFILE );
6811 	// Die Groesse in 1/100 mm umrechnen
6812 	// Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird,
6813 	// versucht SV einen BestMatchden richtigen Wert zu raten.
6814 	Size aSize = rMtf.GetPrefSize();
6815 	MapMode aMMSrc = rMtf.GetPrefMapMode();
6816 	MapMode aMMDst( MAP_100TH_MM );
6817 	aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
6818 	aEle.SetSize( aSize );
6819  	aEle.SetAspect( nAspect );
6820 	aEle.SetAdviseFlags( nAdviseModes );
6821 	aEle.SetMtf( rMtf );
6822     aEle.Write( *xStm );
6823 
6824 	xStm->SetBufferSize( 0 );
6825 	return xStm->GetError() == SVSTREAM_OK;
6826 }
6827 
6828 struct ClsIDs {
6829 	sal_uInt32		nId;
6830 	const sal_Char* pSvrName;
6831 	const sal_Char* pDspName;
6832 };
6833 static ClsIDs aClsIDs[] = {
6834 
6835 	{ 0x000212F0, "MSWordArt",     		"Microsoft Word Art"	 		},
6836 	{ 0x000212F0, "MSWordArt.2",   		"Microsoft Word Art 2.0" 		},
6837 
6838 	// MS Apps
6839 	{ 0x00030000, "ExcelWorksheet",		"Microsoft Excel Worksheet"		},
6840 	{ 0x00030001, "ExcelChart",			"Microsoft Excel Chart"			},
6841 	{ 0x00030002, "ExcelMacrosheet",	"Microsoft Excel Macro"			},
6842 	{ 0x00030003, "WordDocument",		"Microsoft Word Document"		},
6843 	{ 0x00030004, "MSPowerPoint",		"Microsoft PowerPoint"			},
6844 	{ 0x00030005, "MSPowerPointSho",	"Microsoft PowerPoint Slide Show"},
6845 	{ 0x00030006, "MSGraph",			"Microsoft Graph"				},
6846 	{ 0x00030007, "MSDraw",				"Microsoft Draw"				},
6847 	{ 0x00030008, "Note-It",			"Microsoft Note-It"				},
6848 	{ 0x00030009, "WordArt",			"Microsoft Word Art"			},
6849 	{ 0x0003000a, "PBrush",				"Microsoft PaintBrush Picture"	},
6850 	{ 0x0003000b, "Equation",			"Microsoft Equation Editor"		},
6851 	{ 0x0003000c, "Package",			"Package"						},
6852 	{ 0x0003000d, "SoundRec",			"Sound"							},
6853 	{ 0x0003000e, "MPlayer",			"Media Player"					},
6854 	// MS Demos
6855 	{ 0x0003000f, "ServerDemo",			"OLE 1.0 Server Demo"			},
6856 	{ 0x00030010, "Srtest",				"OLE 1.0 Test Demo"				},
6857 	{ 0x00030011, "SrtInv",				"OLE 1.0 Inv Demo"				},
6858 	{ 0x00030012, "OleDemo",			"OLE 1.0 Demo"					},
6859 
6860 	// Coromandel / Dorai Swamy / 718-793-7963
6861 	{ 0x00030013, "CoromandelIntegra",	"Coromandel Integra"			},
6862 	{ 0x00030014, "CoromandelObjServer","Coromandel Object Server"		},
6863 
6864 	// 3-d Visions Corp / Peter Hirsch / 310-325-1339
6865 	{ 0x00030015, "StanfordGraphics",	"Stanford Graphics"				},
6866 
6867 	// Deltapoint / Nigel Hearne / 408-648-4000
6868 	{ 0x00030016, "DGraphCHART",		"DeltaPoint Graph Chart"		},
6869 	{ 0x00030017, "DGraphDATA",			"DeltaPoint Graph Data"			},
6870 
6871 	// Corel / Richard V. Woodend / 613-728-8200 x1153
6872 	{ 0x00030018, "PhotoPaint",			"Corel PhotoPaint"				},
6873 	{ 0x00030019, "CShow",				"Corel Show"					},
6874 	{ 0x0003001a, "CorelChart",			"Corel Chart"					},
6875 	{ 0x0003001b, "CDraw",				"Corel Draw"					},
6876 
6877 	// Inset Systems / Mark Skiba / 203-740-2400
6878 	{ 0x0003001c, "HJWIN1.0",			"Inset Systems"					},
6879 
6880 	// Mark V Systems / Mark McGraw / 818-995-7671
6881 	{ 0x0003001d, "ObjMakerOLE",		"MarkV Systems Object Maker"	},
6882 
6883 	// IdentiTech / Mike Gilger / 407-951-9503
6884 	{ 0x0003001e, "FYI",				"IdentiTech FYI"				},
6885 	{ 0x0003001f, "FYIView",			"IdentiTech FYI Viewer"			},
6886 
6887 	// Inventa Corporation / Balaji Varadarajan / 408-987-0220
6888 	{ 0x00030020, "Stickynote",			"Inventa Sticky Note"			},
6889 
6890 	// ShapeWare Corp. / Lori Pearce / 206-467-6723
6891 	{ 0x00030021, "ShapewareVISIO10",   "Shapeware Visio 1.0"			},
6892 	{ 0x00030022, "ImportServer",		"Spaheware Import Server"		},
6893 
6894 	// test app SrTest
6895 	{ 0x00030023, "SrvrTest",			"OLE 1.0 Server Test"			},
6896 
6897 	// test app ClTest.  Doesn't really work as a server but is in reg db
6898 	{ 0x00030025, "Cltest",				"OLE 1.0 Client Test"			},
6899 
6900 	// Microsoft ClipArt Gallery   Sherry Larsen-Holmes
6901 	{ 0x00030026, "MS_ClipArt_Gallery",	"Microsoft ClipArt Gallery"		},
6902 	// Microsoft Project  Cory Reina
6903 	{ 0x00030027, "MSProject",			"Microsoft Project"				},
6904 
6905 	// Microsoft Works Chart
6906 	{ 0x00030028, "MSWorksChart",		"Microsoft Works Chart"			},
6907 
6908 	// Microsoft Works Spreadsheet
6909 	{ 0x00030029, "MSWorksSpreadsheet",	"Microsoft Works Spreadsheet"	},
6910 
6911 	// AFX apps - Dean McCrory
6912 	{ 0x0003002A, "MinSvr",				"AFX Mini Server"				},
6913 	{ 0x0003002B, "HierarchyList",		"AFX Hierarchy List"			},
6914 	{ 0x0003002C, "BibRef",				"AFX BibRef"					},
6915 	{ 0x0003002D, "MinSvrMI",			"AFX Mini Server MI"			},
6916 	{ 0x0003002E, "TestServ",			"AFX Test Server"				},
6917 
6918 	// Ami Pro
6919 	{ 0x0003002F, "AmiProDocument",		"Ami Pro Document"				},
6920 
6921 	// WordPerfect Presentations For Windows
6922 	{ 0x00030030, "WPGraphics",			"WordPerfect Presentation"		},
6923 	{ 0x00030031, "WPCharts",			"WordPerfect Chart"				},
6924 
6925 	// MicroGrafx Charisma
6926 	{ 0x00030032, "Charisma",			"MicroGrafx Charisma"			},
6927 	{ 0x00030033, "Charisma_30",		"MicroGrafx Charisma 3.0"		},
6928 	{ 0x00030034, "CharPres_30",		"MicroGrafx Charisma 3.0 Pres"	},
6929 	// MicroGrafx Draw
6930 	{ 0x00030035, "Draw",				"MicroGrafx Draw"				},
6931 	// MicroGrafx Designer
6932 	{ 0x00030036, "Designer_40",		"MicroGrafx Designer 4.0"		},
6933 
6934 	// STAR DIVISION
6935 //	{ 0x000424CA, "StarMath",			"StarMath 1.0"					},
6936 	{ 0x00043AD2, "FontWork",			"Star FontWork"					},
6937 //	{ 0x000456EE, "StarMath2",			"StarMath 2.0"					},
6938 
6939 	{ 0, "", "" } };
6940 
6941 
6942 sal_Bool SvxMSDffManager::ConvertToOle2( SvStream& rStm, sal_uInt32 nReadLen,
6943 					const GDIMetaFile * pMtf, const SotStorageRef& rDest )
6944 {
6945 	sal_Bool bMtfRead = sal_False;
6946 	SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ),
6947 													STREAM_WRITE| STREAM_SHARE_DENYALL );
6948 	if( xOle10Stm->GetError() )
6949 		return sal_False;
6950 
6951 	sal_uInt32 nType;
6952 	sal_uInt32 nRecType;
6953 	sal_uInt32 nStrLen;
6954 	String aSvrName;
6955 	sal_uInt32 nDummy0;
6956 	sal_uInt32 nDummy1;
6957 	sal_uInt32 nDataLen;
6958 	sal_uInt8 * pData;
6959 	sal_uInt32 nBytesRead = 0;
6960 	do
6961 	{
6962 		rStm >> nType;
6963 		rStm >> nRecType;
6964 		rStm >> nStrLen;
6965 		if( nStrLen )
6966 		{
6967 			if( 0x10000L > nStrLen )
6968 			{
6969 				sal_Char * pBuf = new sal_Char[ nStrLen ];
6970 				rStm.Read( pBuf, nStrLen );
6971                 aSvrName.Assign( String( pBuf, (sal_uInt16) nStrLen-1, gsl_getSystemTextEncoding() ) );
6972                 delete[] pBuf;
6973 			}
6974 			else
6975 				break;
6976 		}
6977 		rStm >> nDummy0;
6978 		rStm >> nDummy1;
6979 		rStm >> nDataLen;
6980 
6981 		nBytesRead += 6 * sizeof( sal_uInt32 ) + nStrLen + nDataLen;
6982 
6983 		if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen )
6984 		{
6985 			if( xOle10Stm.Is() )
6986 			{
6987 				pData = new sal_uInt8[ nDataLen ];
6988 				if( !pData )
6989 					return sal_False;
6990 
6991 				rStm.Read( pData, nDataLen );
6992 
6993 				// write to ole10 stream
6994 				*xOle10Stm << nDataLen;
6995 				xOle10Stm->Write( pData, nDataLen );
6996 				xOle10Stm = SotStorageStreamRef();
6997 
6998 				// set the compobj stream
6999 				ClsIDs* pIds;
7000 				for( pIds = aClsIDs; pIds->nId; pIds++ )
7001 				{
7002 					if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) )
7003 						break;
7004 				}
7005 //				SvGlobalName* pClsId = NULL;
7006 				String aShort, aFull;
7007 				if( pIds->nId )
7008 				{
7009 					// gefunden!
7010 					sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName );
7011 					rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt,
7012 									String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) );
7013 				}
7014 				else
7015 				{
7016 					sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName );
7017 					rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName );
7018 				}
7019 
7020                 delete[] pData;
7021 			}
7022 			else if( nRecType == 5 && !pMtf )
7023 			{
7024 				sal_uLong nPos = rStm.Tell();
7025 				sal_uInt16 sz[4];
7026 				rStm.Read( sz, 8 );
7027 				//rStm.SeekRel( 8 );
7028 				Graphic aGraphic;
7029 				if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() )
7030 				{
7031 					const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
7032 					MakeContentStream( rDest, rMtf );
7033 					bMtfRead = sal_True;
7034 				}
7035 				// set behind the data
7036 				rStm.Seek( nPos + nDataLen );
7037             }
7038 			else
7039 				rStm.SeekRel( nDataLen );
7040 		}
7041 	} while( !rStm.IsEof() && nReadLen >= nBytesRead );
7042 
7043 	if( !bMtfRead && pMtf )
7044 	{
7045 		MakeContentStream( rDest, *pMtf );
7046 		return sal_True;
7047     }
7048 
7049 	return sal_False;
7050 }
7051 
7052 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName )
7053 {
7054 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 )
7055 	  || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
7056         return "swriter";
7057 	else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 )
7058 	  || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
7059         return "scalc";
7060 	else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 )
7061 	  || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
7062         return "simpress";
7063 	else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 )
7064       || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
7065         return "sdraw";
7066 	else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 )
7067       || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
7068         return "smath";
7069 	else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 )
7070 	  || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
7071         return "schart";
7072     return 0;
7073 }
7074 
7075 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
7076 {
7077 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) )
7078         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) );
7079 
7080 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
7081         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) );
7082 
7083 	if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) )
7084         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) );
7085 
7086 	if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
7087         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) );
7088 
7089 	if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
7090         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) );
7091 
7092 	if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
7093         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) );
7094 
7095 	if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
7096         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) );
7097 
7098     if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
7099         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) );
7100 
7101 	if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) )
7102         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) );
7103 
7104     if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
7105         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) );
7106 
7107 	if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
7108         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) );
7109 
7110 	if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
7111         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) );
7112 
7113     return ::rtl::OUString();
7114 }
7115 
7116 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >  SvxMSDffManager::CheckForConvertToSOObj( sal_uInt32 nConvertFlags,
7117                         SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage,
7118                         const Graphic& rGrf,
7119 						const Rectangle& rVisArea )
7120 {
7121     uno::Reference < embed::XEmbeddedObject > xObj;
7122     SvGlobalName aStgNm = rSrcStg.GetClassName();
7123     const char* pName = GetInternalServerName_Impl( aStgNm );
7124     String sStarName;
7125     if ( pName )
7126         sStarName = String::CreateFromAscii( pName );
7127     else if ( nConvertFlags )
7128     {
7129         static struct _ObjImpType
7130         {
7131             sal_uInt32 nFlag;
7132             const char* pFactoryNm;
7133             // GlobalNameId
7134             sal_uInt32 n1;
7135             sal_uInt16 n2, n3;
7136             sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15;
7137         } aArr[] = {
7138             { OLE_MATHTYPE_2_STARMATH, "smath",
7139                 0x0002ce02L, 0x0000, 0x0000,
7140                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7141             { OLE_MATHTYPE_2_STARMATH, "smath",
7142                 0x00021700L, 0x0000, 0x0000,
7143                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7144             { OLE_WINWORD_2_STARWRITER, "swriter",
7145                 0x00020906L, 0x0000, 0x0000,
7146                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7147             { OLE_EXCEL_2_STARCALC, "scalc",                // Excel table
7148                 0x00020810L, 0x0000, 0x0000,
7149                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7150             { OLE_EXCEL_2_STARCALC, "scalc",                // Excel chart
7151                 0x00020820L, 0x0000, 0x0000,
7152                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7153             // 114465: additional Excel OLE chart classId to above.
7154             { OLE_EXCEL_2_STARCALC, "scalc",
7155                 0x00020821L, 0x0000, 0x0000,
7156                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7157             { OLE_POWERPOINT_2_STARIMPRESS, "simpress",     // PowerPoint presentation
7158                 0x64818d10L, 0x4f9b, 0x11cf,
7159                 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7160             { OLE_POWERPOINT_2_STARIMPRESS, "simpress",     // PowerPoint slide
7161                 0x64818d11L, 0x4f9b, 0x11cf,
7162                 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7163             { 0, 0,
7164 			  0, 0, 0,
7165 			  0, 0, 0, 0, 0, 0, 0, 0 }
7166         };
7167 
7168         for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr )
7169         {
7170             if( nConvertFlags & pArr->nFlag )
7171             {
7172                 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3,
7173                                 pArr->b8, pArr->b9, pArr->b10, pArr->b11,
7174                                 pArr->b12, pArr->b13, pArr->b14, pArr->b15 );
7175 
7176                 if ( aStgNm == aTypeName )
7177                 {
7178                     sStarName = String::CreateFromAscii( pArr->pFactoryNm );
7179                     break;
7180                 }
7181             }
7182         }
7183     }
7184 
7185     if ( sStarName.Len() )
7186     {
7187         //TODO/MBA: check if (and when) storage and stream will be destroyed!
7188         const SfxFilter* pFilter = 0;
7189         SvMemoryStream* pStream = new SvMemoryStream;
7190         if ( pName )
7191         {
7192             // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also
7193             SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ );
7194             *xStr >> *pStream;
7195         }
7196         else
7197         {
7198             SfxFilterMatcher aMatch( sStarName );
7199             SotStorageRef xStorage = new SotStorage( sal_False, *pStream );
7200             rSrcStg.CopyTo( xStorage );
7201             xStorage->Commit();
7202             xStorage.Clear();
7203             String aType = SfxFilter::GetTypeFromStorage( rSrcStg );
7204             if ( aType.Len() )
7205                 pFilter = aMatch.GetFilter4EA( aType );
7206         }
7207 
7208         if ( pName || pFilter )
7209         {
7210             //Reuse current ole name
7211             String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7212             aDstStgName += String::CreateFromInt32(nMSOleObjCntr);
7213 
7214             ::rtl::OUString aFilterName;
7215             if ( pFilter )
7216                 aFilterName = pFilter->GetName();
7217             else
7218                 aFilterName = GetFilterNameFromClassID_Impl( aStgNm );
7219 
7220             uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2);
7221             aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
7222             uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream );
7223             aMedium[0].Value <<= xStream;
7224             aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
7225             aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
7226 
7227             if ( aFilterName.getLength() )
7228             {
7229                 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
7230                 aMedium[2].Value <<= aFilterName;
7231             }
7232 
7233             ::rtl::OUString aName( aDstStgName );
7234             comphelper::EmbeddedObjectContainer aCnt( rDestStorage );
7235             xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7236 
7237             if ( !xObj.is() )
7238             {
7239                 if( aFilterName.getLength() )
7240                 {
7241                     // throw the filter parameter away as workaround
7242                     aMedium.realloc( 2 );
7243                     xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7244                 }
7245 
7246                 if ( !xObj.is() )
7247                      return xObj;
7248             }
7249 
7250             // TODO/LATER: ViewAspect must be passed from outside!
7251             sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT;
7252 
7253             // JP 26.10.2001: Bug 93374 / 91928 the writer
7254             // objects need the correct visarea needs the
7255             // correct visarea, but this is not true for
7256             // PowerPoint (see bugdoc 94908b)
7257             // SJ: 19.11.2001 bug 94908, also chart objects
7258             // needs the correct visarea
7259 
7260 			// If pName is set this is an own embedded object, it should have the correct size internally
7261 			// TODO/LATER: it might make sence in future to set the size stored in internal object
7262             if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) )
7263             {
7264                 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) );
7265                 Size aSz;
7266 				if ( rVisArea.IsEmpty() )
7267 					aSz = lcl_GetPrefSize(rGrf, aMapMode );
7268 				else
7269 				{
7270 					aSz = rVisArea.GetSize();
7271 					aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode );
7272 				}
7273 
7274                 // don't modify the object
7275                 //TODO/LATER: remove those hacks, that needs to be done differently!
7276                 //xIPObj->EnableSetModified( sal_False );
7277                 awt::Size aSize;
7278                 aSize.Width = aSz.Width();
7279                 aSize.Height = aSz.Height();
7280                 xObj->setVisualAreaSize( nViewAspect, aSize );
7281                 //xIPObj->EnableSetModified( sal_True );
7282             }
7283             else if ( sStarName.EqualsAscii( "smath" ) )
7284             {   // SJ: force the object to recalc its visarea
7285                 //TODO/LATER: wait for PrinterChangeNotification
7286                 //xIPObj->OnDocumentPrinterChanged( NULL );
7287             }
7288         }
7289     }
7290 
7291     return xObj;
7292 }
7293 
7294 // TODO/MBA: code review and testing!
7295 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage(
7296 				const String& rStorageName,
7297 				SotStorageRef& rSrcStorage,
7298                 const uno::Reference < embed::XStorage >& xDestStorage,
7299 				const Graphic& rGrf,
7300 				const Rectangle& rBoundRect,
7301 				const Rectangle& rVisArea,
7302 				SvStream* pDataStrm,
7303                 ErrCode& rError,
7304 				sal_uInt32 nConvertFlags,
7305 				sal_Int64 nReccomendedAspect )
7306 {
7307 	sal_Int64 nAspect = nReccomendedAspect;
7308 	SdrOle2Obj* pRet = 0;
7309     if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() )
7310 	{
7311         comphelper::EmbeddedObjectContainer aCnt( xDestStorage );
7312 		// Ist der 01Ole-Stream ueberhaupt vorhanden ?
7313 		// ( ist er z.B. bei FontWork nicht )
7314 		// Wenn nicht -> Einbindung als Grafik
7315 		sal_Bool bValidStorage = sal_False;
7316 		String aDstStgName( String::CreateFromAscii(
7317 								RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7318 
7319 		aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr );
7320 
7321 		{
7322             SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName,
7323 								STREAM_READWRITE| STREAM_SHARE_DENYALL );
7324 			if( xObjStg.Is()  )
7325 			{
7326 				{
7327 					sal_uInt8 aTestA[10];	// exist the \1CompObj-Stream ?
7328 					SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream(
7329 								String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"),
7330 										RTL_TEXTENCODING_MS_1252 ));
7331 					bValidStorage = xSrcTst.Is() && sizeof( aTestA ) ==
7332 									xSrcTst->Read( aTestA, sizeof( aTestA ) );
7333 					if( !bValidStorage )
7334 					{
7335 						// or the \1Ole-Stream ?
7336 						xSrcTst = xObjStg->OpenSotStream(
7337 									String(RTL_CONSTASCII_STRINGPARAM("\1Ole"),
7338 											RTL_TEXTENCODING_MS_1252 ));
7339 						bValidStorage = xSrcTst.Is() && sizeof(aTestA) ==
7340 										xSrcTst->Read(aTestA, sizeof(aTestA));
7341 					}
7342 				}
7343 
7344                 if( bValidStorage )
7345 				{
7346 					if ( nAspect != embed::Aspects::MSOLE_ICON )
7347 					{
7348 						// check whether the object is iconified one
7349 						// usually this information is already known, the only exception
7350 						// is a kind of embedded objects in Word documents
7351 						// TODO/LATER: should the caller be notified if the aspect changes in future?
7352 
7353 						SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream(
7354 							String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ),
7355 							STREAM_STD_READ | STREAM_NOCREATE );
7356 						if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
7357 						{
7358 							sal_uInt8 nByte = 0;
7359 							*xObjInfoSrc >> nByte;
7360 							if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
7361 								nAspect = embed::Aspects::MSOLE_ICON;
7362 						}
7363 					}
7364 
7365                     uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj(
7366                                 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea ));
7367                     if ( xObj.is() )
7368     			    {
7369                         svt::EmbeddedObjectRef aObj( xObj, nAspect );
7370 
7371                         // TODO/LATER: need MediaType
7372                         aObj.SetGraphic( rGrf, ::rtl::OUString() );
7373 
7374                         // TODO/MBA: check setting of PersistName
7375                         pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false);
7376 						// we have the Object, don't create another
7377 						bValidStorage = false;
7378                     }
7379 				}
7380 			}
7381 		}
7382 
7383 		if( bValidStorage )
7384 		{
7385             // object is not an own object
7386             SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE );
7387 
7388 			if ( xObjStor.Is() )
7389 			{
7390 				SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ );
7391 				xSrcStor->CopyTo( xObjStor );
7392 
7393 				if( !xObjStor->GetError() )
7394 					xObjStor->Commit();
7395 
7396 				if( xObjStor->GetError() )
7397 				{
7398 				    rError = xObjStor->GetError();
7399 					bValidStorage = sal_False;
7400 				}
7401 				else if( !xObjStor.Is() )
7402 					bValidStorage = sal_False;
7403 			}
7404 		}
7405 		else if( pDataStrm )
7406 		{
7407 			sal_uInt32 nLen, nDummy;
7408 			*pDataStrm >> nLen >> nDummy;
7409 			if( SVSTREAM_OK != pDataStrm->GetError() ||
7410 				// Id in BugDoc - exist there other Ids?
7411 				// The ConvertToOle2 - does not check for consistent
7412 				0x30008 != nDummy )
7413 				bValidStorage = sal_False;
7414 			else
7415 			{
7416 				// or is it an OLE-1 Stream in the DataStream?
7417                 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName );
7418                 //TODO/MBA: remove metafile conversion from ConvertToOle2
7419                 //when is this code used?!
7420 				GDIMetaFile aMtf;
7421                 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor );
7422                 xObjStor->Commit();
7423 			}
7424         }
7425 
7426 		if( bValidStorage )
7427 		{
7428             uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName );
7429             if( xObj.is() )
7430             {
7431                 // the visual area must be retrieved from the metafile (object doesn't know it so far)
7432 
7433 				if ( nAspect != embed::Aspects::MSOLE_ICON )
7434 				{
7435                 	// working with visual area can switch the object to running state
7436                 	awt::Size aAwtSz;
7437 					try
7438 					{
7439 						// the provided visual area should be used, if there is any
7440 						if ( rVisArea.IsEmpty() )
7441 						{
7442                 			MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
7443                 			Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit)));
7444                 			aAwtSz.Width = aSz.Width();
7445                 			aAwtSz.Height = aSz.Height();
7446 						}
7447 						else
7448 						{
7449 							aAwtSz.Width = rVisArea.GetWidth();
7450 							aAwtSz.Height = rVisArea.GetHeight();
7451 						}
7452                 		//xInplaceObj->EnableSetModified( sal_False );
7453                 		xObj->setVisualAreaSize( nAspect, aAwtSz );
7454                 		//xInplaceObj->EnableSetModified( sal_True );*/
7455 					}
7456 					catch( uno::Exception& )
7457 					{
7458 						OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" );
7459 					}
7460 				}
7461 
7462                 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7463 
7464                 // TODO/LATER: need MediaType
7465                 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7466 
7467                 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false);
7468             }
7469 		}
7470 	}
7471 
7472 	return pRet;
7473 }
7474 
7475 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const
7476 {
7477 	SdrObject* pRet = NULL;
7478 
7479 	if(120 >= sal_uInt16(eTyp))
7480 	{
7481 		pRet = new SdrRectObj();
7482 	}
7483 
7484 	DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM");
7485 
7486 	return pRet;
7487 }
7488 
7489 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
7490 			const String& rPropName, sal_Bool bTestPropertyAvailability )
7491 {
7492     sal_Bool bRetValue = sal_True;
7493 	if ( bTestPropertyAvailability )
7494 	{
7495 		bRetValue = sal_False;
7496 		try
7497 		{
7498 			uno::Reference< beans::XPropertySetInfo >
7499 				aXPropSetInfo( rXPropSet->getPropertySetInfo() );
7500 			if ( aXPropSetInfo.is() )
7501 				bRetValue = aXPropSetInfo->hasPropertyByName( rPropName );
7502 		}
7503 		catch( uno::Exception& )
7504 		{
7505 			bRetValue = sal_False;
7506 		}
7507 	}
7508 	if ( bRetValue )
7509 	{
7510 		try
7511 		{
7512 			rXPropSet->setPropertyValue( rPropName, rAny );
7513 			bRetValue = sal_True;
7514 		}
7515 		catch( uno::Exception& )
7516 		{
7517 			bRetValue = sal_False;
7518 		}
7519 	}
7520     return bRetValue;
7521 }
7522 
7523 SvxMSDffImportRec::SvxMSDffImportRec()
7524     : pObj( 0 ),
7525       pWrapPolygon(0),
7526       pClientAnchorBuffer( 0 ),
7527       nClientAnchorLen(  0 ),
7528       pClientDataBuffer( 0 ),
7529       nClientDataLen(    0 ),
7530       nXAlign( 0 ),	// position n cm from left
7531       nXRelTo( 2 ), //   relative to column
7532       nYAlign( 0 ), // position n cm below
7533       nYRelTo( 2 ), //   relative to paragraph
7534       nLayoutInTableCell( 0 ), // element is laid out in table cell
7535       nTextRotationAngle( 0 ),
7536       nDxTextLeft( 144 ),
7537       nDyTextTop( 72 ),
7538       nDxTextRight(	144 ),
7539       nDyTextBottom( 72 ),
7540       nDxWrapDistLeft( 0 ),
7541       nDyWrapDistTop( 0 ),
7542       nDxWrapDistRight( 0 ),
7543       nDyWrapDistBottom(0 ),
7544       nCropFromTop( 0 ),
7545       nCropFromBottom( 0 ),
7546       nCropFromLeft( 0 ),
7547       nCropFromRight( 0 ),
7548       aTextId( 0, 0 ),
7549       nNextShapeId(	0 ),
7550       nShapeId( 0 ),
7551       eShapeType( mso_sptNil )
7552 {
7553       eLineStyle      = mso_lineSimple; // GPF-Bug #66227#
7554       bDrawHell       = sal_False;
7555       bHidden         = sal_False;
7556 //	  bInGroup		  = sal_False;
7557       bReplaceByFly   = sal_False;
7558       bLastBoxInChain = sal_True;
7559       bHasUDefProp    = sal_False; // was the DFF_msofbtUDefProp record set?
7560       bVFlip = sal_False;
7561       bHFlip = sal_False;
7562       bAutoWidth      = sal_False;
7563 }
7564 
7565 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy)
7566     : pObj(	rCopy.pObj ),
7567       nXAlign( rCopy.nXAlign ),
7568       nXRelTo( rCopy.nXRelTo ),
7569       nYAlign( rCopy.nYAlign ),
7570       nYRelTo( rCopy.nYRelTo ),
7571       nLayoutInTableCell( rCopy.nLayoutInTableCell ),
7572       nTextRotationAngle( rCopy.nTextRotationAngle ),
7573       nDxTextLeft( rCopy.nDxTextLeft	),
7574       nDyTextTop( rCopy.nDyTextTop ),
7575       nDxTextRight( rCopy.nDxTextRight ),
7576       nDyTextBottom( rCopy.nDyTextBottom ),
7577       nDxWrapDistLeft( rCopy.nDxWrapDistLeft ),
7578       nDyWrapDistTop( rCopy.nDyWrapDistTop ),
7579       nDxWrapDistRight( rCopy.nDxWrapDistRight ),
7580       nDyWrapDistBottom(rCopy.nDyWrapDistBottom ),
7581       nCropFromTop( rCopy.nCropFromTop ),
7582       nCropFromBottom( rCopy.nCropFromBottom ),
7583       nCropFromLeft( rCopy.nCropFromLeft ),
7584       nCropFromRight( rCopy.nCropFromRight ),
7585       aTextId( rCopy.aTextId ),
7586       nNextShapeId( rCopy.nNextShapeId ),
7587       nShapeId( rCopy.nShapeId ),
7588       eShapeType( rCopy.eShapeType )
7589 {
7590     eLineStyle       = rCopy.eLineStyle; // GPF-Bug #66227#
7591     bDrawHell        = rCopy.bDrawHell;
7592     bHidden          = rCopy.bHidden;
7593 //			bInGroup		 = rCopy.bInGroup;
7594     bReplaceByFly    = rCopy.bReplaceByFly;
7595     bAutoWidth       = rCopy.bAutoWidth;
7596     bLastBoxInChain  = rCopy.bLastBoxInChain;
7597     bHasUDefProp     = rCopy.bHasUDefProp;
7598     bVFlip = rCopy.bVFlip;
7599     bHFlip = rCopy.bHFlip;
7600     nClientAnchorLen = rCopy.nClientAnchorLen;
7601     if( rCopy.nClientAnchorLen )
7602     {
7603         pClientAnchorBuffer = new char[ nClientAnchorLen ];
7604         memcpy( pClientAnchorBuffer,
7605                 rCopy.pClientAnchorBuffer,
7606                 nClientAnchorLen );
7607     }
7608     else
7609         pClientAnchorBuffer = 0;
7610 
7611     nClientDataLen = rCopy.nClientDataLen;
7612     if( rCopy.nClientDataLen )
7613     {
7614         pClientDataBuffer = new char[ nClientDataLen ];
7615         memcpy( pClientDataBuffer,
7616                 rCopy.pClientDataBuffer,
7617                 nClientDataLen );
7618     }
7619     else
7620         pClientDataBuffer = 0;
7621 
7622     if (rCopy.pWrapPolygon)
7623         pWrapPolygon = new Polygon(*rCopy.pWrapPolygon);
7624     else
7625         pWrapPolygon = 0;
7626 }
7627 
7628 SvxMSDffImportRec::~SvxMSDffImportRec()
7629 {
7630     if (pClientAnchorBuffer)
7631         delete[] pClientAnchorBuffer;
7632     if (pClientDataBuffer)
7633         delete[] pClientDataBuffer;
7634     if (pWrapPolygon)
7635         delete pWrapPolygon;
7636 }
7637 
7638 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
7639 
7640 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape )
7641 {
7642 	maShapeIdContainer[nShapeId] = pShape;
7643 }
7644 
7645 void SvxMSDffManager::removeShapeId( SdrObject* pShape )
7646 {
7647 	SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() );
7648 	const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() );
7649 	while( aIter != aEnd )
7650 	{
7651 		if( (*aIter).second == pShape )
7652 		{
7653 			maShapeIdContainer.erase( aIter );
7654 			break;
7655 		}
7656 		aIter++;
7657 	}
7658 }
7659 
7660 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId )
7661 {
7662 	SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) );
7663 	return aIter != maShapeIdContainer.end() ? (*aIter).second : 0;
7664 }
7665