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 || IsProperty( DFF_Prop_pVertices ) )
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 						Point aStartPt( 0,0 );
4504 						if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) )
4505 						{
4506 							sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength();
4507 							XPolygon aXP( (sal_uInt16)nNumElemVert );
4508 //								const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
4509 							for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ )
4510 							{
4511 								Point aP;
4512 								sal_Int32 nX = 0, nY = 0;
4513 								seqCoordinates[ nPtNum ].First.Value >>= nX;
4514 								seqCoordinates[ nPtNum ].Second.Value >>= nY;
4515 								aP.X() = nX;
4516 								aP.Y() = nY;
4517 								aXP[ (sal_uInt16)nPtNum ] = aP;
4518 							}
4519 							aPolyBoundRect = Rectangle( aXP.GetBoundRect() );
4520 							if ( nNumElemVert >= 3 )
4521 							{ // arc first command is always wr -- clockwise arc
4522 								// the parameters are : (left,top),(right,bottom),start(x,y),end(x,y)
4523 								aStartPt = aXP[2];
4524 							}
4525 						}
4526 						else
4527 							aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 );	// defaulting
4528 
4529 						// clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry
4530 						aGeometryItem.ClearPropertyValue( sHandles );
4531 						aGeometryItem.ClearPropertyValue( sEquations );
4532 						aGeometryItem.ClearPropertyValue( sViewBox );
4533 						aGeometryItem.ClearPropertyValue( sPath );
4534 
4535 						sal_Int32 nEndAngle = 9000;
4536 						sal_Int32 nStartAngle = 0;
4537 						pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
4538 						if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 )
4539 						{
4540 							double fNumber;
4541 							if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
4542 							{
4543 								seqAdjustmentValues[ 0 ].Value >>= fNumber;
4544 								nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4545 							}
4546 							else
4547 							{
4548 								fNumber = 270.0;
4549 								//normal situation:if endAngle != 90,there will be a direct_value,but for damaged curve,the endAngle need to recalculate.
4550 								Point cent = aPolyBoundRect.Center();
4551 								if ( aStartPt.Y() == cent.Y() )
4552 									fNumber = ( aStartPt.X() >= cent.X() ) ? 0:180.0;
4553 								else if ( aStartPt.X() == cent.X() )
4554 									fNumber = ( aStartPt.Y() >= cent.Y() ) ? 90.0: 270.0;
4555 								else
4556 								{
4557 									fNumber = atan2( double( aStartPt.X() - cent.X() ),double( aStartPt.Y() - cent.Y() ) )+ F_PI; // 0..2PI
4558 									fNumber /= F_PI180; // 0..360.0
4559 								}
4560 								nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4561 								seqAdjustmentValues[ 0 ].Value <<= fNumber;
4562 								seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;		// so this value will properly be stored
4563 							}
4564 
4565 							if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
4566 							{
4567 								seqAdjustmentValues[ 1 ].Value >>= fNumber;
4568 								nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4569 							}
4570 							else
4571 							{
4572 								fNumber = 0.0;
4573 								seqAdjustmentValues[ 1 ].Value <<= fNumber;
4574 								seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
4575 							}
4576 
4577 							PropertyValue aPropVal;
4578 							aPropVal.Name = sAdjustmentValues;
4579 							aPropVal.Value <<= seqAdjustmentValues;
4580 							aGeometryItem.SetPropertyValue( aPropVal );		// storing the angle attribute
4581 						}
4582 						if ( nStartAngle != nEndAngle )
4583 						{
4584 							XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2,
4585 								(sal_uInt16)nStartAngle / 10, (sal_uInt16)nEndAngle / 10, sal_True );
4586 							Rectangle aPolyPieRect( aXPoly.GetBoundRect() );
4587 
4588 							double	fYScale, fXScale;
4589 							double	fYOfs, fXOfs;
4590 
4591 							Point aP( aObjData.aBoundRect.Center() );
4592 							Size aS( aObjData.aBoundRect.GetSize() );
4593 							aP.X() -= aS.Width() / 2;
4594 							aP.Y() -= aS.Height() / 2;
4595 							Rectangle aLogicRect( aP, aS );
4596 
4597 							fYOfs = fXOfs = 0.0;
4598 
4599 							if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() )
4600 							{
4601 								fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth();
4602 								if ( nSpFlags & SP_FFLIPH )
4603 									fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale;
4604 								else
4605 									fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale;
4606 							}
4607 							if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() )
4608 							{
4609 								fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight();
4610 								if ( nSpFlags & SP_FFLIPV )
4611 									fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale;
4612 								else
4613 									fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale;
4614 							}
4615 
4616 							fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth();
4617 							fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight();
4618 
4619 							Rectangle aOldBoundRect( aObjData.aBoundRect );
4620 							aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ),
4621 							 	Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) );
4622 
4623 							// creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system
4624 							double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth();
4625 							double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight();
4626 							sal_Int32 nLeft  = (sal_Int32)(( aPolyPieRect.Left()  - aPolyBoundRect.Left() ) * fTextFrameScaleX );
4627 							sal_Int32 nTop   = (sal_Int32)(( aPolyPieRect.Top()   - aPolyBoundRect.Top() )  * fTextFrameScaleY );
4628 							sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
4629 							sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() )  * fTextFrameScaleY );
4630 							com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 );
4631 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First,	   nLeft );
4632 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second,    nTop );
4633 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight );
4634 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom );
4635 							PropertyValue aProp;
4636 							aProp.Name = sTextFrames;
4637 							aProp.Value <<= aTextFrame;
4638 							aGeometryItem.SetPropertyValue( sPath, aProp );
4639 
4640 							// sj: taking care of the different rotation points, since the new arc is having a bigger snaprect
4641 							if ( mnFix16Angle )
4642 							{
4643 								sal_Int32 nAngle = mnFix16Angle;
4644 								if ( nSpFlags & SP_FFLIPH )
4645 									nAngle = 36000 - nAngle;
4646 								if ( nSpFlags & SP_FFLIPV )
4647 									nAngle = -nAngle;
4648 								double a = nAngle * F_PI18000;
4649 								double ss = sin( a );
4650 								double cc = cos( a );
4651 								Point aP1( aOldBoundRect.TopLeft() );
4652 								Point aC1( aObjData.aBoundRect.Center() );
4653 								Point aP2( aOldBoundRect.TopLeft() );
4654 								Point aC2( aOldBoundRect.Center() );
4655 								RotatePoint( aP1, aC1, ss, cc );
4656 								RotatePoint( aP2, aC2, ss, cc );
4657 								aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() );
4658 							}
4659 						}
4660 						((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem );
4661 						((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
4662 
4663 						// now setting a new name, so the above correction is only done once when importing from ms
4664 						SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
4665 						const rtl::OUString	sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
4666 						const rtl::OUString	sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) );
4667 						PropertyValue aPropVal;
4668 						aPropVal.Name = sType;
4669 						aPropVal.Value <<= sName;
4670 						aGeoName.SetPropertyValue( aPropVal );
4671 						((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName );
4672 					}
4673 					else
4674 						((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
4675 
4676 					pRet->SetSnapRect( aObjData.aBoundRect );
4677 					EnhancedCustomShape2d aCustomShape2d( pRet );
4678 					aTextRect = aCustomShape2d.GetTextRect();
4679 
4680 					bIsCustomShape = sal_True;
4681 
4682 					if( bIsConnector )
4683 					{
4684 						if( nObjectRotation )
4685 						{
4686 							double a = nObjectRotation * nPi180;
4687 							pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
4688 						}
4689 						// Horizontal gespiegelt?
4690 						if ( nSpFlags & SP_FFLIPH )
4691 						{
4692 							Rectangle aBndRect( pRet->GetSnapRect() );
4693 							Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
4694 							Point aBottom( aTop.X(), aTop.Y() + 1000 );
4695 							pRet->NbcMirror( aTop, aBottom );
4696 						}
4697 						// Vertikal gespiegelt?
4698 						if ( nSpFlags & SP_FFLIPV )
4699 						{
4700 							Rectangle aBndRect( pRet->GetSnapRect() );
4701 							Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
4702 							Point aRight( aLeft.X() + 1000, aLeft.Y() );
4703 							pRet->NbcMirror( aLeft, aRight );
4704 						}
4705 						basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) );
4706                         SdrObject::Free( pRet );
4707 
4708 						pRet = new SdrEdgeObj();
4709 						ApplyAttributes( rSt, aSet, aObjData );
4710 						pRet->SetLogicRect( aObjData.aBoundRect );
4711 						pRet->SetMergedItemSet(aSet);
4712 
4713 						// Konnektoren
4714 						MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight );
4715 
4716 						((SdrEdgeObj*)pRet)->ConnectToNode(sal_True, NULL);
4717 						((SdrEdgeObj*)pRet)->ConnectToNode(sal_False, NULL);
4718 
4719 						Point aPoint1( aObjData.aBoundRect.TopLeft() );
4720 						Point aPoint2( aObjData.aBoundRect.BottomRight() );
4721 
4722 						// Rotationen beachten
4723 						if ( nObjectRotation )
4724 						{
4725 							double a = nObjectRotation * nPi180;
4726 							Point aCenter( aObjData.aBoundRect.Center() );
4727 							double ss = sin(a);
4728 							double cc = cos(a);
4729 
4730 							RotatePoint(aPoint1, aCenter, ss, cc);
4731 							RotatePoint(aPoint2, aCenter, ss, cc);
4732 						}
4733 
4734 						// Linie innerhalb des Bereiches zurechtdrehen/spiegeln
4735 						if ( nSpFlags & SP_FFLIPH )
4736 						{
4737 							sal_Int32 n = aPoint1.X();
4738 							aPoint1.X() = aPoint2.X();
4739 							aPoint2.X() = n;
4740 						}
4741 						if ( nSpFlags & SP_FFLIPV )
4742 						{
4743 							sal_Int32 n = aPoint1.Y();
4744 							aPoint1.Y() = aPoint2.Y();
4745 							aPoint2.Y() = n;
4746 						}
4747 						nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH );
4748 
4749 						pRet->NbcSetPoint(aPoint1, 0L);	// Startpunkt
4750 						pRet->NbcSetPoint(aPoint2, 1L);	// Endpunkt
4751 
4752 						sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist;
4753 						n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0;
4754 						switch( eConnectorStyle )
4755 						{
4756 							case mso_cxstyleBent:
4757 							{
4758 								aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) );
4759 								n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630;
4760 							}
4761 							break;
4762 							case mso_cxstyleCurved:
4763 								aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) );
4764 							break;
4765 							default: // mso_cxstyleStraight || mso_cxstyleNone
4766 								aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) );
4767 							break;
4768 						}
4769 						aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) );
4770 						aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) );
4771 						aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) );
4772 						aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) );
4773 
4774 						((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly );
4775 						pRet->SetMergedItemSet( aSet );
4776 					}
4777 				}
4778 			}
4779 
4780 			if ( pRet )
4781 			{
4782 				if( nObjectRotation )
4783 				{
4784 					double a = nObjectRotation * nPi180;
4785 					pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
4786 				}
4787 				// Horizontal gespiegelt?
4788 				if ( nSpFlags & SP_FFLIPH )
4789 				{
4790 					Rectangle aBndRect( pRet->GetSnapRect() );
4791 					Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
4792 					Point aBottom( aTop.X(), aTop.Y() + 1000 );
4793 					pRet->NbcMirror( aTop, aBottom );
4794 				}
4795 				// Vertikal gespiegelt?
4796 				if ( nSpFlags & SP_FFLIPV )
4797 				{
4798 					Rectangle aBndRect( pRet->GetSnapRect() );
4799 					Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
4800 					Point aRight( aLeft.X() + 1000, aLeft.Y() );
4801 					pRet->NbcMirror( aLeft, aRight );
4802 				}
4803 			}
4804 		}
4805 	}
4806 
4807     // #i51348# #118052# name of the shape
4808     if( pRet )
4809     {
4810         ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt );
4811         if( aObjName.getLength() > 0 )
4812             pRet->SetName( aObjName );
4813     }
4814 
4815 	pRet =
4816 		ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet);
4817 
4818 	if ( pRet )
4819 	{
4820 		sal_Int32 nGroupProperties( GetPropertyValue( DFF_Prop_fPrint ) );
4821 		pRet->SetVisible( ( nGroupProperties & 2 ) == 0 );
4822 		pRet->SetPrintable( ( nGroupProperties & 1 ) != 0 );
4823 	}
4824 
4825 	if ( mbTracing )
4826 		mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP
4827 									? rtl::OUString::createFromAscii( "GroupShape" )
4828 									: rtl::OUString::createFromAscii( "Shape" ) );
4829     //Import alt text as description
4830 	if ( pRet && SeekToContent( DFF_Prop_wzDescription, rSt ) )
4831 	{
4832 		String aAltText;
4833 		MSDFFReadZString( rSt, aAltText, GetPropertyValue( DFF_Prop_wzDescription ), sal_True );
4834 		pRet->SetDescription( aAltText );
4835 	}
4836 
4837 	return pRet;
4838 }
4839 
4840 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect )
4841 {
4842 	Rectangle aChildAnchor;
4843 	rHd.SeekToContent( rSt );
4844 	while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4845 	{
4846 		DffRecordHeader aShapeHd;
4847 		rSt >> aShapeHd;
4848 		if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
4849 				( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
4850 		{
4851 			DffRecordHeader aShapeHd2( aShapeHd );
4852 			if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
4853 				rSt >> aShapeHd2;
4854 			while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
4855 			{
4856 				DffRecordHeader aShapeAtom;
4857 				rSt >> aShapeAtom;
4858 
4859 				if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor )
4860 				{
4861 					if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT )
4862 					{
4863 						sal_Int32 l, t, r, b;
4864 						if ( aShapeAtom.nRecLen == 16 )
4865 						{
4866 							rSt >> l >> t >> r >> b;
4867 						}
4868 						else
4869 						{
4870 							sal_Int16 ls, ts, rs, bs;
4871 							rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ...
4872 							l = ls, t = ts, r = rs, b = bs;
4873 						}
4874 						Scale( l );
4875 						Scale( t );
4876 						Scale( r );
4877 						Scale( b );
4878 						aClientRect = Rectangle( l, t, r, b );
4879 					}
4880 					break;
4881 				}
4882 				else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
4883 				{
4884 					sal_Int32 l, o, r, u;
4885 					rSt >> l >> o >> r >> u;
4886 					Scale( l );
4887 					Scale( o );
4888 					Scale( r );
4889 					Scale( u );
4890 					Rectangle aChild( l, o, r, u );
4891 					aChildAnchor.Union( aChild );
4892 					break;
4893 				}
4894 				aShapeAtom.SeekToEndOfRecord( rSt );
4895 			}
4896 		}
4897 		aShapeHd.SeekToEndOfRecord( rSt );
4898 	}
4899 	return aChildAnchor;
4900 }
4901 
4902 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt,
4903 							Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor,
4904 								const Rectangle& rClientRect, const Rectangle& rGlobalChildRect )
4905 {
4906 	sal_Bool bFirst = sal_True;
4907 	rHd.SeekToContent( rSt );
4908 	DffRecordHeader aShapeHd;
4909 	while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4910 	{
4911 		rSt >> aShapeHd;
4912 		if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
4913 				( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
4914 		{
4915 			DffRecordHeader aShapeHd2( aShapeHd );
4916 			if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
4917 				rSt >> aShapeHd2;
4918 			while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
4919 			{
4920 				DffRecordHeader aShapeAtom;
4921 				rSt >> aShapeAtom;
4922 				if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
4923 				{
4924 					sal_Int32 l, o, r, u;
4925 					rSt >> l >> o >> r >> u;
4926 					Scale( l );
4927 					Scale( o );
4928 					Scale( r );
4929 					Scale( u );
4930 					Rectangle aChild( l, o, r, u );
4931 
4932 					if ( bFirst )
4933 					{
4934 						if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
4935 						{
4936 							double fl = l;
4937 							double fo = o;
4938 							double fWidth = r - l;
4939 							double fHeight= u - o;
4940 							double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
4941 							double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
4942 							fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
4943 							fo = ( ( o - rGlobalChildRect.Top()  ) * fYScale ) + rClientRect.Top();
4944 							fWidth *= fXScale;
4945 							fHeight *= fYScale;
4946 							rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
4947 						}
4948 						bFirst = sal_False;
4949 					}
4950 					else
4951 						rGroupChildAnchor.Union( aChild );
4952 					break;
4953 				}
4954 				aShapeAtom.SeekToEndOfRecord( rSt );
4955 			}
4956 		}
4957 		aShapeHd.SeekToEndOfRecord( rSt );
4958 	}
4959 }
4960 
4961 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt,
4962 									   DffObjData& rObjData,
4963 									   void* pData,
4964 									   Rectangle& rTextRect,
4965 									   SdrObject* pObj
4966 									   )
4967 {
4968 	if( !rTextRect.IsEmpty() )
4969 	{
4970 		SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
4971 		SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
4972 		SvxMSDffImportRec* pTextImpRec = pImpRec;
4973 
4974 		// fill Import Record with data
4975 		pImpRec->nShapeId   = rObjData.nShapeId;
4976 		pImpRec->eShapeType = rObjData.eShapeType;
4977 
4978 		MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue(
4979 															DFF_Prop_WrapText,
4980 															mso_wrapSquare ) );
4981 		rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
4982 											DFF_msofbtClientAnchor,
4983 											SEEK_FROM_CURRENT_AND_RESTART );
4984 		if( rObjData.bClientAnchor )
4985 			ProcessClientAnchor( rSt,
4986 					maShapeRecords.Current()->nRecLen,
4987 					pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
4988 
4989 		rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
4990 											DFF_msofbtClientData,
4991 											SEEK_FROM_CURRENT_AND_RESTART );
4992 		if( rObjData.bClientData )
4993 			ProcessClientData( rSt,
4994 					maShapeRecords.Current()->nRecLen,
4995 					pImpRec->pClientDataBuffer, pImpRec->nClientDataLen );
4996 
4997 
4998 		// process user (== Winword) defined parameters in 0xF122 record
4999 		if(    maShapeRecords.SeekToContent( rSt,
5000 											 DFF_msofbtUDefProp,
5001 											 SEEK_FROM_CURRENT_AND_RESTART )
5002 			&& maShapeRecords.Current()->nRecLen )
5003 		{
5004 			sal_uInt32  nBytesLeft = maShapeRecords.Current()->nRecLen;
5005 			sal_uInt32	nUDData;
5006 			sal_uInt16  nPID;
5007 			while( 5 < nBytesLeft )
5008 			{
5009 				rSt >> nPID;
5010 				if ( rSt.GetError() != 0 )
5011 					break;
5012 				rSt >> nUDData;
5013 				switch( nPID )
5014 				{
5015 					case 0x038F: pImpRec->nXAlign = nUDData; break;
5016 					case 0x0390: pImpRec->nXRelTo = nUDData; break;
5017 					case 0x0391: pImpRec->nYAlign = nUDData; break;
5018 					case 0x0392: pImpRec->nYRelTo = nUDData; break;
5019                     case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break;
5020 				}
5021 				if ( rSt.GetError() != 0 )
5022 					break;
5023 				pImpRec->bHasUDefProp = sal_True;
5024 				nBytesLeft  -= 6;
5025 			}
5026 		}
5027 
5028 		//  Textrahmen, auch Title oder Outline
5029 		SdrObject*  pOrgObj  = pObj;
5030 		SdrRectObj* pTextObj = 0;
5031 		sal_uInt32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
5032 		if( nTextId )
5033 		{
5034 			SfxItemSet aSet( pSdrModel->GetItemPool() );
5035 
5036             //Originally anything that as a mso_sptTextBox was created as a
5037             //textbox, this was changed for #88277# to be created as a simple
5038             //rect to keep impress happy. For the rest of us we'd like to turn
5039             //it back into a textbox again.
5040             FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox);
5041             if (!bTextFrame)
5042             {
5043                 //Either
5044                 //a) its a simple text object or
5045                 //b) its a rectangle with text and square wrapping.
5046                 bTextFrame =
5047                 (
5048                     (pImpRec->eShapeType == mso_sptTextSimple) ||
5049                     (
5050                         (pImpRec->eShapeType == mso_sptRectangle)
5051                         && (eWrapMode == mso_wrapSquare)
5052                         && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
5053                     )
5054                 );
5055             }
5056 
5057             if (bTextFrame)
5058             {
5059                 SdrObject::Free( pObj );
5060                 pObj = pOrgObj = 0;
5061             }
5062 
5063             // Distance of Textbox to it's surrounding Customshape
5064 			sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
5065 			sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
5066 			sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L  );
5067 			sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
5068 
5069 			ScaleEmu( nTextLeft );
5070 			ScaleEmu( nTextRight );
5071 			ScaleEmu( nTextTop );
5072 			ScaleEmu( nTextBottom );
5073 
5074             sal_Int32 nTextRotationAngle=0;
5075             bool bVerticalText = false;
5076             if ( IsProperty( DFF_Prop_txflTextFlow ) )
5077             {
5078                 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue(
5079                     DFF_Prop_txflTextFlow) & 0xFFFF);
5080                 switch( eTextFlow )
5081                 {
5082                     case mso_txflBtoT:
5083                         nTextRotationAngle = 9000;
5084                     break;
5085                     case mso_txflVertN:
5086                     case mso_txflTtoBN:
5087                         nTextRotationAngle = 27000;
5088                         break;
5089                     case mso_txflTtoBA:
5090                         bVerticalText = true;
5091                     break;
5092                     case mso_txflHorzA:
5093                         bVerticalText = true;
5094                         nTextRotationAngle = 9000;
5095                     case mso_txflHorzN:
5096                     default :
5097                         break;
5098                 }
5099             }
5100 
5101             if (nTextRotationAngle)
5102 			{
5103                 while (nTextRotationAngle > 360000)
5104                     nTextRotationAngle-=9000;
5105                 switch (nTextRotationAngle)
5106                 {
5107                     case 9000:
5108                         {
5109                             long nWidth = rTextRect.GetWidth();
5110                             rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5111                             rTextRect.Bottom() = rTextRect.Top() + nWidth;
5112 
5113                             sal_Int32 nOldTextLeft = nTextLeft;
5114                             sal_Int32 nOldTextRight = nTextRight;
5115                             sal_Int32 nOldTextTop = nTextTop;
5116                             sal_Int32 nOldTextBottom = nTextBottom;
5117 
5118                             nTextLeft = nOldTextBottom;
5119                             nTextRight = nOldTextTop;
5120                             nTextTop = nOldTextLeft;
5121                             nTextBottom = nOldTextRight;
5122                         }
5123                         break;
5124                     case 27000:
5125                         {
5126                             long nWidth = rTextRect.GetWidth();
5127                             rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5128                             rTextRect.Bottom() = rTextRect.Top() + nWidth;
5129 
5130                             sal_Int32 nOldTextLeft = nTextLeft;
5131                             sal_Int32 nOldTextRight = nTextRight;
5132                             sal_Int32 nOldTextTop = nTextTop;
5133                             sal_Int32 nOldTextBottom = nTextBottom;
5134 
5135                             nTextLeft = nOldTextTop;
5136                             nTextRight = nOldTextBottom;
5137                             nTextTop = nOldTextRight;
5138                             nTextBottom = nOldTextLeft;
5139                         }
5140                         break;
5141                     default:
5142                         break;
5143                 }
5144 			}
5145 
5146             pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect);
5147             pTextImpRec = new SvxMSDffImportRec(*pImpRec);
5148 
5149             // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
5150             // hier rausrechnen
5151             Rectangle aNewRect(rTextRect);
5152 			aNewRect.Bottom() -= nTextTop + nTextBottom;
5153             aNewRect.Right() -= nTextLeft + nTextRight;
5154 
5155 			// Nur falls es eine einfache Textbox ist, darf der Writer
5156 			// das Objekt durch einen Rahmen ersetzen, ansonsten
5157 			if( bTextFrame )
5158 			{
5159 				SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId );
5160 				aTmpRec.bSortByShapeId = sal_True;
5161 
5162 				sal_uInt16 nFound;
5163 				if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) )
5164 				{
5165 					SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound);
5166 					pTextImpRec->bReplaceByFly   = rInfo.bReplaceByFly;
5167 					pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain;
5168 				}
5169 			}
5170 
5171 			if( !pObj )
5172 				ApplyAttributes( rSt, aSet, rObjData );
5173 
5174             bool bFitText = false;
5175             if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2)
5176             {
5177                 aSet.Put( SdrTextAutoGrowHeightItem( sal_True ) );
5178                 aSet.Put( SdrTextMinFrameHeightItem(
5179                     aNewRect.Bottom() - aNewRect.Top() ) );
5180                 aSet.Put( SdrTextMinFrameWidthItem(
5181                     aNewRect.Right() - aNewRect.Left() ) );
5182                 bFitText = true;
5183             }
5184             else
5185             {
5186                 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) );
5187                 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
5188             }
5189 
5190 			switch ( (MSO_WrapMode)
5191                 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) )
5192 			{
5193 				case mso_wrapNone :
5194     				aSet.Put( SdrTextAutoGrowWidthItem( sal_True ) );
5195                     if (bFitText)
5196                     {
5197                         //can't do autowidth in flys #i107184#
5198 					    pTextImpRec->bReplaceByFly = false;
5199                     }
5200 				break;
5201 				case mso_wrapByPoints :
5202 					aSet.Put( SdrTextContourFrameItem( sal_True ) );
5203 				break;
5204 				default: break;
5205 			}
5206 
5207 			// Abstaende an den Raendern der Textbox setzen
5208 			aSet.Put( SdrTextLeftDistItem( nTextLeft ) );
5209 			aSet.Put( SdrTextRightDistItem( nTextRight ) );
5210 			aSet.Put( SdrTextUpperDistItem( nTextTop ) );
5211 			aSet.Put( SdrTextLowerDistItem( nTextBottom ) );
5212 			pTextImpRec->nDxTextLeft	= nTextLeft;
5213 			pTextImpRec->nDyTextTop		= nTextTop;
5214 			pTextImpRec->nDxTextRight	= nTextRight;
5215 			pTextImpRec->nDyTextBottom	= nTextBottom;
5216 
5217 			// Textverankerung lesen
5218 			if ( IsProperty( DFF_Prop_anchorText ) )
5219 			{
5220 				MSO_Anchor eTextAnchor =
5221                     (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText );
5222 
5223 				SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER;
5224 				sal_Bool bTVASet(sal_False);
5225 				SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER;
5226 				sal_Bool bTHASet(sal_False);
5227 
5228 				switch( eTextAnchor )
5229 				{
5230 					case mso_anchorTop:
5231 					{
5232 						eTVA = SDRTEXTVERTADJUST_TOP;
5233 						bTVASet = sal_True;
5234 					}
5235 					break;
5236 					case mso_anchorTopCentered:
5237 					{
5238 						eTVA = SDRTEXTVERTADJUST_TOP;
5239 						bTVASet = sal_True;
5240 						bTHASet = sal_True;
5241 					}
5242 					break;
5243 
5244 					case mso_anchorMiddle:
5245 						bTVASet = sal_True;
5246 					break;
5247 					case mso_anchorMiddleCentered:
5248 					{
5249 						bTVASet = sal_True;
5250 						bTHASet = sal_True;
5251 					}
5252 					break;
5253 					case mso_anchorBottom:
5254 					{
5255 						eTVA = SDRTEXTVERTADJUST_BOTTOM;
5256 						bTVASet = sal_True;
5257 					}
5258 					break;
5259 					case mso_anchorBottomCentered:
5260 					{
5261 						eTVA = SDRTEXTVERTADJUST_BOTTOM;
5262 						bTVASet = sal_True;
5263 						bTHASet = sal_True;
5264 					}
5265 					break;
5266 	/*
5267 					case mso_anchorTopBaseline:
5268 					case mso_anchorBottomBaseline:
5269 					case mso_anchorTopCenteredBaseline:
5270 					case mso_anchorBottomCenteredBaseline:
5271 					break;
5272 	*/
5273 					default : break;
5274 				}
5275 				// Einsetzen
5276 				if ( bTVASet )
5277 					aSet.Put( SdrTextVertAdjustItem( eTVA ) );
5278 				if ( bTHASet )
5279 					aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
5280 			}
5281 
5282 			pTextObj->SetMergedItemSet(aSet);
5283             pTextObj->SetModel(pSdrModel);
5284 
5285             if (bVerticalText)
5286                 pTextObj->SetVerticalWriting(sal_True);
5287 
5288             if (nTextRotationAngle)
5289 			{
5290                 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ?
5291                     rTextRect.GetWidth() : rTextRect.GetHeight();
5292                 nMinWH /= 2;
5293                 Point aPivot(rTextRect.TopLeft());
5294                 aPivot.X() += nMinWH;
5295                 aPivot.Y() += nMinWH;
5296 				double a = nTextRotationAngle * nPi180;
5297 				pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a));
5298 			}
5299 
5300 			// rotate text with shape ?
5301 			if ( mnFix16Angle )
5302 			{
5303 				double a = mnFix16Angle * nPi180;
5304 				pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle,
5305                     sin( a ), cos( a ) );
5306 			}
5307 
5308 			if( !pObj )
5309 			{
5310 				pObj = pTextObj;
5311 			}
5312 			else
5313 			{
5314 				if( pTextObj != pObj )
5315 				{
5316 					SdrObject* pGroup = new SdrObjGroup;
5317 					pGroup->GetSubList()->NbcInsertObject( pObj );
5318 					pGroup->GetSubList()->NbcInsertObject( pTextObj );
5319                     if (pOrgObj == pObj)
5320                         pOrgObj = pGroup;
5321                     else
5322 					    pOrgObj = pObj;
5323                     pObj = pGroup;
5324 				}
5325 			}
5326 		}
5327 		else if( !pObj )
5328 		{
5329 			// simple rectangular objects are ignored by ImportObj()  :-(
5330 			// this is OK for Draw but not for Calc and Writer
5331 			// cause here these objects have a default border
5332 			pObj = new SdrRectObj(rTextRect);
5333 			pOrgObj = pObj;
5334 			pObj->SetModel( pSdrModel );
5335             SfxItemSet aSet( pSdrModel->GetItemPool() );
5336 			ApplyAttributes( rSt, aSet, rObjData );
5337 
5338 			const SfxPoolItem* pPoolItem=NULL;
5339 			SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
5340 													 sal_False, &pPoolItem );
5341 			if( SFX_ITEM_DEFAULT == eState )
5342 				aSet.Put( XFillColorItem( String(),
5343 						  Color( mnDefaultColor ) ) );
5344 			pObj->SetMergedItemSet(aSet);
5345 		}
5346 
5347         //Means that fBehindDocument is set
5348         if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
5349 		    pImpRec->bDrawHell = sal_True;
5350         else
5351 		    pImpRec->bDrawHell = sal_False;
5352         if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
5353             pImpRec->bHidden = sal_True;
5354 		pTextImpRec->bDrawHell	= pImpRec->bDrawHell;
5355 		pTextImpRec->bHidden = pImpRec->bHidden;
5356 		pImpRec->nNextShapeId	= GetPropertyValue( DFF_Prop_hspNext, 0 );
5357 		pTextImpRec->nNextShapeId=pImpRec->nNextShapeId;
5358 
5359 		if ( nTextId )
5360 		{
5361 			pTextImpRec->aTextId.nTxBxS = (sal_uInt16)( nTextId >> 16 );
5362 			pTextImpRec->aTextId.nSequence = (sal_uInt16)nTextId;
5363 		}
5364 
5365 		pTextImpRec->nDxWrapDistLeft = GetPropertyValue(
5366 									DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
5367 		pTextImpRec->nDyWrapDistTop = GetPropertyValue(
5368 									DFF_Prop_dyWrapDistTop, 0 ) / 635L;
5369 		pTextImpRec->nDxWrapDistRight = GetPropertyValue(
5370 									DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
5371 		pTextImpRec->nDyWrapDistBottom = GetPropertyValue(
5372 									DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
5373         // 16.16 fraction times total image width or height, as appropriate.
5374 
5375         if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt))
5376         {
5377             delete pTextImpRec->pWrapPolygon;
5378             sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
5379             rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
5380             if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
5381             {
5382                 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert);
5383                 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
5384                 {
5385                     sal_Int32 nX, nY;
5386                     if (nElemSizeVert == 8)
5387                         rSt >> nX >> nY;
5388                     else
5389                     {
5390                         sal_Int16 nSmallX, nSmallY;
5391                         rSt >> nSmallX >> nSmallY;
5392                         nX = nSmallX;
5393                         nY = nSmallY;
5394                     }
5395                     (*(pTextImpRec->pWrapPolygon))[i].X() = nX;
5396                     (*(pTextImpRec->pWrapPolygon))[i].Y() = nY;
5397                 }
5398             }
5399         }
5400 
5401 		pImpRec->nCropFromTop = GetPropertyValue(
5402 									DFF_Prop_cropFromTop, 0 );
5403 		pImpRec->nCropFromBottom = GetPropertyValue(
5404 									DFF_Prop_cropFromBottom, 0 );
5405 		pImpRec->nCropFromLeft = GetPropertyValue(
5406 									DFF_Prop_cropFromLeft, 0 );
5407 		pImpRec->nCropFromRight = GetPropertyValue(
5408 									DFF_Prop_cropFromRight, 0 );
5409 
5410         pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false;
5411         pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false;
5412 
5413 		sal_uInt32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
5414 		pImpRec->eLineStyle = (nLineFlags & 8)
5415 							? (MSO_LineStyle)GetPropertyValue(
5416 												DFF_Prop_lineStyle,
5417 												mso_lineSimple )
5418 							: (MSO_LineStyle)USHRT_MAX;
5419 		pTextImpRec->eLineStyle = pImpRec->eLineStyle;
5420 
5421 		if( pImpRec->nShapeId )
5422 		{
5423 			// Import-Record-Liste ergaenzen
5424 			if( pOrgObj )
5425 			{
5426 				pImpRec->pObj = pOrgObj;
5427 				rImportData.aRecords.Insert( pImpRec );
5428 			}
5429 
5430 			if( pTextObj && (pOrgObj != pTextObj) )
5431 			{
5432 				// Modify ShapeId (must be unique)
5433 				pImpRec->nShapeId |= 0x8000000;
5434 				pTextImpRec->pObj = pTextObj;
5435 				rImportData.aRecords.Insert( pTextImpRec );
5436 			}
5437 
5438 			// Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen
5439 			/*Only store objects which are not deep inside the tree*/
5440 			if( ( rObjData.nCalledByGroup == 0 )
5441 				||
5442 				( (rObjData.nSpFlags & SP_FGROUP)
5443 				 && (rObjData.nCalledByGroup < 2) )
5444 			  )
5445 				StoreShapeOrder( pImpRec->nShapeId,
5446 								( ( (sal_uLong)pImpRec->aTextId.nTxBxS ) << 16 )
5447 									+ pImpRec->aTextId.nSequence, pObj );
5448 		}
5449 		else
5450 			delete pImpRec;
5451 	}
5452 
5453 	return pObj;
5454 };
5455 
5456 void SvxMSDffManager::StoreShapeOrder(sal_uLong			nId,
5457 									  sal_uLong			nTxBx,
5458 									  SdrObject*	pObject,
5459 									  SwFlyFrmFmt*	pFly,
5460 									  short			nHdFtSection) const
5461 {
5462 	sal_uInt16 nShpCnt = pShapeOrders->Count();
5463 	for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5464 	{
5465 		SvxMSDffShapeOrder& rOrder
5466 			= *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5467 
5468 		if( rOrder.nShapeId == nId )
5469 		{
5470 			rOrder.nTxBxComp = nTxBx;
5471 			rOrder.pObj      = pObject;
5472 			rOrder.pFly      = pFly;
5473 			rOrder.nHdFtSection = nHdFtSection;
5474 		}
5475 	}
5476 }
5477 
5478 
5479 void SvxMSDffManager::ExchangeInShapeOrder(	SdrObject*   pOldObject,
5480 											sal_uLong        nTxBx,
5481 											SwFlyFrmFmt* pFly,
5482 											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 == pOldObject )
5491 		{
5492 			rOrder.pFly      = pFly;
5493 			rOrder.pObj      = pObject;
5494 			rOrder.nTxBxComp = nTxBx;
5495 		}
5496 	}
5497 }
5498 
5499 
5500 void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const
5501 {
5502 	sal_uInt16 nShpCnt = pShapeOrders->Count();
5503 	for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5504 	{
5505 		SvxMSDffShapeOrder& rOrder
5506 			= *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5507 
5508 		if( rOrder.pObj == pObject )
5509 		{
5510 			rOrder.pObj      = 0;
5511 			rOrder.pFly      = 0;
5512 			rOrder.nTxBxComp = 0;
5513 		}
5514 	}
5515 }
5516 
5517 
5518 
5519 
5520 //---------------------------------------------------------------------------
5521 //  Hilfs Deklarationen
5522 //---------------------------------------------------------------------------
5523 
5524 /*struct SvxMSDffBLIPInfo                       -> in's Header-File
5525 {
5526 	sal_uInt16 nBLIPType;       // Art des BLIP: z.B. 6 fuer PNG
5527 	sal_uLong  nFilePos;        // Offset des BLIP im Daten-Stream
5528 	sal_uLong  nBLIPSize;       // Anzahl Bytes, die der BLIP im Stream einnimmt
5529 	SvxMSDffBLIPInfo(sal_uInt16 nBType, sal_uLong nFPos, sal_uLong nBSize):
5530 		nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){}
5531 };
5532 */
5533 
5534 SV_IMPL_PTRARR(			SvxMSDffBLIPInfos,		SvxMSDffBLIPInfo_Ptr	);
5535 
5536 SV_IMPL_PTRARR(			SvxMSDffShapeOrders,	SvxMSDffShapeOrder_Ptr	);
5537 
5538 SV_IMPL_OP_PTRARR_SORT(	SvxMSDffShapeInfos,		SvxMSDffShapeInfo_Ptr	);
5539 
5540 SV_IMPL_OP_PTRARR_SORT(	SvxMSDffShapeTxBxSort,	SvxMSDffShapeOrder_Ptr	);
5541 
5542 
5543 // Liste aller SvxMSDffImportRec fuer eine Gruppe
5544 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr)
5545 
5546 //---------------------------------------------------------------------------
5547 //  exportierte Klasse: oeffentliche Methoden
5548 //---------------------------------------------------------------------------
5549 
5550 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_,
5551                                  const String& rBaseURL,
5552 								 long      nOffsDgg_,
5553 								 SvStream* pStData_,
5554 								 SdrModel* pSdrModel_,// s. unten: SetModel()
5555 								 long      nApplicationScale,
5556 								 ColorData mnDefaultColor_,
5557 								 sal_uLong     nDefaultFontHeight_,
5558 								 SvStream* pStData2_,
5559 								 MSFilterTracer* pTracer )
5560 	:DffPropertyReader( *this ),
5561 	 pFormModel( NULL ),
5562 	 pBLIPInfos( new SvxMSDffBLIPInfos  ),
5563 	 pShapeInfos(  new SvxMSDffShapeInfos ),
5564 	 pShapeOrders( new SvxMSDffShapeOrders ),
5565 	 nDefaultFontHeight( nDefaultFontHeight_),
5566 	 nOffsDgg( nOffsDgg_ ),
5567 	 nBLIPCount(  USHRT_MAX ),				// mit Error initialisieren, da wir erst pruefen,
5568 	 nShapeCount( USHRT_MAX ),              // ob Kontroll-Stream korrekte Daten enthaellt
5569      maBaseURL( rBaseURL ),
5570 	 mpFidcls( NULL ),
5571 	 rStCtrl(  rStCtrl_  ),
5572 	 pStData(  pStData_  ),
5573 	 pStData2( pStData2_ ),
5574 	 nSvxMSDffSettings( 0 ),
5575 	 nSvxMSDffOLEConvFlags( 0 ),
5576 	 pSecPropSet( NULL ),
5577      pEscherBlipCache( NULL ),
5578 	 mnDefaultColor( mnDefaultColor_),
5579 	 mpTracer( pTracer ),
5580      mbTracing( sal_False )
5581 {
5582 	if ( mpTracer )
5583 	{
5584 		uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
5585 		aAny >>= mbTracing;
5586 	}
5587 	SetModel( pSdrModel_, nApplicationScale );
5588 
5589 	// FilePos des/der Stream(s) merken
5590 	sal_uLong nOldPosCtrl = rStCtrl.Tell();
5591 	sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
5592 
5593 	// Falls kein Datenstream angegeben, gehen wir davon aus,
5594 	// dass die BLIPs im Steuerstream stehen.
5595 	if( !pStData )
5596 		pStData = &rStCtrl;
5597 
5598 	SetDefaultPropSet( rStCtrl, nOffsDgg );
5599 
5600 	// Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
5601 	GetCtrlData( nOffsDgg );
5602 
5603 	// Text-Box-Story-Ketten-Infos ueberpruefen
5604 	CheckTxBxStoryChain();
5605 
5606 	// alte FilePos des/der Stream(s) restaurieren
5607 	rStCtrl.Seek( nOldPosCtrl );
5608 	if( &rStCtrl != pStData )
5609 		pStData->Seek( nOldPosData );
5610 }
5611 
5612 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer )
5613 	:DffPropertyReader( *this ),
5614 	 pFormModel( NULL ),
5615 	 pBLIPInfos(   new SvxMSDffBLIPInfos  ),
5616 	 pShapeInfos(  new SvxMSDffShapeInfos ),
5617 	 pShapeOrders( new SvxMSDffShapeOrders ),
5618 	 nDefaultFontHeight( 24 ),
5619 	 nOffsDgg( 0 ),
5620 	 nBLIPCount(  USHRT_MAX ),				// mit Error initialisieren, da wir erst pruefen,
5621 	 nShapeCount( USHRT_MAX ),              // ob Kontroll-Stream korrekte Daten enthaellt
5622      maBaseURL( rBaseURL ),
5623 	 mpFidcls( NULL ),
5624 	 rStCtrl(  rStCtrl_  ),
5625 	 pStData( 0 ),
5626 	 pStData2( 0 ),
5627 	 nSvxMSDffSettings( 0 ),
5628 	 nSvxMSDffOLEConvFlags( 0 ),
5629 	 pSecPropSet( NULL ),
5630      pEscherBlipCache( NULL ),
5631 	 mnDefaultColor( COL_DEFAULT ),
5632 	 mpTracer( pTracer ),
5633      mbTracing( sal_False )
5634 {
5635 	if ( mpTracer )
5636 	{
5637 		uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
5638 		aAny >>= mbTracing;
5639 	}
5640 	SetModel( NULL, 0 );
5641 }
5642 
5643 SvxMSDffManager::~SvxMSDffManager()
5644 {
5645     if ( pEscherBlipCache )
5646     {
5647         void* pPtr;
5648         for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() )
5649             delete (EscherBlipCacheEntry*)pPtr;
5650         delete pEscherBlipCache;
5651     }
5652 	delete pSecPropSet;
5653 	delete pBLIPInfos;
5654 	delete pShapeInfos;
5655 	delete pShapeOrders;
5656 	delete pFormModel;
5657 	delete[] mpFidcls;
5658 }
5659 
5660 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags )
5661 {
5662 	nOffsDgg = nOffsDgg_;
5663 	pStData = pStData_;
5664 	nSvxMSDffOLEConvFlags = nOleConvFlags;
5665 
5666 	// FilePos des/der Stream(s) merken
5667 	sal_uLong nOldPosCtrl = rStCtrl.Tell();
5668 
5669 	SetDefaultPropSet( rStCtrl, nOffsDgg );
5670 
5671 	// insert fidcl cluster table
5672 	GetFidclData( nOffsDgg );
5673 
5674 	// Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
5675 	GetCtrlData( nOffsDgg );
5676 
5677 	// Text-Box-Story-Ketten-Infos ueberpruefen
5678 	CheckTxBxStoryChain();
5679 
5680 	// alte FilePos des/der Stream(s) restaurieren
5681 	rStCtrl.Seek( nOldPosCtrl );
5682 }
5683 
5684 void SvxMSDffManager::SetDgContainer( SvStream& rSt )
5685 {
5686 	sal_uInt32 nFilePos = rSt.Tell();
5687 	DffRecordHeader aDgContHd;
5688 	rSt >> aDgContHd;
5689 	// insert this container only if there is also a DgAtom
5690 	if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) )
5691 	{
5692 		DffRecordHeader aRecHd;
5693 		rSt >> aRecHd;
5694 		sal_uInt32 nDrawingId = aRecHd.nRecInstance;
5695 		maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos );
5696 		rSt.Seek( nFilePos );
5697 	}
5698 }
5699 
5700 void SvxMSDffManager::GetFidclData( long nOffsDggL )
5701 {
5702 	if ( nOffsDggL )
5703 	{
5704 		sal_uInt32 nDummy, nMerk = rStCtrl.Tell();
5705 		rStCtrl.Seek( nOffsDggL );
5706 
5707 		DffRecordHeader aRecHd;
5708 		rStCtrl >> aRecHd;
5709 
5710 		DffRecordHeader aDggAtomHd;
5711 		if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) )
5712 		{
5713 			aDggAtomHd.SeekToContent( rStCtrl );
5714 			rStCtrl >> mnCurMaxShapeId
5715 					>> mnIdClusters
5716 					>> nDummy
5717 					>> mnDrawingsSaved;
5718 
5719 			if ( mnIdClusters-- > 2 )
5720 			{
5721 				if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) )
5722 				{
5723 					//mpFidcls = new FIDCL[ mnIdClusters ];
5724                     mpFidcls = new (std::nothrow) FIDCL[ mnIdClusters ];
5725                     if ( mpFidcls ) {
5726                         for ( sal_uInt32 i = 0; i < mnIdClusters; i++ )
5727                         {
5728                             rStCtrl >> mpFidcls[ i ].dgid
5729                                     >> mpFidcls[ i ].cspidCur;
5730                         }
5731                     }
5732 				}
5733 			}
5734 		}
5735 		rStCtrl.Seek( nMerk );
5736 	}
5737 }
5738 
5739 void SvxMSDffManager::CheckTxBxStoryChain()
5740 {
5741 	SvxMSDffShapeInfos* pOld = pShapeInfos;
5742 	sal_uInt16 nCnt				= pOld->Count();
5743 	pShapeInfos				= new SvxMSDffShapeInfos( (nCnt < 255)
5744 													 ? nCnt
5745 													 : 255 );
5746 	// altes Info-Array ueberarbeiten
5747 	// (ist sortiert nach nTxBxComp)
5748 	sal_uLong nChain    = ULONG_MAX;
5749 	sal_uInt16 nObjMark = 0;
5750 	sal_Bool bSetReplaceFALSE = sal_False;
5751 	sal_uInt16 nObj;
5752 	for( nObj = 0; nObj < nCnt; ++nObj )
5753 	{
5754 		SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj );
5755 		if( pObj->nTxBxComp )
5756 		{
5757 			pObj->bLastBoxInChain = sal_False;
5758 			// Gruppenwechsel ?
5759             // --> OD 2008-07-28 #156763#
5760             // the text id also contains an internal drawing container id
5761             // to distinguish between text id of drawing objects in different
5762             // drawing containers.
5763 //            if( nChain != (pObj->nTxBxComp & 0xFFFF0000) )
5764             if( nChain != pObj->nTxBxComp )
5765             // <--
5766             {
5767 				// voriger war letzter seiner Gruppe
5768 				if( nObj )
5769 					pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True;
5770 				// Merker und Hilfs-Flag zuruecksetzen
5771 				nObjMark = nObj;
5772                 // --> OD 2008-07-28 #156763#
5773 //                nChain   = pObj->nTxBxComp & 0xFFFF0000;
5774                 nChain = pObj->nTxBxComp;
5775                 // <--
5776 				bSetReplaceFALSE = !pObj->bReplaceByFly;
5777 			}
5778 			else
5779 			if( !pObj->bReplaceByFly )
5780 			{
5781 				// Objekt, das NICHT durch Rahmen ersetzt werden darf ?
5782 				// Hilfs-Flag setzen
5783 				bSetReplaceFALSE = sal_True;
5784 				// ggfs Flag in Anfang der Gruppe austragen
5785 				for( sal_uInt16 nObj2 = nObjMark; nObj2 < nObj; ++nObj2 )
5786 					pOld->GetObject( nObj2 )->bReplaceByFly = sal_False;
5787 			}
5788 
5789 			if( bSetReplaceFALSE )
5790 			{
5791 				pObj->bReplaceByFly = sal_False;
5792 			}
5793 		}
5794 		// alle Shape-Info-Objekte in pShapeInfos umkopieren
5795 		// (aber nach nShapeId sortieren)
5796 		pObj->bSortByShapeId = sal_True;
5797         // --> OD 2008-07-28 #156763#
5798         pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000;
5799         // <--
5800 		pShapeInfos->Insert( pObj );
5801 	}
5802 	// voriger war letzter seiner Gruppe
5803 	if( nObj )
5804 		pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True;
5805 	// urspruengliches Array freigeben, ohne Objekte zu zerstoeren
5806 	pOld->Remove((sal_uInt16)0, nCnt);
5807 	delete pOld;
5808 }
5809 
5810 
5811 /*****************************************************************************
5812 
5813 	Einlesen der Shape-Infos im Ctor:
5814 	---------------------------------
5815 	merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos
5816 			   =========                  ============	   =============
5817 	und merken des File-Offsets fuer jedes Blip
5818 				   ============
5819 ******************************************************************************/
5820 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ )
5821 {
5822 	// Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen
5823 	long nOffsDggL = nOffsDgg_;
5824 
5825 	// Kontroll Stream positionieren
5826 	rStCtrl.Seek( nOffsDggL );
5827 
5828 	sal_uInt8   nVer;
5829 	sal_uInt16 nInst;
5830 	sal_uInt16 nFbt;
5831 	sal_uInt32  nLength;
5832 	if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return;
5833 
5834 	sal_Bool bOk;
5835 	sal_uLong nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE;
5836 
5837 	// Fall A: erst Drawing Group Container, dann n Mal Drawing Container
5838 	if( DFF_msofbtDggContainer == nFbt )
5839 	{
5840         GetDrawingGroupContainerData( rStCtrl, nLength );
5841 
5842 		 rStCtrl.Seek( STREAM_SEEK_TO_END );
5843 		sal_uInt32 nMaxStrPos = rStCtrl.Tell();
5844 
5845 		nPos += nLength;
5846         // --> OD 2008-07-28 #156763#
5847         unsigned long nDrawingContainerId = 1;
5848         // <--
5849         do
5850 		{
5851 			rStCtrl.Seek( nPos );
5852 
5853 			bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt );
5854 
5855 			if( !bOk )
5856 			{
5857 				nPos++;				// ????????? TODO: trying to get an one-hit wonder, this code code should be rewritten...
5858 				rStCtrl.Seek( nPos );
5859 				bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength )
5860 						&& ( DFF_msofbtDgContainer == nFbt );
5861 			}
5862 			if( bOk )
5863             {
5864                 // --> OD 2008-07-28 #156763#
5865                 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId );
5866                 // <--
5867             }
5868 			nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
5869             // --> OD 2008-07-28 #156763#
5870             ++nDrawingContainerId;
5871             // <--
5872 		}
5873 		while( ( rStCtrl.GetError() == 0 ) && ( nPos < nMaxStrPos ) && bOk );
5874 	}
5875 }
5876 
5877 
5878 // ab hier: Drawing Group Container  d.h. Dokument - weit gueltige Daten
5879 //                      =======================           ========
5880 //
5881 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, sal_uLong nLenDgg )
5882 {
5883 	sal_uInt8   nVer;
5884 	sal_uInt16 nInst;
5885 	sal_uInt16 nFbt;
5886 	sal_uInt32 nLength;
5887 
5888 	sal_uLong nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0;
5889 
5890 	// Nach einem BStore Container suchen
5891 	do
5892 	{
5893 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
5894 		nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
5895 		if( DFF_msofbtBstoreContainer == nFbt )
5896 		{
5897 			nLenBStoreCont = nLength;       break;
5898 		}
5899 		rSt.SeekRel( nLength );
5900 	}
5901 	while( nRead < nLenDgg );
5902 
5903 	if( !nLenBStoreCont ) return;
5904 
5905 	// Im BStore Container alle Header der Container und Atome auslesen und die
5906 	// relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen.
5907 	// Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit.
5908 
5909 	const sal_uLong nSkipBLIPLen = 20;  // bis zu nBLIPLen zu ueberspringende Bytes
5910 	const sal_uLong nSkipBLIPPos =  4;  // dahinter bis zu nBLIPPos zu skippen
5911 
5912 	sal_uInt32 nBLIPLen = 0, nBLIPPos = 0;
5913 
5914 	nRead = 0;
5915 	do
5916 	{
5917 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
5918 		nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
5919 		if( DFF_msofbtBSE == nFbt )
5920 		{
5921 			nLenFBSE = nLength;
5922 			// ist FBSE gross genug fuer unsere Daten
5923 			sal_Bool bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE );
5924 
5925 			if( bOk )
5926 			{
5927 				rSt.SeekRel( nSkipBLIPLen );
5928 				rSt >> nBLIPLen;
5929 				rSt.SeekRel( nSkipBLIPPos );
5930 				rSt >> nBLIPPos;
5931 				bOk = rSt.GetError() == 0;
5932 
5933 				nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4;
5934 			}
5935 
5936 			if( bOk )
5937 			{
5938 				// Besonderheit:
5939 				// Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist,
5940 				// nehmen wir an, dass das Bild IM FBSE drin steht!
5941 				if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) )
5942 					nBLIPPos = rSt.Tell() + 4;
5943 
5944 				// Das hat ja fein geklappt!
5945 				// Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben.
5946 				nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell());
5947 
5948 				if( USHRT_MAX == nBLIPCount )
5949 					nBLIPCount = 1;
5950 				else
5951 					nBLIPCount++;
5952 
5953 				// Jetzt die Infos fuer spaetere Zugriffe speichern
5954 				pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ),
5955 														  pBLIPInfos->Count() );
5956 			}
5957 		}
5958 		rSt.SeekRel( nLength );
5959 	}
5960 	while( nRead < nLenBStoreCont );
5961 }
5962 
5963 
5964 // ab hier: Drawing Container  d.h. Seiten (Blatt, Dia) - weit gueltige Daten
5965 //                      =================               ======
5966 //
5967 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, sal_uLong nLenDg,
5968                                                const unsigned long nDrawingContainerId )
5969 {
5970 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
5971 
5972 	sal_uLong nReadDg = 0;
5973 
5974 	// Wir stehen in einem Drawing Container (je einer pro Seite)
5975 	// und muessen nun
5976 	// alle enthaltenen Shape Group Container abklappern
5977 	do
5978 	{
5979 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
5980 		nReadDg += DFF_COMMON_RECORD_HEADER_SIZE;
5981 		// Patriarch gefunden (der oberste Shape Group Container) ?
5982 		if( DFF_msofbtSpgrContainer == nFbt )
5983 		{
5984             if(!this->GetShapeGroupContainerData( rSt, nLength, sal_True, nDrawingContainerId )) return;
5985 		}
5986 		else
5987 		// blanker Shape Container ? (ausserhalb vom Shape Group Container)
5988 		if( DFF_msofbtSpContainer == nFbt )
5989 		{
5990             if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return;
5991 		}
5992 		else
5993 			rSt.SeekRel( nLength );
5994 		nReadDg += nLength;
5995 	}
5996 	while( nReadDg < nLenDg );
5997 }
5998 
5999 sal_Bool SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt,
6000 												  sal_uLong nLenShapeGroupCont,
6001                                                   sal_Bool bPatriarch,
6002                                                   const unsigned long nDrawingContainerId )
6003 {
6004 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
6005 	long nStartShapeGroupCont = rSt.Tell();
6006 	// Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite)
6007 	// und muessen nun
6008 	// alle enthaltenen Shape Container abklappern
6009 	sal_Bool  bFirst = !bPatriarch;
6010 	sal_uLong nReadSpGrCont = 0;
6011 	do
6012 	{
6013 		if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) )
6014 			return sal_False;
6015 		nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE;
6016 		// Shape Container ?
6017 		if( DFF_msofbtSpContainer == nFbt )
6018 		{
6019 			sal_uLong nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX;
6020             if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) )
6021 				return sal_False;
6022 			bFirst = sal_False;
6023 		}
6024 		else
6025 		// eingeschachtelter Shape Group Container ?
6026 		if( DFF_msofbtSpgrContainer == nFbt )
6027 		{
6028             if ( !this->GetShapeGroupContainerData( rSt, nLength, sal_False, nDrawingContainerId ) )
6029 				return sal_False;
6030 		}
6031 		else
6032 			rSt.SeekRel( nLength );
6033 		nReadSpGrCont += nLength;
6034 	}
6035 	while( nReadSpGrCont < nLenShapeGroupCont );
6036 	// den Stream wieder korrekt positionieren
6037 	rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont );
6038 	return sal_True;
6039 }
6040 
6041 sal_Bool SvxMSDffManager::GetShapeContainerData( SvStream& rSt,
6042                                              sal_uLong nLenShapeCont,
6043                                              sal_uLong nPosGroup,
6044                                              const unsigned long nDrawingContainerId )
6045 {
6046 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
6047 	long  nStartShapeCont = rSt.Tell();
6048 	// Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group)
6049 	// und muessen nun
6050 	// die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe)
6051 	// und den ersten BStore Verweis (falls vorhanden) entnehmen
6052 	sal_uLong nLenShapePropTbl = 0;
6053 	sal_uLong nReadSpCont = 0;
6054 
6055 	// File Offset des Shape-Containers bzw. der Gruppe(!) vermerken
6056 	//
6057 	sal_uLong nStartOffs = (ULONG_MAX > nPosGroup) ?
6058 							nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE;
6059 	SvxMSDffShapeInfo aInfo( nStartOffs );
6060 
6061 	// duerfte das Shape durch einen Rahmen ersetzt werden ?
6062 	// (vorausgesetzt, es zeigt sich, dass es eine TextBox ist,
6063 	//  und der Text nicht gedreht ist)
6064 	sal_Bool bCanBeReplaced = (ULONG_MAX > nPosGroup) ? sal_False : sal_True;
6065 
6066 	// wir wissen noch nicht, ob es eine TextBox ist
6067 	MSO_SPT			eShapeType		= mso_sptNil;
6068 	MSO_WrapMode	eWrapMode		= mso_wrapSquare;
6069 //	sal_Bool			bIsTextBox		= sal_False;
6070 
6071 	// Shape analysieren
6072 	//
6073 	do
6074 	{
6075 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return sal_False;
6076 		nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE;
6077 		// FSP ?
6078 		if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) )
6079 		{
6080 			// Wir haben den FSP gefunden: Shape Typ und Id vermerken!
6081 			eShapeType = (MSO_SPT)nInst;
6082 			rSt >> aInfo.nShapeId;
6083 			rSt.SeekRel( nLength - 4 );
6084 			nReadSpCont += nLength;
6085 		}
6086 		else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ?
6087 		{
6088 			// Wir haben die Property Table gefunden:
6089 			// nach der Blip Property suchen!
6090 			sal_uLong  nPropRead = 0;
6091 			sal_uInt16 nPropId;
6092 			sal_uInt32  nPropVal;
6093 			nLenShapePropTbl = nLength;
6094 //			sal_uInt32 nPropCount = nInst;
6095 			long nStartShapePropTbl = rSt.Tell();
6096 //			sal_uInt32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6);
6097 			do
6098 			{
6099 				rSt >> nPropId
6100 					>> nPropVal;
6101 				nPropRead += 6;
6102 
6103 				switch( nPropId )
6104 				{
6105 					case DFF_Prop_txflTextFlow :
6106                         //Writer can now handle vertical textflows in its
6107                         //native frames, to only need to do this for the
6108                         //other two formats
6109 
6110                         //Writer will handle all textflow except BtoT
6111 						if (GetSvxMSDffSettings() &
6112                             (SVXMSDFF_SETTINGS_IMPORT_PPT |
6113                              SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6114                         {
6115                             if( 0 != nPropVal )
6116                                 bCanBeReplaced = false;
6117                         }
6118                         else if (
6119                             (nPropVal != mso_txflHorzN) &&
6120                             (nPropVal != mso_txflTtoBA)
6121                                 )
6122                         {
6123                             bCanBeReplaced = false;
6124                         }
6125 					break;
6126 					case DFF_Prop_cdirFont :
6127                         //Writer can now handle right to left and left
6128                         //to right in its native frames, so only do
6129                         //this for the other two formats.
6130 						if (GetSvxMSDffSettings() &
6131                             (SVXMSDFF_SETTINGS_IMPORT_PPT |
6132                              SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6133                         {
6134                             if( 0 != nPropVal )
6135                                 bCanBeReplaced = sal_False;
6136                         }
6137                     break;
6138 					case DFF_Prop_Rotation :
6139 						if( 0 != nPropVal )
6140 							bCanBeReplaced = sal_False;
6141 					break;
6142 
6143 					case DFF_Prop_gtextFStrikethrough :
6144 						if( ( 0x20002000 & nPropVal )  == 0x20002000 )
6145 							bCanBeReplaced = sal_False;
6146 					break;
6147 
6148 					case DFF_Prop_fc3DLightFace :
6149 						if( ( 0x00080008 & nPropVal ) == 0x00080008 )
6150 							bCanBeReplaced = sal_False;
6151 					break;
6152 
6153 					case DFF_Prop_WrapText :
6154 						eWrapMode = (MSO_WrapMode)nPropVal;
6155 					break;
6156 
6157 					default:
6158 					{
6159 						// Bit gesetzt und gueltig?
6160 						if( 0x4000 == ( nPropId & 0xC000 ) )
6161 						{
6162 							// Blip Property gefunden: BStore Idx vermerken!
6163 							nPropRead = nLenShapePropTbl;
6164 						}
6165 						else if( 0x8000 & nPropId )
6166 						{
6167 							// komplexe Prop gefunden:
6168 							// Laenge ist immer 6, nur die Laenge der nach der
6169 							// eigentlichen Prop-Table anhaengenden Extra-Daten
6170 							// ist unterschiedlich
6171 							nPropVal = 6;
6172 						}
6173 					}
6174 					break;
6175 				}
6176 
6177 /*
6178 //JP 21.04.99: Bug 64510
6179 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge
6180 // Performance einbussen hat.
6181 
6182 				if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig?
6183 				{
6184 					// Blip Property gefunden: BStore Idx vermerken!
6185 					aInfo.nBStoreIdx = nPropVal;    // Index im BStore Container
6186 					break;
6187 				}
6188 				else
6189 				if(    (    (    (DFF_Prop_txflTextFlow   == nPropId)
6190 							  || (DFF_Prop_Rotation       == nPropId)
6191 							  || (DFF_Prop_cdirFont       == nPropId) )
6192 						 && (0 != nPropVal) )
6193 
6194 					|| (    (DFF_Prop_gtextFStrikethrough == nPropId)
6195 						 && ( (0x20002000 & nPropVal)  == 0x20002000) ) // also DFF_Prop_gtextFVertical
6196 					|| (    (DFF_Prop_fc3DLightFace       == nPropId)
6197 						 && ( (0x00080008 & nPropVal)  == 0x00080008) )	// also DFF_Prop_f3D
6198 				  )
6199 				{
6200 					bCanBeReplaced = sal_False;  // Mist: gedrehter Text oder 3D-Objekt!
6201 				}
6202 				else
6203 				if( DFF_Prop_WrapText == nPropId )
6204 				{
6205 					eWrapMode = (MSO_WrapMode)nPropVal;
6206 				}
6207 				////////////////////////////////////////////////////////////////
6208 				////////////////////////////////////////////////////////////////
6209 				// keine weitere Property-Auswertung: folge beim Shape-Import //
6210 				////////////////////////////////////////////////////////////////
6211 				////////////////////////////////////////////////////////////////
6212 				else
6213 				if( 0x8000 & nPropId )
6214 				{
6215 					// komplexe Prop gefunden: Laenge lesen und ueberspringen
6216 					if(!SkipBytes( rSt, nPropVal )) return sal_False;
6217 					nPropRead += nPropVal;
6218 				}
6219 */
6220 			}
6221 			while( nPropRead < nLenShapePropTbl );
6222 			rSt.Seek( nStartShapePropTbl + nLenShapePropTbl );
6223 			nReadSpCont += nLenShapePropTbl;
6224 		}
6225 		else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) )	// Text-Box-Story-Eintrag gefunden
6226 		{
6227 			rSt >> aInfo.nTxBxComp;
6228             // --> OD 2008-07-28 #156763#
6229             // Add internal drawing container id to text id.
6230             // Note: The text id uses the first two bytes, while the internal
6231             // drawing container id used the second two bytes.
6232             aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) +
6233                               nDrawingContainerId;
6234             DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId,
6235                         "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." );
6236             // <--
6237 		}
6238 		else
6239 		{
6240 			rSt.SeekRel( nLength );
6241 			nReadSpCont += nLength;
6242 		}
6243 	}
6244 	while( nReadSpCont < nLenShapeCont );
6245 
6246 	//
6247 	// Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern
6248 	//
6249 	if( aInfo.nShapeId )
6250 	{
6251 		// fuer Textboxen ggfs. ersetzen durch Rahmen erlauben
6252 		if(     bCanBeReplaced
6253 			 && aInfo.nTxBxComp
6254 			 && (
6255 					( eShapeType == mso_sptTextSimple )
6256 				 || ( eShapeType == mso_sptTextBox    )
6257 				 || (    (    ( eShapeType == mso_sptRectangle      )
6258 						   || ( eShapeType == mso_sptRoundRectangle )
6259 						 )
6260 				) ) )
6261 		{
6262 			aInfo.bReplaceByFly = sal_True;
6263 		}
6264 		pShapeInfos->Insert(  new SvxMSDffShapeInfo(  aInfo          ) );
6265 		pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ),
6266 							  pShapeOrders->Count() );
6267 	}
6268 
6269 	// und den Stream wieder korrekt positionieren
6270 	rSt.Seek( nStartShapeCont + nLenShapeCont );
6271 	return sal_True;
6272 }
6273 
6274 
6275 
6276 /*****************************************************************************
6277 
6278 	Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id)
6279 	----------------------------------
6280 ******************************************************************************/
6281 sal_Bool SvxMSDffManager::GetShape(sal_uLong nId, SdrObject*&         rpShape,
6282 										  SvxMSDffImportData& rData)
6283 {
6284 	SvxMSDffShapeInfo aTmpRec(0, nId);
6285 	aTmpRec.bSortByShapeId = sal_True;
6286 
6287 	sal_uInt16 nFound;
6288 	if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) )
6289 	{
6290 		SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound );
6291 
6292 		// eventuell altes Errorflag loeschen
6293 		if( rStCtrl.GetError() )
6294 			rStCtrl.ResetError();
6295 		// FilePos des/der Stream(s) merken
6296 		sal_uLong nOldPosCtrl = rStCtrl.Tell();
6297 		sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6298 		// das Shape im Steuer Stream anspringen
6299 		rStCtrl.Seek( rInfo.nFilePos );
6300 
6301 		// Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt!
6302 		if( rStCtrl.GetError() )
6303 			rStCtrl.ResetError();
6304 		else
6305 			rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect );
6306 
6307 		// alte FilePos des/der Stream(s) restaurieren
6308 		rStCtrl.Seek( nOldPosCtrl );
6309 		if( &rStCtrl != pStData )
6310 			pStData->Seek( nOldPosData );
6311 		return ( 0 != rpShape );
6312 	}
6313 	return sal_False;
6314 }
6315 
6316 
6317 
6318 /*      Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr)
6319 	---------------------------------
6320 ******************************************************************************/
6321 sal_Bool SvxMSDffManager::GetBLIP( sal_uLong nIdx_, Graphic& rData, Rectangle* pVisArea ) const
6322 {
6323 	sal_Bool bOk = sal_False;       // Ergebnisvariable initialisieren
6324 	if ( pStData )
6325 	{
6326         // check if a graphic for this blipId is already imported
6327         if ( nIdx_ && pEscherBlipCache )
6328         {
6329             EscherBlipCacheEntry* pEntry;
6330             for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry;
6331                     pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() )
6332             {
6333                 if ( pEntry->nBlip == nIdx_ )
6334                 {	/* if this entry is available, then it should be possible
6335 					to get the Graphic via GraphicObject */
6336 					GraphicObject aGraphicObject( pEntry->aUniqueID );
6337                     rData = aGraphicObject.GetGraphic();
6338 					if ( rData.GetType() != GRAPHIC_NONE )
6339 	                    bOk = sal_True;
6340 					else
6341 						delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove();
6342 					break;
6343                 }
6344             }
6345         }
6346         if ( !bOk )
6347         {
6348 		    sal_uInt16 nIdx = sal_uInt16( nIdx_ );
6349 		    if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return sal_False;
6350 
6351 		    // eventuell alte(s) Errorflag(s) loeschen
6352 		    if( rStCtrl.GetError() )
6353 			    rStCtrl.ResetError();
6354 		    if(    ( &rStCtrl != pStData )
6355 			    && pStData->GetError() )
6356 			    pStData->ResetError();
6357 
6358 		    // FilePos des/der Stream(s) merken
6359 		    sal_uLong nOldPosCtrl = rStCtrl.Tell();
6360 		    sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6361 
6362 		    // passende Info-Struct aus unserem Pointer Array nehmen
6363 		    SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ];
6364 
6365 		    // das BLIP Atom im Daten Stream anspringen
6366 		    pStData->Seek( rInfo.nFilePos );
6367 		    // ggfs. Fehlerstatus zuruecksetzen
6368 		    if( pStData->GetError() )
6369 			    pStData->ResetError();
6370 		    else
6371 			    bOk = GetBLIPDirect( *pStData, rData, pVisArea );
6372 		    if( pStData2 && !bOk )
6373 		    {
6374 			    // Fehler, aber zweite Chance: es gibt noch einen zweiten
6375 			    //         Datenstream, in dem die Grafik liegen koennte!
6376 			    if( pStData2->GetError() )
6377 				    pStData2->ResetError();
6378 			    sal_uLong nOldPosData2 = pStData2->Tell();
6379 			    // das BLIP Atom im zweiten Daten Stream anspringen
6380 			    pStData2->Seek( rInfo.nFilePos );
6381 			    // ggfs. Fehlerstatus zuruecksetzen
6382 			    if( pStData2->GetError() )
6383 				    pStData2->ResetError();
6384 			    else
6385 				    bOk = GetBLIPDirect( *pStData2, rData, pVisArea );
6386 			    // alte FilePos des zweiten Daten-Stream restaurieren
6387 			    pStData2->Seek( nOldPosData2 );
6388 		    }
6389 		    // alte FilePos des/der Stream(s) restaurieren
6390 		    rStCtrl.Seek( nOldPosCtrl );
6391 		    if( &rStCtrl != pStData )
6392 		      pStData->Seek( nOldPosData );
6393 
6394             if ( bOk )
6395             {
6396                 // create new BlipCacheEntry for this graphic
6397 				GraphicObject aGraphicObject( rData );
6398                 if ( !pEscherBlipCache )
6399                     const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List();
6400                 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() );
6401                 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND );
6402             }
6403         }
6404 	}
6405 	return bOk;
6406 }
6407 
6408 /*      Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream)
6409 	---------------------------------
6410 ******************************************************************************/
6411 sal_Bool SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const
6412 {
6413 	sal_uLong nOldPos = rBLIPStream.Tell();
6414 
6415 	int nRes = GRFILTER_OPENERROR;  // Fehlervariable initialisieren
6416 
6417 	// nachschauen, ob es sich auch wirklich um ein BLIP handelt
6418 	sal_uInt32 nLength;
6419 	sal_uInt16 nInst, nFbt( 0 );
6420 	sal_uInt8   nVer;
6421 	if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) )
6422 	{
6423 		Size		aMtfSize100;
6424 		sal_Bool		bMtfBLIP = sal_False;
6425 		sal_Bool		bZCodecCompression = sal_False;
6426 		// Nun exakt auf den Beginn der eingebetteten Grafik positionieren
6427 		sal_uLong nSkip = ( nInst & 0x0001 ) ? 32 : 16;
6428 
6429 		switch( nInst & 0xFFFE )
6430 		{
6431 			case 0x216 :			// Metafile header then compressed WMF
6432 			case 0x3D4 :			// Metafile header then compressed EMF
6433 			case 0x542 :			// Metafile hd. then compressed PICT
6434 			{
6435 				rBLIPStream.SeekRel( nSkip + 20 );
6436 
6437 				// read in size of metafile in EMUS
6438 				rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height();
6439 
6440 				// scale to 1/100mm
6441 				aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360;
6442 
6443 				if ( pVisArea )		// seem that we currently are skipping the visarea position
6444 					*pVisArea = Rectangle( Point(), aMtfSize100 );
6445 
6446 				// skip rest of header
6447 				nSkip = 6;
6448 				bMtfBLIP = bZCodecCompression = sal_True;
6449 			}
6450 			break;
6451 			case 0x46A :			// One byte tag then JPEG (= JFIF) data
6452 			case 0x6E0 :			// One byte tag then PNG data
6453 			case 0x6E2 :			// One byte tag then JPEG in CMYK color space
6454 			case 0x7A8 :
6455 				nSkip += 1;			// One byte tag then DIB data
6456 			break;
6457 		}
6458 		rBLIPStream.SeekRel( nSkip );
6459 
6460 		SvStream* pGrStream = &rBLIPStream;
6461 		SvMemoryStream* pOut = NULL;
6462 		if( bZCodecCompression )
6463 		{
6464 			pOut = new SvMemoryStream( 0x8000, 0x4000 );
6465 			ZCodec aZCodec( 0x8000, 0x8000 );
6466 			aZCodec.BeginCompression();
6467 			aZCodec.Decompress( rBLIPStream, *pOut );
6468 			aZCodec.EndCompression();
6469 			pOut->Seek( STREAM_SEEK_TO_BEGIN );
6470 			pOut->SetResizeOffset( 0 );	// sj: #i102257# setting ResizeOffset of 0 prevents from seeking
6471 										// behind the stream end (allocating too much memory)
6472 			pGrStream = pOut;
6473 		}
6474 
6475 //#define DBG_EXTRACTGRAPHICS
6476 #ifdef DBG_EXTRACTGRAPHICS
6477 
6478 		static sal_Int32 nCount;
6479 
6480 		String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) );
6481 		aFileName.Append( String::CreateFromInt32( nCount++ ) );
6482 		switch( nInst &~ 1 )
6483 		{
6484 			case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break;
6485 			case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break;
6486 			case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break;
6487 			case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
6488 			case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break;
6489 			case 0x6e2 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
6490 			case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break;
6491 		}
6492 
6493 		String aURLStr;
6494 
6495 		if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
6496 		{
6497 			INetURLObject aURL( aURLStr );
6498 
6499 			aURL.removeSegment();
6500 			aURL.removeFinalSlash();
6501 			aURL.Append( aFileName );
6502 
6503 			SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE );
6504 
6505 			if( pDbgOut )
6506 			{
6507 				if ( bZCodecCompression )
6508 				{
6509 					pOut->Seek( STREAM_SEEK_TO_END );
6510 					pDbgOut->Write( pOut->GetData(), pOut->Tell() );
6511 					pOut->Seek( STREAM_SEEK_TO_BEGIN );
6512 				}
6513 				else
6514 				{
6515 					sal_Int32 nDbgLen = nLength - nSkip;
6516 					if ( nDbgLen )
6517 					{
6518 						sal_Char* pDat = new sal_Char[ nDbgLen ];
6519 						pGrStream->Read( pDat, nDbgLen );
6520 						pDbgOut->Write( pDat, nDbgLen );
6521 						pGrStream->SeekRel( -nDbgLen );
6522 						delete[] pDat;
6523 					}
6524 				}
6525 
6526 				delete pDbgOut;
6527 			}
6528 		}
6529 #endif
6530 
6531 		if( ( nInst & 0xFFFE ) == 0x7A8 )
6532 		{	// DIBs direkt holen
6533 			Bitmap aNew;
6534 			if( aNew.Read( *pGrStream, sal_False ) )
6535 			{
6536 				rData = Graphic( aNew );
6537 				nRes = GRFILTER_OK;
6538 			}
6539 		}
6540 		else
6541 		{	// und unsere feinen Filter darauf loslassen
6542 			GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
6543 			String aEmptyStr;
6544 			nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW );
6545 
6546 			// SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems,
6547 			// then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the
6548 			// scaling has been implemented does not happen anymore.
6549 			//
6550 			// For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the
6551 			// dxarray is empty (this has been solved in wmf/emf but not for pict)
6552 			if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) )
6553 			{
6554 				if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) )
6555 				{	// #75956#, scaling does not work properly, if the graphic is less than 1cm
6556 					GDIMetaFile	aMtf( rData.GetGDIMetaFile() );
6557 					const Size	aOldSize( aMtf.GetPrefSize() );
6558 
6559 					if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) &&
6560 						aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) )
6561 					{
6562 						aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(),
6563 									(double) aMtfSize100.Height() / aOldSize.Height() );
6564 						aMtf.SetPrefSize( aMtfSize100 );
6565 						aMtf.SetPrefMapMode( MAP_100TH_MM );
6566 						rData = aMtf;
6567 					}
6568 				}
6569 			}
6570 		}
6571 		// ggfs. Fehlerstatus zuruecksetzen
6572 		if ( ERRCODE_IO_PENDING == pGrStream->GetError() )
6573 		  pGrStream->ResetError();
6574 		delete pOut;
6575 	}
6576 	rBLIPStream.Seek( nOldPos );    // alte FilePos des Streams restaurieren
6577 
6578 	return ( GRFILTER_OK == nRes ); // Ergebniss melden
6579 }
6580 
6581 /* static */
6582 sal_Bool SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn)
6583 {
6584 	rRec.nFilePos = rIn.Tell();
6585 	return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer,
6586 													rRec.nRecInstance,
6587 													rRec.nRecType,
6588 													rRec.nRecLen );
6589 }
6590 
6591 
6592 /* auch static */
6593 sal_Bool SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt,
6594 											  sal_uInt8&     rVer,
6595 											  sal_uInt16&   rInst,
6596 											  sal_uInt16&   rFbt,
6597 											  sal_uInt32&    rLength )
6598 {
6599 	sal_uInt16 nTmp;
6600 	rSt >> nTmp >> rFbt >> rLength;
6601 	rVer = sal::static_int_cast< sal_uInt8 >(nTmp & 15);
6602 	rInst = nTmp >> 4;
6603 	if ( rLength > ( SAL_MAX_UINT32 - rSt.Tell() ) )	// preserving overflow, optimal would be to check
6604 		rSt.SetError( SVSTREAM_FILEFORMAT_ERROR );		// the record size against the parent header
6605 	return rSt.GetError() == 0;
6606 }
6607 
6608 
6609 
6610 
6611 sal_Bool SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, sal_uLong nDatLen,
6612 										  char*& rpBuff, sal_uInt32& rBuffLen ) const
6613 {
6614 	if( nDatLen )
6615 	{
6616 		rpBuff = new (std::nothrow) char[ nDatLen ];
6617 		rBuffLen = nDatLen;
6618 		rStData.Read( rpBuff, nDatLen );
6619 	}
6620 	return sal_True;
6621 }
6622 
6623 sal_Bool SvxMSDffManager::ProcessClientData(SvStream& rStData, sal_uLong nDatLen,
6624 										char*& rpBuff, sal_uInt32& rBuffLen ) const
6625 {
6626 	if( nDatLen )
6627 	{
6628 		rpBuff = new (std::nothrow) char[ nDatLen ];
6629 		if ( rpBuff )
6630 		{
6631 			rBuffLen = nDatLen;
6632 			rStData.Read( rpBuff, nDatLen );
6633 		}
6634 	}
6635 	return sal_True;
6636 }
6637 
6638 
6639 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ )
6640 {
6641 	return;  // wird von SJ im Draw ueberladen
6642 }
6643 
6644 sal_uLong SvxMSDffManager::Calc_nBLIPPos( sal_uLong nOrgVal, sal_uLong /* nStreamPos */ ) const
6645 {
6646 	return nOrgVal;
6647 }
6648 
6649 sal_Bool SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const
6650 {
6651 	return sal_False;
6652 }
6653 
6654 sal_Bool SvxMSDffManager::ShapeHasText( sal_uLong /* nShapeId */, sal_uLong /* nFilePos */ ) const
6655 {
6656 	return sal_True;
6657 }
6658 
6659 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup>
6660 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId,
6661                                        const Graphic& rGrf,
6662                                        const Rectangle& rBoundRect,
6663 									   const Rectangle& rVisArea,
6664                                        const int /* _nCalledByGroup */,
6665 									   sal_Int64 nAspect ) const
6666 // <--
6667 {
6668     SdrObject* pRet = 0;
6669 	String sStorageName;
6670     SvStorageRef xSrcStg;
6671     ErrCode nError = ERRCODE_NONE;
6672     uno::Reference < embed::XStorage > xDstStg;
6673 	if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
6674 		pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg,
6675                                         rGrf, rBoundRect, rVisArea, pStData, nError,
6676 										nSvxMSDffOLEConvFlags, nAspect );
6677 	return pRet;
6678 }
6679 
6680 sal_Bool SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf )
6681 {
6682 	String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) );
6683 	SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream );
6684 	xStm->SetVersion( pStor->GetVersion() );
6685 	xStm->SetBufferSize( 8192 );
6686 
6687     sal_uInt16 nAspect = ASPECT_CONTENT;
6688     sal_uLong nAdviseModes = 2;
6689 
6690 	Impl_OlePres aEle( FORMAT_GDIMETAFILE );
6691 	// Die Groesse in 1/100 mm umrechnen
6692 	// Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird,
6693 	// versucht SV einen BestMatchden richtigen Wert zu raten.
6694 	Size aSize = rMtf.GetPrefSize();
6695 	MapMode aMMSrc = rMtf.GetPrefMapMode();
6696 	MapMode aMMDst( MAP_100TH_MM );
6697 	aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
6698 	aEle.SetSize( aSize );
6699  	aEle.SetAspect( nAspect );
6700 	aEle.SetAdviseFlags( nAdviseModes );
6701 	aEle.SetMtf( rMtf );
6702     aEle.Write( *xStm );
6703 
6704 	xStm->SetBufferSize( 0 );
6705 	return xStm->GetError() == SVSTREAM_OK;
6706 }
6707 
6708 struct ClsIDs {
6709 	sal_uInt32		nId;
6710 	const sal_Char* pSvrName;
6711 	const sal_Char* pDspName;
6712 };
6713 static ClsIDs aClsIDs[] = {
6714 
6715 	{ 0x000212F0, "MSWordArt",     		"Microsoft Word Art"	 		},
6716 	{ 0x000212F0, "MSWordArt.2",   		"Microsoft Word Art 2.0" 		},
6717 
6718 	// MS Apps
6719 	{ 0x00030000, "ExcelWorksheet",		"Microsoft Excel Worksheet"		},
6720 	{ 0x00030001, "ExcelChart",			"Microsoft Excel Chart"			},
6721 	{ 0x00030002, "ExcelMacrosheet",	"Microsoft Excel Macro"			},
6722 	{ 0x00030003, "WordDocument",		"Microsoft Word Document"		},
6723 	{ 0x00030004, "MSPowerPoint",		"Microsoft PowerPoint"			},
6724 	{ 0x00030005, "MSPowerPointSho",	"Microsoft PowerPoint Slide Show"},
6725 	{ 0x00030006, "MSGraph",			"Microsoft Graph"				},
6726 	{ 0x00030007, "MSDraw",				"Microsoft Draw"				},
6727 	{ 0x00030008, "Note-It",			"Microsoft Note-It"				},
6728 	{ 0x00030009, "WordArt",			"Microsoft Word Art"			},
6729 	{ 0x0003000a, "PBrush",				"Microsoft PaintBrush Picture"	},
6730 	{ 0x0003000b, "Equation",			"Microsoft Equation Editor"		},
6731 	{ 0x0003000c, "Package",			"Package"						},
6732 	{ 0x0003000d, "SoundRec",			"Sound"							},
6733 	{ 0x0003000e, "MPlayer",			"Media Player"					},
6734 	// MS Demos
6735 	{ 0x0003000f, "ServerDemo",			"OLE 1.0 Server Demo"			},
6736 	{ 0x00030010, "Srtest",				"OLE 1.0 Test Demo"				},
6737 	{ 0x00030011, "SrtInv",				"OLE 1.0 Inv Demo"				},
6738 	{ 0x00030012, "OleDemo",			"OLE 1.0 Demo"					},
6739 
6740 	// Coromandel / Dorai Swamy / 718-793-7963
6741 	{ 0x00030013, "CoromandelIntegra",	"Coromandel Integra"			},
6742 	{ 0x00030014, "CoromandelObjServer","Coromandel Object Server"		},
6743 
6744 	// 3-d Visions Corp / Peter Hirsch / 310-325-1339
6745 	{ 0x00030015, "StanfordGraphics",	"Stanford Graphics"				},
6746 
6747 	// Deltapoint / Nigel Hearne / 408-648-4000
6748 	{ 0x00030016, "DGraphCHART",		"DeltaPoint Graph Chart"		},
6749 	{ 0x00030017, "DGraphDATA",			"DeltaPoint Graph Data"			},
6750 
6751 	// Corel / Richard V. Woodend / 613-728-8200 x1153
6752 	{ 0x00030018, "PhotoPaint",			"Corel PhotoPaint"				},
6753 	{ 0x00030019, "CShow",				"Corel Show"					},
6754 	{ 0x0003001a, "CorelChart",			"Corel Chart"					},
6755 	{ 0x0003001b, "CDraw",				"Corel Draw"					},
6756 
6757 	// Inset Systems / Mark Skiba / 203-740-2400
6758 	{ 0x0003001c, "HJWIN1.0",			"Inset Systems"					},
6759 
6760 	// Mark V Systems / Mark McGraw / 818-995-7671
6761 	{ 0x0003001d, "ObjMakerOLE",		"MarkV Systems Object Maker"	},
6762 
6763 	// IdentiTech / Mike Gilger / 407-951-9503
6764 	{ 0x0003001e, "FYI",				"IdentiTech FYI"				},
6765 	{ 0x0003001f, "FYIView",			"IdentiTech FYI Viewer"			},
6766 
6767 	// Inventa Corporation / Balaji Varadarajan / 408-987-0220
6768 	{ 0x00030020, "Stickynote",			"Inventa Sticky Note"			},
6769 
6770 	// ShapeWare Corp. / Lori Pearce / 206-467-6723
6771 	{ 0x00030021, "ShapewareVISIO10",   "Shapeware Visio 1.0"			},
6772 	{ 0x00030022, "ImportServer",		"Spaheware Import Server"		},
6773 
6774 	// test app SrTest
6775 	{ 0x00030023, "SrvrTest",			"OLE 1.0 Server Test"			},
6776 
6777 	// test app ClTest.  Doesn't really work as a server but is in reg db
6778 	{ 0x00030025, "Cltest",				"OLE 1.0 Client Test"			},
6779 
6780 	// Microsoft ClipArt Gallery   Sherry Larsen-Holmes
6781 	{ 0x00030026, "MS_ClipArt_Gallery",	"Microsoft ClipArt Gallery"		},
6782 	// Microsoft Project  Cory Reina
6783 	{ 0x00030027, "MSProject",			"Microsoft Project"				},
6784 
6785 	// Microsoft Works Chart
6786 	{ 0x00030028, "MSWorksChart",		"Microsoft Works Chart"			},
6787 
6788 	// Microsoft Works Spreadsheet
6789 	{ 0x00030029, "MSWorksSpreadsheet",	"Microsoft Works Spreadsheet"	},
6790 
6791 	// AFX apps - Dean McCrory
6792 	{ 0x0003002A, "MinSvr",				"AFX Mini Server"				},
6793 	{ 0x0003002B, "HierarchyList",		"AFX Hierarchy List"			},
6794 	{ 0x0003002C, "BibRef",				"AFX BibRef"					},
6795 	{ 0x0003002D, "MinSvrMI",			"AFX Mini Server MI"			},
6796 	{ 0x0003002E, "TestServ",			"AFX Test Server"				},
6797 
6798 	// Ami Pro
6799 	{ 0x0003002F, "AmiProDocument",		"Ami Pro Document"				},
6800 
6801 	// WordPerfect Presentations For Windows
6802 	{ 0x00030030, "WPGraphics",			"WordPerfect Presentation"		},
6803 	{ 0x00030031, "WPCharts",			"WordPerfect Chart"				},
6804 
6805 	// MicroGrafx Charisma
6806 	{ 0x00030032, "Charisma",			"MicroGrafx Charisma"			},
6807 	{ 0x00030033, "Charisma_30",		"MicroGrafx Charisma 3.0"		},
6808 	{ 0x00030034, "CharPres_30",		"MicroGrafx Charisma 3.0 Pres"	},
6809 	// MicroGrafx Draw
6810 	{ 0x00030035, "Draw",				"MicroGrafx Draw"				},
6811 	// MicroGrafx Designer
6812 	{ 0x00030036, "Designer_40",		"MicroGrafx Designer 4.0"		},
6813 
6814 	// STAR DIVISION
6815 //	{ 0x000424CA, "StarMath",			"StarMath 1.0"					},
6816 	{ 0x00043AD2, "FontWork",			"Star FontWork"					},
6817 //	{ 0x000456EE, "StarMath2",			"StarMath 2.0"					},
6818 
6819 	{ 0, "", "" } };
6820 
6821 
6822 sal_Bool SvxMSDffManager::ConvertToOle2( SvStream& rStm, sal_uInt32 nReadLen,
6823 					const GDIMetaFile * pMtf, const SotStorageRef& rDest )
6824 {
6825 	sal_Bool bMtfRead = sal_False;
6826 	SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ),
6827 													STREAM_WRITE| STREAM_SHARE_DENYALL );
6828 	if( xOle10Stm->GetError() )
6829 		return sal_False;
6830 
6831 	sal_uInt32 nType;
6832 	sal_uInt32 nRecType;
6833 	sal_uInt32 nStrLen;
6834 	String aSvrName;
6835 	sal_uInt32 nDummy0;
6836 	sal_uInt32 nDummy1;
6837 	sal_uInt32 nDataLen;
6838 	sal_uInt8 * pData;
6839 	sal_uInt32 nBytesRead = 0;
6840 	do
6841 	{
6842 		rStm >> nType;
6843 		rStm >> nRecType;
6844 		rStm >> nStrLen;
6845 		if( nStrLen )
6846 		{
6847 			if( 0x10000L > nStrLen )
6848 			{
6849 				sal_Char * pBuf = new sal_Char[ nStrLen ];
6850 				rStm.Read( pBuf, nStrLen );
6851                 aSvrName.Assign( String( pBuf, (sal_uInt16) nStrLen-1, gsl_getSystemTextEncoding() ) );
6852                 delete[] pBuf;
6853 			}
6854 			else
6855 				break;
6856 		}
6857 		rStm >> nDummy0;
6858 		rStm >> nDummy1;
6859 		rStm >> nDataLen;
6860 
6861 		nBytesRead += 6 * sizeof( sal_uInt32 ) + nStrLen + nDataLen;
6862 
6863 		if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen )
6864 		{
6865 			if( xOle10Stm.Is() )
6866 			{
6867 				pData = new sal_uInt8[ nDataLen ];
6868 				if( !pData )
6869 					return sal_False;
6870 
6871 				rStm.Read( pData, nDataLen );
6872 
6873 				// write to ole10 stream
6874 				*xOle10Stm << nDataLen;
6875 				xOle10Stm->Write( pData, nDataLen );
6876 				xOle10Stm = SotStorageStreamRef();
6877 
6878 				// set the compobj stream
6879 				ClsIDs* pIds;
6880 				for( pIds = aClsIDs; pIds->nId; pIds++ )
6881 				{
6882 					if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) )
6883 						break;
6884 				}
6885 //				SvGlobalName* pClsId = NULL;
6886 				String aShort, aFull;
6887 				if( pIds->nId )
6888 				{
6889 					// gefunden!
6890 					sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName );
6891 					rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt,
6892 									String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) );
6893 				}
6894 				else
6895 				{
6896 					sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName );
6897 					rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName );
6898 				}
6899 
6900                 delete[] pData;
6901 			}
6902 			else if( nRecType == 5 && !pMtf )
6903 			{
6904 				sal_uLong nPos = rStm.Tell();
6905 				sal_uInt16 sz[4];
6906 				rStm.Read( sz, 8 );
6907 				//rStm.SeekRel( 8 );
6908 				Graphic aGraphic;
6909 				if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() )
6910 				{
6911 					const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
6912 					MakeContentStream( rDest, rMtf );
6913 					bMtfRead = sal_True;
6914 				}
6915 				// set behind the data
6916 				rStm.Seek( nPos + nDataLen );
6917             }
6918 			else
6919 				rStm.SeekRel( nDataLen );
6920 		}
6921 	} while( !rStm.IsEof() && nReadLen >= nBytesRead );
6922 
6923 	if( !bMtfRead && pMtf )
6924 	{
6925 		MakeContentStream( rDest, *pMtf );
6926 		return sal_True;
6927     }
6928 
6929 	return sal_False;
6930 }
6931 
6932 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName )
6933 {
6934 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 )
6935 	  || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
6936         return "swriter";
6937 	else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 )
6938 	  || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
6939         return "scalc";
6940 	else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 )
6941 	  || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
6942         return "simpress";
6943 	else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 )
6944       || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
6945         return "sdraw";
6946 	else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 )
6947       || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
6948         return "smath";
6949 	else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 )
6950 	  || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
6951         return "schart";
6952     return 0;
6953 }
6954 
6955 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
6956 {
6957 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) )
6958         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) );
6959 
6960 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
6961         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) );
6962 
6963 	if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) )
6964         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) );
6965 
6966 	if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
6967         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) );
6968 
6969 	if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
6970         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) );
6971 
6972 	if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
6973         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) );
6974 
6975 	if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
6976         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) );
6977 
6978     if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
6979         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) );
6980 
6981 	if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) )
6982         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) );
6983 
6984     if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
6985         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) );
6986 
6987 	if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
6988         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) );
6989 
6990 	if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
6991         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) );
6992 
6993     return ::rtl::OUString();
6994 }
6995 
6996 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >  SvxMSDffManager::CheckForConvertToSOObj( sal_uInt32 nConvertFlags,
6997                         SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage,
6998                         const Graphic& rGrf,
6999 						const Rectangle& rVisArea )
7000 {
7001     uno::Reference < embed::XEmbeddedObject > xObj;
7002     SvGlobalName aStgNm = rSrcStg.GetClassName();
7003     const char* pName = GetInternalServerName_Impl( aStgNm );
7004     String sStarName;
7005     if ( pName )
7006         sStarName = String::CreateFromAscii( pName );
7007     else if ( nConvertFlags )
7008     {
7009         static struct _ObjImpType
7010         {
7011             sal_uInt32 nFlag;
7012             const char* pFactoryNm;
7013             // GlobalNameId
7014             sal_uInt32 n1;
7015             sal_uInt16 n2, n3;
7016             sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15;
7017         } aArr[] = {
7018             { OLE_MATHTYPE_2_STARMATH, "smath",
7019                 0x0002ce02L, 0x0000, 0x0000,
7020                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7021             { OLE_MATHTYPE_2_STARMATH, "smath",
7022                 0x00021700L, 0x0000, 0x0000,
7023                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7024             { OLE_WINWORD_2_STARWRITER, "swriter",
7025                 0x00020906L, 0x0000, 0x0000,
7026                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7027             { OLE_EXCEL_2_STARCALC, "scalc",                // Excel table
7028                 0x00020810L, 0x0000, 0x0000,
7029                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7030             { OLE_EXCEL_2_STARCALC, "scalc",                // Excel chart
7031                 0x00020820L, 0x0000, 0x0000,
7032                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7033             // 114465: additional Excel OLE chart classId to above.
7034             { OLE_EXCEL_2_STARCALC, "scalc",
7035                 0x00020821L, 0x0000, 0x0000,
7036                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7037             { OLE_POWERPOINT_2_STARIMPRESS, "simpress",     // PowerPoint presentation
7038                 0x64818d10L, 0x4f9b, 0x11cf,
7039                 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7040             { OLE_POWERPOINT_2_STARIMPRESS, "simpress",     // PowerPoint slide
7041                 0x64818d11L, 0x4f9b, 0x11cf,
7042                 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7043             { 0, 0,
7044 			  0, 0, 0,
7045 			  0, 0, 0, 0, 0, 0, 0, 0 }
7046         };
7047 
7048         for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr )
7049         {
7050             if( nConvertFlags & pArr->nFlag )
7051             {
7052                 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3,
7053                                 pArr->b8, pArr->b9, pArr->b10, pArr->b11,
7054                                 pArr->b12, pArr->b13, pArr->b14, pArr->b15 );
7055 
7056                 if ( aStgNm == aTypeName )
7057                 {
7058                     sStarName = String::CreateFromAscii( pArr->pFactoryNm );
7059                     break;
7060                 }
7061             }
7062         }
7063     }
7064 
7065     if ( sStarName.Len() )
7066     {
7067         //TODO/MBA: check if (and when) storage and stream will be destroyed!
7068         const SfxFilter* pFilter = 0;
7069         SvMemoryStream* pStream = new SvMemoryStream;
7070         if ( pName )
7071         {
7072             // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also
7073             SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ );
7074             *xStr >> *pStream;
7075         }
7076         else
7077         {
7078             SfxFilterMatcher aMatch( sStarName );
7079             SotStorageRef xStorage = new SotStorage( sal_False, *pStream );
7080             rSrcStg.CopyTo( xStorage );
7081             xStorage->Commit();
7082             xStorage.Clear();
7083             String aType = SfxFilter::GetTypeFromStorage( rSrcStg );
7084             if ( aType.Len() )
7085                 pFilter = aMatch.GetFilter4EA( aType );
7086         }
7087 
7088         if ( pName || pFilter )
7089         {
7090             //Reuse current ole name
7091             String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7092             aDstStgName += String::CreateFromInt32(nMSOleObjCntr);
7093 
7094             ::rtl::OUString aFilterName;
7095             if ( pFilter )
7096                 aFilterName = pFilter->GetName();
7097             else
7098                 aFilterName = GetFilterNameFromClassID_Impl( aStgNm );
7099 
7100             uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2);
7101             aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
7102             uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream );
7103             aMedium[0].Value <<= xStream;
7104             aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
7105             aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
7106 
7107             if ( aFilterName.getLength() )
7108             {
7109                 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
7110                 aMedium[2].Value <<= aFilterName;
7111             }
7112 
7113             ::rtl::OUString aName( aDstStgName );
7114             comphelper::EmbeddedObjectContainer aCnt( rDestStorage );
7115             xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7116 
7117             if ( !xObj.is() )
7118             {
7119                 if( aFilterName.getLength() )
7120                 {
7121                     // throw the filter parameter away as workaround
7122                     aMedium.realloc( 2 );
7123                     xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7124                 }
7125 
7126                 if ( !xObj.is() )
7127                      return xObj;
7128             }
7129 
7130             // TODO/LATER: ViewAspect must be passed from outside!
7131             sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT;
7132 
7133             // JP 26.10.2001: Bug 93374 / 91928 the writer
7134             // objects need the correct visarea needs the
7135             // correct visarea, but this is not true for
7136             // PowerPoint (see bugdoc 94908b)
7137             // SJ: 19.11.2001 bug 94908, also chart objects
7138             // needs the correct visarea
7139 
7140 			// If pName is set this is an own embedded object, it should have the correct size internally
7141 			// TODO/LATER: it might make sence in future to set the size stored in internal object
7142             if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) )
7143             {
7144                 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) );
7145                 Size aSz;
7146 				if ( rVisArea.IsEmpty() )
7147 					aSz = lcl_GetPrefSize(rGrf, aMapMode );
7148 				else
7149 				{
7150 					aSz = rVisArea.GetSize();
7151 					aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode );
7152 				}
7153 
7154                 // don't modify the object
7155                 //TODO/LATER: remove those hacks, that needs to be done differently!
7156                 //xIPObj->EnableSetModified( sal_False );
7157                 awt::Size aSize;
7158                 aSize.Width = aSz.Width();
7159                 aSize.Height = aSz.Height();
7160                 xObj->setVisualAreaSize( nViewAspect, aSize );
7161                 //xIPObj->EnableSetModified( sal_True );
7162             }
7163             else if ( sStarName.EqualsAscii( "smath" ) )
7164             {   // SJ: force the object to recalc its visarea
7165                 //TODO/LATER: wait for PrinterChangeNotification
7166                 //xIPObj->OnDocumentPrinterChanged( NULL );
7167             }
7168         }
7169     }
7170 
7171     return xObj;
7172 }
7173 
7174 // TODO/MBA: code review and testing!
7175 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage(
7176 				const String& rStorageName,
7177 				SotStorageRef& rSrcStorage,
7178                 const uno::Reference < embed::XStorage >& xDestStorage,
7179 				const Graphic& rGrf,
7180 				const Rectangle& rBoundRect,
7181 				const Rectangle& rVisArea,
7182 				SvStream* pDataStrm,
7183                 ErrCode& rError,
7184 				sal_uInt32 nConvertFlags,
7185 				sal_Int64 nReccomendedAspect )
7186 {
7187 	sal_Int64 nAspect = nReccomendedAspect;
7188 	SdrOle2Obj* pRet = 0;
7189     if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() )
7190 	{
7191         comphelper::EmbeddedObjectContainer aCnt( xDestStorage );
7192 		// Ist der 01Ole-Stream ueberhaupt vorhanden ?
7193 		// ( ist er z.B. bei FontWork nicht )
7194 		// Wenn nicht -> Einbindung als Grafik
7195 		sal_Bool bValidStorage = sal_False;
7196 		String aDstStgName( String::CreateFromAscii(
7197 								RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7198 
7199 		aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr );
7200 
7201 		{
7202             SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName,
7203 								STREAM_READWRITE| STREAM_SHARE_DENYALL );
7204 			if( xObjStg.Is()  )
7205 			{
7206 				{
7207 					sal_uInt8 aTestA[10];	// exist the \1CompObj-Stream ?
7208 					SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream(
7209 								String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"),
7210 										RTL_TEXTENCODING_MS_1252 ));
7211 					bValidStorage = xSrcTst.Is() && sizeof( aTestA ) ==
7212 									xSrcTst->Read( aTestA, sizeof( aTestA ) );
7213 					if( !bValidStorage )
7214 					{
7215 						// or the \1Ole-Stream ?
7216 						xSrcTst = xObjStg->OpenSotStream(
7217 									String(RTL_CONSTASCII_STRINGPARAM("\1Ole"),
7218 											RTL_TEXTENCODING_MS_1252 ));
7219 						bValidStorage = xSrcTst.Is() && sizeof(aTestA) ==
7220 										xSrcTst->Read(aTestA, sizeof(aTestA));
7221 					}
7222 				}
7223 
7224                 if( bValidStorage )
7225 				{
7226 					if ( nAspect != embed::Aspects::MSOLE_ICON )
7227 					{
7228 						// check whether the object is iconified one
7229 						// usually this information is already known, the only exception
7230 						// is a kind of embedded objects in Word documents
7231 						// TODO/LATER: should the caller be notified if the aspect changes in future?
7232 
7233 						SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream(
7234 							String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ),
7235 							STREAM_STD_READ | STREAM_NOCREATE );
7236 						if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
7237 						{
7238 							sal_uInt8 nByte = 0;
7239 							*xObjInfoSrc >> nByte;
7240 							if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
7241 								nAspect = embed::Aspects::MSOLE_ICON;
7242 						}
7243 					}
7244 
7245                     uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj(
7246                                 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea ));
7247                     if ( xObj.is() )
7248     			    {
7249                         svt::EmbeddedObjectRef aObj( xObj, nAspect );
7250 
7251                         // TODO/LATER: need MediaType
7252                         aObj.SetGraphic( rGrf, ::rtl::OUString() );
7253 
7254                         // TODO/MBA: check setting of PersistName
7255                         pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false);
7256 						// we have the Object, don't create another
7257 						bValidStorage = false;
7258                     }
7259 				}
7260 			}
7261 		}
7262 
7263 		if( bValidStorage )
7264 		{
7265             // object is not an own object
7266             SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE );
7267 
7268 			if ( xObjStor.Is() )
7269 			{
7270 				SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ );
7271 				xSrcStor->CopyTo( xObjStor );
7272 
7273 				if( !xObjStor->GetError() )
7274 					xObjStor->Commit();
7275 
7276 				if( xObjStor->GetError() )
7277 				{
7278 				    rError = xObjStor->GetError();
7279 					bValidStorage = sal_False;
7280 				}
7281 				else if( !xObjStor.Is() )
7282 					bValidStorage = sal_False;
7283 			}
7284 		}
7285 		else if( pDataStrm )
7286 		{
7287 			sal_uInt32 nLen, nDummy;
7288 			*pDataStrm >> nLen >> nDummy;
7289 			if( SVSTREAM_OK != pDataStrm->GetError() ||
7290 				// Id in BugDoc - exist there other Ids?
7291 				// The ConvertToOle2 - does not check for consistent
7292 				0x30008 != nDummy )
7293 				bValidStorage = sal_False;
7294 			else
7295 			{
7296 				// or is it an OLE-1 Stream in the DataStream?
7297                 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName );
7298                 //TODO/MBA: remove metafile conversion from ConvertToOle2
7299                 //when is this code used?!
7300 				GDIMetaFile aMtf;
7301                 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor );
7302                 xObjStor->Commit();
7303 			}
7304         }
7305 
7306 		if( bValidStorage )
7307 		{
7308             uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName );
7309             if( xObj.is() )
7310             {
7311                 // the visual area must be retrieved from the metafile (object doesn't know it so far)
7312 
7313 				if ( nAspect != embed::Aspects::MSOLE_ICON )
7314 				{
7315                 	// working with visual area can switch the object to running state
7316                 	awt::Size aAwtSz;
7317 					try
7318 					{
7319 						// the provided visual area should be used, if there is any
7320 						if ( rVisArea.IsEmpty() )
7321 						{
7322                 			MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
7323                 			Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit)));
7324                 			aAwtSz.Width = aSz.Width();
7325                 			aAwtSz.Height = aSz.Height();
7326 						}
7327 						else
7328 						{
7329 							aAwtSz.Width = rVisArea.GetWidth();
7330 							aAwtSz.Height = rVisArea.GetHeight();
7331 						}
7332                 		//xInplaceObj->EnableSetModified( sal_False );
7333                 		xObj->setVisualAreaSize( nAspect, aAwtSz );
7334                 		//xInplaceObj->EnableSetModified( sal_True );*/
7335 					}
7336 					catch( uno::Exception& )
7337 					{
7338 						OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" );
7339 					}
7340 				}
7341 
7342                 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7343 
7344                 // TODO/LATER: need MediaType
7345                 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7346 
7347                 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false);
7348             }
7349 		}
7350 	}
7351 
7352 	return pRet;
7353 }
7354 
7355 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const
7356 {
7357 	SdrObject* pRet = NULL;
7358 
7359 	if(120 >= sal_uInt16(eTyp))
7360 	{
7361 		pRet = new SdrRectObj();
7362 	}
7363 
7364 	DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM");
7365 
7366 	return pRet;
7367 }
7368 
7369 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
7370 			const String& rPropName, sal_Bool bTestPropertyAvailability )
7371 {
7372     sal_Bool bRetValue = sal_True;
7373 	if ( bTestPropertyAvailability )
7374 	{
7375 		bRetValue = sal_False;
7376 		try
7377 		{
7378 			uno::Reference< beans::XPropertySetInfo >
7379 				aXPropSetInfo( rXPropSet->getPropertySetInfo() );
7380 			if ( aXPropSetInfo.is() )
7381 				bRetValue = aXPropSetInfo->hasPropertyByName( rPropName );
7382 		}
7383 		catch( uno::Exception& )
7384 		{
7385 			bRetValue = sal_False;
7386 		}
7387 	}
7388 	if ( bRetValue )
7389 	{
7390 		try
7391 		{
7392 			rXPropSet->setPropertyValue( rPropName, rAny );
7393 			bRetValue = sal_True;
7394 		}
7395 		catch( uno::Exception& )
7396 		{
7397 			bRetValue = sal_False;
7398 		}
7399 	}
7400     return bRetValue;
7401 }
7402 
7403 SvxMSDffImportRec::SvxMSDffImportRec()
7404     : pObj( 0 ),
7405       pWrapPolygon(0),
7406       pClientAnchorBuffer( 0 ),
7407       nClientAnchorLen(  0 ),
7408       pClientDataBuffer( 0 ),
7409       nClientDataLen(    0 ),
7410       nXAlign( 0 ),	// position n cm from left
7411       nXRelTo( 2 ), //   relative to column
7412       nYAlign( 0 ), // position n cm below
7413       nYRelTo( 2 ), //   relative to paragraph
7414       nLayoutInTableCell( 0 ), // element is laid out in table cell
7415       nTextRotationAngle( 0 ),
7416       nDxTextLeft( 144 ),
7417       nDyTextTop( 72 ),
7418       nDxTextRight(	144 ),
7419       nDyTextBottom( 72 ),
7420       nDxWrapDistLeft( 0 ),
7421       nDyWrapDistTop( 0 ),
7422       nDxWrapDistRight( 0 ),
7423       nDyWrapDistBottom(0 ),
7424       nCropFromTop( 0 ),
7425       nCropFromBottom( 0 ),
7426       nCropFromLeft( 0 ),
7427       nCropFromRight( 0 ),
7428       aTextId( 0, 0 ),
7429       nNextShapeId(	0 ),
7430       nShapeId( 0 ),
7431       eShapeType( mso_sptNil )
7432 {
7433       eLineStyle      = mso_lineSimple; // GPF-Bug #66227#
7434       bDrawHell       = sal_False;
7435       bHidden         = sal_False;
7436 //	  bInGroup		  = sal_False;
7437       bReplaceByFly   = sal_False;
7438       bLastBoxInChain = sal_True;
7439       bHasUDefProp    = sal_False; // was the DFF_msofbtUDefProp record set?
7440       bVFlip = sal_False;
7441       bHFlip = sal_False;
7442       bAutoWidth      = sal_False;
7443 }
7444 
7445 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy)
7446     : pObj(	rCopy.pObj ),
7447       nXAlign( rCopy.nXAlign ),
7448       nXRelTo( rCopy.nXRelTo ),
7449       nYAlign( rCopy.nYAlign ),
7450       nYRelTo( rCopy.nYRelTo ),
7451       nLayoutInTableCell( rCopy.nLayoutInTableCell ),
7452       nTextRotationAngle( rCopy.nTextRotationAngle ),
7453       nDxTextLeft( rCopy.nDxTextLeft	),
7454       nDyTextTop( rCopy.nDyTextTop ),
7455       nDxTextRight( rCopy.nDxTextRight ),
7456       nDyTextBottom( rCopy.nDyTextBottom ),
7457       nDxWrapDistLeft( rCopy.nDxWrapDistLeft ),
7458       nDyWrapDistTop( rCopy.nDyWrapDistTop ),
7459       nDxWrapDistRight( rCopy.nDxWrapDistRight ),
7460       nDyWrapDistBottom(rCopy.nDyWrapDistBottom ),
7461       nCropFromTop( rCopy.nCropFromTop ),
7462       nCropFromBottom( rCopy.nCropFromBottom ),
7463       nCropFromLeft( rCopy.nCropFromLeft ),
7464       nCropFromRight( rCopy.nCropFromRight ),
7465       aTextId( rCopy.aTextId ),
7466       nNextShapeId( rCopy.nNextShapeId ),
7467       nShapeId( rCopy.nShapeId ),
7468       eShapeType( rCopy.eShapeType )
7469 {
7470     eLineStyle       = rCopy.eLineStyle; // GPF-Bug #66227#
7471     bDrawHell        = rCopy.bDrawHell;
7472     bHidden          = rCopy.bHidden;
7473 //			bInGroup		 = rCopy.bInGroup;
7474     bReplaceByFly    = rCopy.bReplaceByFly;
7475     bAutoWidth       = rCopy.bAutoWidth;
7476     bLastBoxInChain  = rCopy.bLastBoxInChain;
7477     bHasUDefProp     = rCopy.bHasUDefProp;
7478     bVFlip = rCopy.bVFlip;
7479     bHFlip = rCopy.bHFlip;
7480     nClientAnchorLen = rCopy.nClientAnchorLen;
7481     if( rCopy.nClientAnchorLen )
7482     {
7483         pClientAnchorBuffer = new char[ nClientAnchorLen ];
7484         memcpy( pClientAnchorBuffer,
7485                 rCopy.pClientAnchorBuffer,
7486                 nClientAnchorLen );
7487     }
7488     else
7489         pClientAnchorBuffer = 0;
7490 
7491     nClientDataLen = rCopy.nClientDataLen;
7492     if( rCopy.nClientDataLen )
7493     {
7494         pClientDataBuffer = new char[ nClientDataLen ];
7495         memcpy( pClientDataBuffer,
7496                 rCopy.pClientDataBuffer,
7497                 nClientDataLen );
7498     }
7499     else
7500         pClientDataBuffer = 0;
7501 
7502     if (rCopy.pWrapPolygon)
7503         pWrapPolygon = new Polygon(*rCopy.pWrapPolygon);
7504     else
7505         pWrapPolygon = 0;
7506 }
7507 
7508 SvxMSDffImportRec::~SvxMSDffImportRec()
7509 {
7510     if (pClientAnchorBuffer)
7511         delete[] pClientAnchorBuffer;
7512     if (pClientDataBuffer)
7513         delete[] pClientDataBuffer;
7514     if (pWrapPolygon)
7515         delete pWrapPolygon;
7516 }
7517 
7518 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
7519 
7520 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape )
7521 {
7522 	maShapeIdContainer[nShapeId] = pShape;
7523 }
7524 
7525 void SvxMSDffManager::removeShapeId( SdrObject* pShape )
7526 {
7527 	SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() );
7528 	const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() );
7529 	while( aIter != aEnd )
7530 	{
7531 		if( (*aIter).second == pShape )
7532 		{
7533 			maShapeIdContainer.erase( aIter );
7534 			break;
7535 		}
7536 		aIter++;
7537 	}
7538 }
7539 
7540 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId )
7541 {
7542 	SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) );
7543 	return aIter != maShapeIdContainer.end() ? (*aIter).second : 0;
7544 }
7545