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