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