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 & 0x1fff );//Last 13 bits for segment points number
2366 					switch( nTmp >> 13 )//First 3 bits for command type
2367 					{
2368 						case 0x0: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break;
2369 						case 0x1: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break;
2370 						case 0x2: nCommand = EnhancedCustomShapeSegmentCommand::MOVETO; if ( !nCnt ) nCnt = 1; break;
2371 						case 0x3: nCommand = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; nCnt = 0; break;
2372 						case 0x4: nCommand = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; nCnt = 0; break;
2373 						case 0x5:
2374 						case 0x6:
2375 						{
2376 							switch ( ( nTmp >> 8 ) & 0x1f )//5 bits next to command type is for path escape type
2377 							{
2378 								case 0x0:
2379 								{
2380 									//It is msopathEscapeExtension which is transformed into LINETO.
2381 									//If issue happens, I think this part can be comment so that it will be taken as unknow command.
2382 									//When export, origin data will be export without any change.
2383 									nCommand = EnhancedCustomShapeSegmentCommand::LINETO;
2384 									if ( !nCnt )
2385 										nCnt = 1;
2386 								}
2387 								break;
2388 								case 0x1:
2389 								{
2390 									nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
2391 									nCnt = ( nTmp & 0xff ) / 3;
2392 								}
2393 								break;
2394 								case 0x2:
2395 								{
2396 									nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
2397 									nCnt = ( nTmp & 0xff ) / 3;
2398 								}
2399 								break;
2400 								case 0x3:
2401 								{
2402 									nCommand = EnhancedCustomShapeSegmentCommand::ARCTO;
2403 									nCnt = ( nTmp & 0xff ) >> 2;
2404 								};
2405 								break;
2406 								case 0x4:
2407 								{
2408 									nCommand = EnhancedCustomShapeSegmentCommand::ARC;
2409 									nCnt = ( nTmp & 0xff ) >> 2;
2410 								}
2411 								break;
2412 								case 0x5:
2413 								{
2414 									nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
2415 									nCnt = ( nTmp & 0xff ) >> 2;
2416 								}
2417 								break;
2418 								case 0x6:
2419 								{
2420 									nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
2421 									nCnt = ( nTmp & 0xff ) >> 2;
2422 								}
2423 								break;
2424 								case 0x7:
2425 								{
2426 									nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
2427 									nCnt = nTmp & 0xff;
2428 								}
2429 								break;
2430 								case 0x8:
2431 								{
2432 									nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
2433 									nCnt = nTmp & 0xff;
2434 								}
2435 								break;
2436 								case 0xa: nCommand = EnhancedCustomShapeSegmentCommand::NOFILL; nCnt = 0; break;
2437 								case 0xb: nCommand = EnhancedCustomShapeSegmentCommand::NOSTROKE; nCnt = 0; break;
2438 							}
2439 						}
2440 						break;
2441 					}
2442 					// if the command is unknown, we will store all the data in nCnt, so it will be possible to export without loss
2443 					if ( nCommand == EnhancedCustomShapeSegmentCommand::UNKNOWN )
2444 						nCnt = (sal_Int16)nTmp;
2445 					aSegments[ i ].Command = nCommand;
2446 					aSegments[ i ].Count = nCnt;
2447 				}
2448 			}
2449 			const rtl::OUString	sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
2450 			aProp.Name = sSegments;
2451 			aProp.Value <<= aSegments;
2452 			aPathPropVec.push_back( aProp );
2453 		}
2454 		// Path/StretchX
2455 		if ( IsProperty( DFF_Prop_stretchPointX ) )
2456 		{
2457 			const rtl::OUString	sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
2458 			sal_Int32 nStretchX = GetPropertyValue( DFF_Prop_stretchPointX, 0 );
2459 			aProp.Name = sStretchX;
2460 			aProp.Value <<= nStretchX;
2461 			aPathPropVec.push_back( aProp );
2462 		}
2463 		// Path/StretchX
2464 		if ( IsProperty( DFF_Prop_stretchPointY ) )
2465 		{
2466 			const rtl::OUString	sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
2467 			sal_Int32 nStretchY = GetPropertyValue( DFF_Prop_stretchPointY, 0 );
2468 			aProp.Name = sStretchY;
2469 			aProp.Value <<= nStretchY;
2470 			aPathPropVec.push_back( aProp );
2471 		}
2472 		// Path/TextFrames
2473 		if ( IsProperty( DFF_Prop_textRectangles ) )
2474 		{
2475 			sal_uInt16 i;
2476 			sal_uInt16 nNumElem = 0;
2477 			sal_uInt16 nNumElemMem = 0;
2478 			sal_uInt16 nElemSize = 16;
2479 
2480 			if ( SeekToContent( DFF_Prop_textRectangles, rIn ) )
2481 				rIn >> nNumElem >> nNumElemMem >> nElemSize;
2482 			if ( nElemSize == 16 )
2483 			{
2484 				sal_Int32 nLeft, nTop, nRight, nBottom;
2485 				com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem );
2486 				for ( i = 0; i < nNumElem; i++ )
2487 				{
2488 					rIn >> nLeft
2489 						>> nTop
2490 						>> nRight
2491 						>> nBottom;
2492 
2493 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.First,	 nLeft );
2494 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.Second, nTop  );
2495 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.First,	 nRight );
2496 					EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.Second, nBottom);
2497 				}
2498 				const rtl::OUString	sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
2499 				aProp.Name = sTextFrames;
2500 				aProp.Value <<= aTextFrames;
2501 				aPathPropVec.push_back( aProp );
2502 			}
2503 		}
2504 		//Path/GluePoints
2505 		if ( IsProperty( DFF_Prop_connectorPoints ) )
2506 		{
2507 			com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
2508 
2509 			sal_uInt16 i;
2510 			sal_uInt16 nNumElemVert = 0;
2511 			sal_uInt16 nNumElemMemVert = 0;
2512 			sal_uInt16 nElemSizeVert = 8;
2513 
2514 			if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) )
2515 				rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
2516 
2517 			sal_Int32 nX, nY;
2518 			sal_Int16 nTmpA, nTmpB;
2519 			aGluePoints.realloc( nNumElemVert );
2520 			for ( i = 0; i < nNumElemVert; i++ )
2521 			{
2522 				if ( nElemSizeVert == 8 )
2523 				{
2524 					rIn >> nX
2525 						>> nY;
2526 				}
2527 				else
2528 				{
2529 					rIn >> nTmpA
2530 						>> nTmpB;
2531 
2532 					nX = nTmpA;
2533 					nY = nTmpB;
2534 				}
2535 				EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First,  nX );
2536 				EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY );
2537 			}
2538 			const rtl::OUString	sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
2539 			aProp.Name = sGluePoints;
2540 			aProp.Value <<= aGluePoints;
2541 			aPathPropVec.push_back( aProp );
2542 		}
2543 		if ( IsProperty( DFF_Prop_connectorType ) )
2544 		{
2545 			sal_Int16 nGluePointType = (sal_uInt16)GetPropertyValue( DFF_Prop_connectorType );
2546 			const rtl::OUString	sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
2547 			aProp.Name = sGluePointType;
2548 			aProp.Value <<= nGluePointType;
2549 			aPathPropVec.push_back( aProp );
2550 		}
2551 		// pushing the whole Path element
2552 		if ( aPathPropVec.size() )
2553 		{
2554 			const rtl::OUString	sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
2555 			PropSeq aPathPropSeq( aPathPropVec.size() );
2556 			aIter = aPathPropVec.begin();
2557 			aEnd = aPathPropVec.end();
2558 			beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
2559 			while ( aIter != aEnd )
2560 				*pPathValues++ = *aIter++;
2561 			aProp.Name = sPath;
2562 			aProp.Value <<= aPathPropSeq;
2563 			aPropVec.push_back( aProp );
2564 		}
2565 	}
2566 	/////////////////////////////////////////
2567 	// "TextPath" PropertySequence element //
2568 	/////////////////////////////////////////
2569 	sal_Bool bTextPathOn = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x4000 ) != 0;
2570 	if ( bTextPathOn )
2571 	{
2572 		PropVec aTextPathPropVec;
2573 
2574 		// TextPath
2575 		const rtl::OUString	sTextPathOn( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
2576 		aProp.Name = sTextPathOn;
2577 		aProp.Value <<= bTextPathOn;
2578 		aTextPathPropVec.push_back( aProp );
2579 
2580 		// TextPathMode
2581 		const rtl::OUString	sTextPathMode( RTL_CONSTASCII_USTRINGPARAM ( "TextPathMode" ) );
2582 		sal_Bool bTextPathFitPath = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x100 ) != 0;
2583 
2584 		sal_Bool bTextPathFitShape;
2585 		if ( IsHardAttribute( DFF_Prop_gtextFStretch ) )
2586 			bTextPathFitShape = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x400 ) != 0;
2587 		else
2588 		{
2589 			bTextPathFitShape = true;
2590 			switch( rObjData.eShapeType )
2591 			{
2592 				case mso_sptTextArchUpCurve :
2593 				case mso_sptTextArchDownCurve :
2594 				case mso_sptTextCircleCurve :
2595 				case mso_sptTextButtonCurve :
2596 					bTextPathFitShape = false;
2597 				default : break;
2598 			}
2599 		}
2600 		EnhancedCustomShapeTextPathMode eTextPathMode( EnhancedCustomShapeTextPathMode_NORMAL );
2601 		if ( bTextPathFitShape )
2602 			eTextPathMode = EnhancedCustomShapeTextPathMode_SHAPE;
2603 		else if ( bTextPathFitPath )
2604 			eTextPathMode = EnhancedCustomShapeTextPathMode_PATH;
2605 		aProp.Name = sTextPathMode;
2606 		aProp.Value <<= eTextPathMode;
2607 		aTextPathPropVec.push_back( aProp );
2608 
2609 		// ScaleX
2610 		const rtl::OUString	sTextPathScaleX( RTL_CONSTASCII_USTRINGPARAM ( "ScaleX" ) );
2611 		sal_Bool bTextPathScaleX = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x40 ) != 0;
2612 		aProp.Name = sTextPathScaleX;
2613 		aProp.Value <<= bTextPathScaleX;
2614 		aTextPathPropVec.push_back( aProp );
2615 		// SameLetterHeights
2616 		const rtl::OUString sSameLetterHeight( RTL_CONSTASCII_USTRINGPARAM ( "SameLetterHeights" ) );
2617 		sal_Bool bSameLetterHeight = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x80 ) != 0;
2618 		aProp.Name = sSameLetterHeight;
2619 		aProp.Value <<= bSameLetterHeight;
2620 		aTextPathPropVec.push_back( aProp );
2621 
2622 		// pushing the whole TextPath element
2623 		const rtl::OUString	sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
2624 		PropSeq aTextPathPropSeq( aTextPathPropVec.size() );
2625 		aIter = aTextPathPropVec.begin();
2626 		aEnd = aTextPathPropVec.end();
2627 		beans::PropertyValue* pTextPathValues = aTextPathPropSeq.getArray();
2628 		while ( aIter != aEnd )
2629 			*pTextPathValues++ = *aIter++;
2630 		aProp.Name = sTextPath;
2631 		aProp.Value <<= aTextPathPropSeq;
2632 		aPropVec.push_back( aProp );
2633 	}
2634 	////////////////////////
2635 	// "AdjustmentValues" // The AdjustmentValues are imported at last, because depending to the type of the
2636 	//////////////////////// handle (POLAR) we will convert the adjustment value from a fixed float to double
2637 
2638 	// checking the last used adjustment handle, so we can determine how many handles are to allocate
2639 	sal_Int32 i = DFF_Prop_adjust10Value;
2640 	while ( ( i >= DFF_Prop_adjustValue ) && !IsProperty( i ) )
2641 		i--;
2642 	sal_Int32 nAdjustmentValues = ( i - DFF_Prop_adjustValue ) + 1;
2643 	if ( nAdjustmentValues )
2644 	{
2645 		uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq( nAdjustmentValues );
2646 		while( --nAdjustmentValues >= 0 )
2647 		{
2648 			sal_Int32 nValue = 0;
2649 			beans::PropertyState ePropertyState = beans::PropertyState_DEFAULT_VALUE;
2650 			if ( IsProperty( i ) )
2651 			{
2652 				nValue = GetPropertyValue( i );
2653 				ePropertyState = beans::PropertyState_DIRECT_VALUE;
2654 			}
2655 			if ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << ( i - DFF_Prop_adjustValue ) ) )
2656 			{
2657 				double fValue = nValue;
2658 				fValue /= 65536;
2659 				aAdjustmentSeq[ nAdjustmentValues ].Value <<= fValue;
2660 			}
2661 			else
2662 				aAdjustmentSeq[ nAdjustmentValues ].Value <<= nValue;
2663 			aAdjustmentSeq[ nAdjustmentValues ].State = ePropertyState;
2664 			i--;
2665 		}
2666 		const rtl::OUString	sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
2667 		aProp.Name = sAdjustmentValues;
2668 		aProp.Value <<= aAdjustmentSeq;
2669 		aPropVec.push_back( aProp );
2670 	}
2671 
2672 	// creating the whole property set
2673 	PropSeq aSeq( aPropVec.size() );
2674 	beans::PropertyValue* pValues = aSeq.getArray();
2675 	aIter = aPropVec.begin();
2676 	aEnd = aPropVec.end();
2677 	while ( aIter != aEnd )
2678 		*pValues++ = *aIter++;
2679 	rSet.Put( SdrCustomShapeGeometryItem( aSeq ) );
2680 }
2681 
2682 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet ) const
2683 {
2684 	Rectangle aEmptyRect;
2685 	DffRecordHeader aHdTemp;
2686 	DffObjData aDffObjTemp( aHdTemp, aEmptyRect, 0 );
2687 	ApplyAttributes( rIn, rSet, aDffObjTemp );
2688 }
2689 
2690 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, DffObjData& rObjData ) const
2691 {
2692 	sal_Bool bHasShadow = sal_False;
2693 	if ( IsProperty( DFF_Prop_gtextSize ) )
2694 		rSet.Put( SvxFontHeightItem( rManager.ScalePt( GetPropertyValue( DFF_Prop_gtextSize ) ), 100, EE_CHAR_FONTHEIGHT ) );
2695 	sal_uInt32 nFontAttributes = GetPropertyValue( DFF_Prop_gtextFStrikethrough );
2696 	if ( nFontAttributes & 0x20 )
2697         rSet.Put( SvxWeightItem( nFontAttributes & 0x20 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
2698 	if ( nFontAttributes & 0x10 )
2699         rSet.Put( SvxPostureItem( nFontAttributes & 0x10 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
2700 	if ( nFontAttributes & 0x08 )
2701         rSet.Put( SvxUnderlineItem( nFontAttributes & 0x08 ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
2702 	if ( nFontAttributes & 0x40 )
2703         rSet.Put( SvxShadowedItem( nFontAttributes & 0x40 != 0, EE_CHAR_SHADOW ) );
2704 //	if ( nFontAttributes & 0x02 )
2705 //		rSet.Put( SvxCaseMapItem( nFontAttributes & 0x02 ? SVX_CASEMAP_KAPITAELCHEN : SVX_CASEMAP_NOT_MAPPED ) );
2706 	if ( nFontAttributes & 0x01 )
2707         rSet.Put( SvxCrossedOutItem( nFontAttributes & 0x01 ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) );
2708 	if ( IsProperty( DFF_Prop_fillColor ) )
2709 		rSet.Put( XFillColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor ) ) );
2710 	if ( IsProperty( DFF_Prop_shadowType ) )
2711 	{
2712 		MSO_ShadowType eShadowType = static_cast< MSO_ShadowType >( GetPropertyValue( DFF_Prop_shadowType ) );
2713 		if( eShadowType != mso_shadowOffset )
2714 		{
2715 			rSet.Put( SdrShadowXDistItem( 35 ) ); // 0,35 mm Schattendistanz
2716 			rSet.Put( SdrShadowYDistItem( 35 ) );
2717 		}
2718 	}
2719 	if ( IsProperty( DFF_Prop_shadowColor ) )
2720 		rSet.Put( SdrShadowColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_shadowColor ), DFF_Prop_shadowColor ) ) );
2721 	if ( IsProperty( DFF_Prop_shadowOpacity ) )
2722         rSet.Put( SdrShadowTransparenceItem( (sal_uInt16)( ( 0x10000 - GetPropertyValue( DFF_Prop_shadowOpacity ) ) / 655 ) ) );
2723 	if ( IsProperty( DFF_Prop_shadowOffsetX ) )
2724 	{
2725 		sal_Int32 nVal = static_cast< sal_Int32 >( GetPropertyValue( DFF_Prop_shadowOffsetX ) );
2726 		rManager.ScaleEmu( nVal );
2727 		rSet.Put( SdrShadowXDistItem( nVal ) );
2728 	}
2729 	if ( IsProperty( DFF_Prop_shadowOffsetY ) )
2730 	{
2731 		sal_Int32 nVal = static_cast< sal_Int32 >( GetPropertyValue( DFF_Prop_shadowOffsetY ) );
2732 		rManager.ScaleEmu( nVal );
2733 		rSet.Put( SdrShadowYDistItem( nVal ) );
2734 	}
2735 	if ( IsProperty( DFF_Prop_fshadowObscured ) )
2736 	{
2737         bHasShadow = ( GetPropertyValue( DFF_Prop_fshadowObscured ) & 2 ) != 0;
2738 		if ( bHasShadow )
2739         {
2740 			if ( !IsProperty( DFF_Prop_shadowOffsetX ) )
2741 				rSet.Put( SdrShadowXDistItem( 35 ) );
2742 			if ( !IsProperty( DFF_Prop_shadowOffsetY ) )
2743 				rSet.Put( SdrShadowYDistItem( 35 ) );
2744 		}
2745 	}
2746 	if ( bHasShadow )
2747 	{
2748 		// #160376# sj: activating shadow only if fill and or linestyle is used
2749 		// this is required because of the latest drawing layer core changes.
2750 		// Issue i104085 is related to this.
2751 		sal_uInt32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
2752 		if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( rObjData.eShapeType ))
2753 			nLineFlags &= ~0x08;
2754 		sal_uInt32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
2755 		if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType ))
2756 			nFillFlags &= ~0x10;
2757 		if ( nFillFlags & 0x10 )
2758 		{
2759 			MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
2760 			switch( eMSO_FillType )
2761 			{
2762 				case mso_fillSolid :
2763 				case mso_fillPattern :
2764 				case mso_fillTexture :
2765 				case mso_fillPicture :
2766 				case mso_fillShade :
2767 				case mso_fillShadeCenter :
2768 				case mso_fillShadeShape :
2769 				case mso_fillShadeScale :
2770 				case mso_fillShadeTitle :
2771 				break;
2772 				// case mso_fillBackground :
2773 				default:
2774 					nFillFlags &=~0x10;			// no fillstyle used
2775 				break;
2776 			}
2777 		}
2778 		if ( ( ( nLineFlags & 0x08 ) == 0 ) && ( ( nFillFlags & 0x10 ) == 0 ) )	// if there is no fillstyle and linestyle
2779 			bHasShadow = sal_False;												// we are turning shadow off.
2780 
2781 		if ( bHasShadow )
2782 			rSet.Put( SdrShadowItem( bHasShadow ) );
2783 	}
2784 	ApplyLineAttributes( rSet, rObjData.eShapeType ); // #i28269#
2785 	ApplyFillAttributes( rIn, rSet, rObjData );
2786 	if ( rObjData.eShapeType != mso_sptNil || IsProperty( DFF_Prop_pVertices ) )
2787 	{
2788 		ApplyCustomShapeGeometryAttributes( rIn, rSet, rObjData );
2789 		ApplyCustomShapeTextAttributes( rSet );
2790 		if ( rManager.GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_EXCEL )
2791 		{
2792 			if ( mnFix16Angle || ( rObjData.nSpFlags & SP_FFLIPV ) )
2793 				CheckAndCorrectExcelTextRotation( rIn, rSet, rObjData );
2794 		}
2795 	}
2796 }
2797 
2798 void DffPropertyReader::CheckAndCorrectExcelTextRotation( SvStream& rIn, SfxItemSet& rSet, DffObjData& rObjData ) const
2799 {
2800 	sal_Bool bRotateTextWithShape = rObjData.bRotateTextWithShape;
2801 	if ( rObjData.bOpt2 )		// sj: #158494# is the second property set available ? if then we have to check the xml data of
2802 	{							// the shape, because the textrotation of Excel 2003 and greater versions is stored there
2803 								// (upright property of the textbox)
2804 		if ( rManager.pSecPropSet->SeekToContent( DFF_Prop_metroBlob, rIn ) )
2805 		{
2806 			sal_uInt32 nLen = rManager.pSecPropSet->GetPropertyValue( DFF_Prop_metroBlob );
2807 			if ( nLen )
2808 			{
2809 				::com::sun::star::uno::Sequence< sal_Int8 > aXMLDataSeq( nLen );
2810 				rIn.Read( aXMLDataSeq.getArray(), nLen );
2811 				::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xInputStream
2812 					( new ::comphelper::SequenceInputStream( aXMLDataSeq ) );
2813 				try
2814 				{
2815 					::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory() );
2816 					if ( xFactory.is() )
2817 					{
2818 						::com::sun::star::uno::Reference< com::sun::star::embed::XStorage > xStorage
2819 							( ::comphelper::OStorageHelper::GetStorageOfFormatFromInputStream(
2820 								OFOPXML_STORAGE_FORMAT_STRING, xInputStream, xFactory, sal_True ) );
2821 						if ( xStorage.is() )
2822 						{
2823 							const rtl::OUString sDRS( RTL_CONSTASCII_USTRINGPARAM ( "drs" ) );
2824 							::com::sun::star::uno::Reference< ::com::sun::star::embed::XStorage >
2825 								xStorageDRS( xStorage->openStorageElement( sDRS, ::com::sun::star::embed::ElementModes::SEEKABLEREAD ) );
2826 							if ( xStorageDRS.is() )
2827 							{
2828 								const rtl::OUString sShapeXML( RTL_CONSTASCII_USTRINGPARAM ( "shapexml.xml" ) );
2829 								::com::sun::star::uno::Reference< ::com::sun::star::io::XStream > xShapeXMLStream( xStorageDRS->openStreamElement( sShapeXML, ::com::sun::star::embed::ElementModes::SEEKABLEREAD ) );
2830 								if ( xShapeXMLStream.is() )
2831 								{
2832 									::com::sun::star::uno::Reference< ::com::sun::star::io::XInputStream > xShapeXMLInputStream( xShapeXMLStream->getInputStream() );
2833 									if ( xShapeXMLInputStream.is() )
2834 									{
2835 										::com::sun::star::uno::Sequence< sal_Int8 > aSeq;
2836 										sal_Int32 nBytesRead = xShapeXMLInputStream->readBytes( aSeq, 0x7fffffff );
2837 										if ( nBytesRead )
2838 										{	// for only one property I spare to use a XML parser at this point, this
2839 											// should be enhanced if needed
2840 
2841 											bRotateTextWithShape = sal_True;	// using the correct xml default
2842 											const char* pArry = reinterpret_cast< char* >( aSeq.getArray() );
2843 											const char* pUpright = "upright=";
2844 											const char* pEnd = pArry + nBytesRead;
2845 											const char* pPtr = pArry;
2846 											while( ( pPtr + 12 ) < pEnd )
2847 											{
2848 												if ( !memcmp( pUpright, pPtr, 8 ) )
2849 												{
2850 													bRotateTextWithShape = ( pPtr[ 9 ] != '1' ) && ( pPtr[ 9 ] != 't' );
2851 													break;
2852 												}
2853 												else
2854 													pPtr++;
2855 											}
2856 										}
2857 									}
2858 								}
2859 							}
2860 						}
2861 					}
2862 				}
2863 				catch( com::sun::star::uno::Exception& )
2864 				{
2865 				}
2866 			}
2867 		}
2868 	}
2869 	if ( !bRotateTextWithShape )
2870 	{
2871 		const com::sun::star::uno::Any* pAny, aAny;
2872 		SdrCustomShapeGeometryItem aGeometryItem((SdrCustomShapeGeometryItem&)rSet.Get( SDRATTR_CUSTOMSHAPE_GEOMETRY ));
2873 		const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
2874 		pAny = aGeometryItem.GetPropertyValueByName( sTextRotateAngle );
2875 		double fExtraTextRotateAngle = 0.0;
2876 		if ( pAny )
2877 			*pAny >>= fExtraTextRotateAngle;
2878 
2879 		if ( rManager.mnFix16Angle )
2880 			fExtraTextRotateAngle += mnFix16Angle / 100.0;
2881 		if ( rObjData.nSpFlags & SP_FFLIPV )
2882 			fExtraTextRotateAngle -= 180.0;
2883 
2884 		com::sun::star::beans::PropertyValue aTextRotateAngle;
2885 		aTextRotateAngle.Name = sTextRotateAngle;
2886 		aTextRotateAngle.Value <<= fExtraTextRotateAngle;
2887 		aGeometryItem.SetPropertyValue( aTextRotateAngle );
2888 		rSet.Put( aGeometryItem );
2889 	}
2890 }
2891 
2892 //---------------------------------------------------------------------------
2893 //- Record Manager ----------------------------------------------------------
2894 //---------------------------------------------------------------------------
2895 
2896 DffRecordList::DffRecordList( DffRecordList* pList ) :
2897 	nCount					( 0 ),
2898 	nCurrent				( 0 ),
2899 	pPrev					( pList ),
2900 	pNext					( NULL )
2901 {
2902 	if ( pList )
2903 		pList->pNext = this;
2904 }
2905 
2906 DffRecordList::~DffRecordList()
2907 {
2908 	delete pNext;
2909 }
2910 
2911 DffRecordManager::DffRecordManager() :
2912 	DffRecordList	( NULL ),
2913 	pCList			( (DffRecordList*)this )
2914 {
2915 }
2916 
2917 DffRecordManager::DffRecordManager( SvStream& rIn ) :
2918 	DffRecordList	( NULL ),
2919 	pCList			( (DffRecordList*)this )
2920 {
2921 	Consume( rIn );
2922 }
2923 
2924 DffRecordManager::~DffRecordManager()
2925 {
2926 };
2927 
2928 
2929 void DffRecordManager::Consume( SvStream& rIn, sal_Bool bAppend, sal_uInt32 nStOfs )
2930 {
2931 	if ( !bAppend )
2932 		Clear();
2933 	sal_uInt32 nOldPos = rIn.Tell();
2934 	if ( !nStOfs )
2935 	{
2936 		DffRecordHeader aHd;
2937 		rIn >> aHd;
2938 		if ( aHd.nRecVer == DFF_PSFLAG_CONTAINER )
2939 			nStOfs = aHd.GetRecEndFilePos();
2940 	}
2941 	if ( nStOfs )
2942 	{
2943 		pCList = (DffRecordList*)this;
2944 		while ( pCList->pNext )
2945 			pCList = pCList->pNext;
2946 		while ( ( rIn.GetError() == 0 ) && ( ( rIn.Tell() + 8 ) <=  nStOfs ) )
2947 		{
2948 			if ( pCList->nCount == DFF_RECORD_MANAGER_BUF_SIZE )
2949 				pCList = new DffRecordList( pCList );
2950 			rIn >> pCList->mHd[ pCList->nCount ];
2951 			pCList->mHd[ pCList->nCount++ ].SeekToEndOfRecord( rIn );
2952 		}
2953 		rIn.Seek( nOldPos );
2954 	}
2955 }
2956 
2957 void DffRecordManager::Clear()
2958 {
2959 	pCList = (DffRecordList*)this;
2960 	delete pNext, pNext = NULL;
2961 	nCurrent = 0;
2962 	nCount = 0;
2963 }
2964 
2965 DffRecordHeader* DffRecordManager::Current()
2966 {
2967 	DffRecordHeader* pRet = NULL;
2968 	if ( pCList->nCurrent < pCList->nCount )
2969 		pRet = &pCList->mHd[ pCList->nCurrent ];
2970 	return pRet;
2971 }
2972 
2973 DffRecordHeader* DffRecordManager::First()
2974 {
2975 	DffRecordHeader* pRet = NULL;
2976 	pCList = (DffRecordList*)this;
2977 	if ( pCList->nCount )
2978 	{
2979 		pCList->nCurrent = 0;
2980 		pRet = &pCList->mHd[ 0 ];
2981 	}
2982 	return pRet;
2983 }
2984 
2985 DffRecordHeader* DffRecordManager::Next()
2986 {
2987 	DffRecordHeader* pRet = NULL;
2988 	sal_uInt32 nC = pCList->nCurrent + 1;
2989 	if ( nC < pCList->nCount )
2990 	{
2991 		pCList->nCurrent++;
2992 		pRet = &pCList->mHd[ nC ];
2993 	}
2994 	else if ( pCList->pNext )
2995 	{
2996 		pCList = pCList->pNext;
2997 		pCList->nCurrent = 0;
2998 		pRet = &pCList->mHd[ 0 ];
2999 	}
3000 	return pRet;
3001 }
3002 
3003 DffRecordHeader* DffRecordManager::Prev()
3004 {
3005 	DffRecordHeader* pRet = NULL;
3006 	sal_uInt32 nCur = pCList->nCurrent;
3007 	if ( !nCur && pCList->pPrev )
3008 	{
3009 		pCList = pCList->pPrev;
3010 		nCur = pCList->nCount;
3011 	}
3012 	if ( nCur-- )
3013 	{
3014 		pCList->nCurrent = nCur;
3015 		pRet = &pCList->mHd[ nCur ];
3016 	}
3017 	return pRet;
3018 }
3019 
3020 DffRecordHeader* DffRecordManager::Last()
3021 {
3022 	DffRecordHeader* pRet = NULL;
3023 	while ( pCList->pNext )
3024 		pCList = pCList->pNext;
3025 	sal_uInt32 nCnt = pCList->nCount;
3026 	if ( nCnt-- )
3027 	{
3028 		pCList->nCurrent = nCnt;
3029 		pRet = &pCList->mHd[ nCnt ];
3030 	}
3031 	return pRet;
3032 }
3033 
3034 sal_Bool DffRecordManager::SeekToContent( SvStream& rIn, sal_uInt16 nRecId, DffSeekToContentMode eMode )
3035 {
3036 	DffRecordHeader* pHd = GetRecordHeader( nRecId, eMode );
3037 	if ( pHd )
3038 	{
3039 		pHd->SeekToContent( rIn );
3040 		return sal_True;
3041 	}
3042 	else
3043 		return sal_False;
3044 }
3045 
3046 DffRecordHeader* DffRecordManager::GetRecordHeader( sal_uInt16 nRecId, DffSeekToContentMode eMode )
3047 {
3048 	sal_uInt32 nOldCurrent = pCList->nCurrent;
3049 	DffRecordList* pOldList = pCList;
3050 	DffRecordHeader* pHd;
3051 
3052 	if ( eMode == SEEK_FROM_BEGINNING )
3053 		pHd = First();
3054 	else
3055 		pHd = Next();
3056 
3057 	while ( pHd )
3058 	{
3059 		if ( pHd->nRecType == nRecId )
3060 			break;
3061 		pHd = Next();
3062 	}
3063 	if ( !pHd && eMode == SEEK_FROM_CURRENT_AND_RESTART )
3064 	{
3065 		DffRecordHeader* pBreak = &pOldList->mHd[ nOldCurrent ];
3066 		pHd = First();
3067 		if ( pHd )
3068 		{
3069 			while ( pHd != pBreak )
3070 			{
3071 				if ( pHd->nRecType == nRecId )
3072 					break;
3073 				pHd = Next();
3074 			}
3075 			if ( pHd->nRecType != nRecId )
3076 				pHd = NULL;
3077 		}
3078 	}
3079 	if ( !pHd )
3080 	{
3081 		pCList = pOldList;
3082 		pOldList->nCurrent = nOldCurrent;
3083 	}
3084 	return pHd;
3085 }
3086 
3087 //---------------------------------------------------------------------------
3088 //  private Methoden
3089 //---------------------------------------------------------------------------
3090 
3091 struct EscherBlipCacheEntry
3092 {
3093 	ByteString	aUniqueID;
3094     sal_uInt32  nBlip;
3095 
3096     EscherBlipCacheEntry( sal_uInt32 nBlipId, const ByteString& rUniqueID ) :
3097 		aUniqueID( rUniqueID ),
3098 		nBlip( nBlipId ) {}
3099 };
3100 
3101 void SvxMSDffManager::Scale( sal_Int32& rVal ) const
3102 {
3103 	if ( bNeedMap )
3104 		rVal = BigMulDiv( rVal, nMapMul, nMapDiv );
3105 }
3106 
3107 void SvxMSDffManager::Scale( Point& rPos ) const
3108 {
3109 	rPos.X() += nMapXOfs;
3110 	rPos.Y() += nMapYOfs;
3111 	if ( bNeedMap )
3112 	{
3113 		rPos.X() = BigMulDiv( rPos.X(), nMapMul, nMapDiv );
3114 		rPos.Y() = BigMulDiv( rPos.Y(), nMapMul, nMapDiv );
3115 	}
3116 }
3117 
3118 void SvxMSDffManager::Scale( Size& rSiz ) const
3119 {
3120 	if ( bNeedMap )
3121 	{
3122 		rSiz.Width() = BigMulDiv( rSiz.Width(), nMapMul, nMapDiv );
3123 		rSiz.Height() = BigMulDiv( rSiz.Height(), nMapMul, nMapDiv );
3124 	}
3125 }
3126 
3127 void SvxMSDffManager::Scale( Rectangle& rRect ) const
3128 {
3129 	rRect.Move( nMapXOfs, nMapYOfs );
3130 	if ( bNeedMap )
3131 	{
3132 		rRect.Left()  =BigMulDiv( rRect.Left()  , nMapMul, nMapDiv );
3133 		rRect.Top()   =BigMulDiv( rRect.Top()   , nMapMul, nMapDiv );
3134 		rRect.Right() =BigMulDiv( rRect.Right() , nMapMul, nMapDiv );
3135 		rRect.Bottom()=BigMulDiv( rRect.Bottom(), nMapMul, nMapDiv );
3136 	}
3137 }
3138 
3139 void SvxMSDffManager::Scale( Polygon& rPoly ) const
3140 {
3141 	if ( !bNeedMap )
3142 		return;
3143 	sal_uInt16 nPointAnz = rPoly.GetSize();
3144 	for ( sal_uInt16 nPointNum = 0; nPointNum < nPointAnz; nPointNum++ )
3145 		Scale( rPoly[ nPointNum ] );
3146 }
3147 
3148 void SvxMSDffManager::Scale( PolyPolygon& rPoly ) const
3149 {
3150 	if ( !bNeedMap )
3151 		return;
3152 	sal_uInt16 nPolyAnz = rPoly.Count();
3153 	for ( sal_uInt16 nPolyNum = 0; nPolyNum < nPolyAnz; nPolyNum++ )
3154 		Scale( rPoly[ nPolyNum ] );
3155 }
3156 
3157 void SvxMSDffManager::ScaleEmu( sal_Int32& rVal ) const
3158 {
3159 	rVal = BigMulDiv( rVal, nEmuMul, nEmuDiv );
3160 }
3161 
3162 sal_uInt32 SvxMSDffManager::ScalePt( sal_uInt32 nVal ) const
3163 {
3164 	MapUnit eMap = pSdrModel->GetScaleUnit();
3165 	Fraction aFact( GetMapFactor( MAP_POINT, eMap ).X() );
3166 	long aMul = aFact.GetNumerator();
3167 	long aDiv = aFact.GetDenominator() * 65536;
3168 	aFact = Fraction( aMul, aDiv ); // nochmal versuchen zu kuerzen
3169 	return BigMulDiv( nVal, aFact.GetNumerator(), aFact.GetDenominator() );
3170 }
3171 
3172 sal_Int32 SvxMSDffManager::ScalePoint( sal_Int32 nVal ) const
3173 {
3174 	return BigMulDiv( nVal, nPntMul, nPntDiv );
3175 };
3176 
3177 void SvxMSDffManager::SetModel(SdrModel* pModel, long nApplicationScale)
3178 {
3179 	pSdrModel = pModel;
3180 	if( pModel && (0 < nApplicationScale) )
3181 	{
3182 		// PPT arbeitet nur mit Einheiten zu 576DPI
3183 		// WW hingegen verwendet twips, dh. 1440DPI.
3184 		MapUnit eMap = pSdrModel->GetScaleUnit();
3185 		Fraction aFact( GetMapFactor(MAP_INCH, eMap).X() );
3186 		long nMul=aFact.GetNumerator();
3187 		long nDiv=aFact.GetDenominator()*nApplicationScale;
3188 		aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3189 		// Bei 100TH_MM -> 2540/576=635/144
3190 		// Bei Twip     -> 1440/576=5/2
3191 		nMapMul  = aFact.GetNumerator();
3192 		nMapDiv  = aFact.GetDenominator();
3193 		bNeedMap = nMapMul!=nMapDiv;
3194 
3195 		// MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
3196 		// 1mm=36000emu, 1twip=635emu
3197 		aFact=GetMapFactor(MAP_100TH_MM,eMap).X();
3198 		nMul=aFact.GetNumerator();
3199 		nDiv=aFact.GetDenominator()*360;
3200 		aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3201 		// Bei 100TH_MM ->                            1/360
3202 		// Bei Twip     -> 14,40/(25,4*360)=144/91440=1/635
3203 		nEmuMul=aFact.GetNumerator();
3204 		nEmuDiv=aFact.GetDenominator();
3205 
3206 		// Und noch was fuer typografische Points
3207 		aFact=GetMapFactor(MAP_POINT,eMap).X();
3208 		nPntMul=aFact.GetNumerator();
3209 		nPntDiv=aFact.GetDenominator();
3210 	}
3211 	else
3212 	{
3213 		pModel = 0;
3214 		nMapMul = nMapDiv = nMapXOfs = nMapYOfs = nEmuMul = nEmuDiv = nPntMul = nPntDiv = 0;
3215 		bNeedMap = sal_False;
3216 	}
3217 }
3218 
3219 sal_Bool SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, sal_uInt32 nId ) const
3220 {
3221 	sal_Bool bRet = sal_False;
3222 	if ( mpFidcls )
3223 	{
3224 		sal_uInt32 nMerk = rSt.Tell();
3225 		sal_uInt32 nShapeId, nSec = ( nId >> 10 ) - 1;
3226 		if ( nSec < mnIdClusters )
3227 		{
3228 			sal_IntPtr nOfs = (sal_IntPtr)maDgOffsetTable.Get( mpFidcls[ nSec ].dgid );
3229 			if ( nOfs )
3230 			{
3231 				rSt.Seek( nOfs );
3232 				DffRecordHeader aEscherF002Hd;
3233 				rSt >> aEscherF002Hd;
3234 				sal_uLong nEscherF002End = aEscherF002Hd.GetRecEndFilePos();
3235 				DffRecordHeader aEscherObjListHd;
3236 				while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < nEscherF002End ) )
3237 				{
3238 					rSt >> aEscherObjListHd;
3239 					if ( aEscherObjListHd.nRecVer != 0xf )
3240 						aEscherObjListHd.SeekToEndOfRecord( rSt );
3241 					else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer )
3242 					{
3243 						DffRecordHeader aShapeHd;
3244 						if ( SeekToRec( rSt, DFF_msofbtSp, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) )
3245 						{
3246 							rSt >> nShapeId;
3247 							if ( nId == nShapeId )
3248 							{
3249 								aEscherObjListHd.SeekToBegOfRecord( rSt );
3250 								bRet = sal_True;
3251 								break;
3252 							}
3253 						}
3254 						aEscherObjListHd.SeekToEndOfRecord( rSt );
3255 					}
3256 				}
3257 			}
3258 		}
3259 		if ( !bRet )
3260 			rSt.Seek( nMerk );
3261 	}
3262 	return bRet;
3263 }
3264 
3265 FASTBOOL SvxMSDffManager::SeekToRec( SvStream& rSt, sal_uInt16 nRecId, sal_uLong nMaxFilePos, DffRecordHeader* pRecHd, sal_uLong nSkipCount ) const
3266 {
3267 	FASTBOOL bRet = sal_False;
3268 	sal_uLong nFPosMerk = rSt.Tell(); // store FilePos to restore it later if necessary
3269 	DffRecordHeader aHd;
3270 	do
3271 	{
3272 		rSt >> aHd;
3273 
3274         // check potential error reading and if seeking to the end of record is possible at all.
3275         // It is probably cheaper instead of doing the file seek operation
3276         if ( rSt.GetError() || ( aHd.GetRecEndFilePos() >  nMaxFilePos ) )
3277         {
3278             bRet= sal_False;
3279             break;
3280         }
3281 
3282 		if ( aHd.nRecType == nRecId )
3283 		{
3284 			if ( nSkipCount )
3285 				nSkipCount--;
3286 			else
3287 			{
3288 				bRet = sal_True;
3289 				if ( pRecHd != NULL )
3290 					*pRecHd = aHd;
3291 				else
3292 					aHd.SeekToBegOfRecord( rSt );
3293 			}
3294 		}
3295 		if ( !bRet )
3296 			aHd.SeekToEndOfRecord( rSt );
3297 	}
3298 	while ( rSt.GetError() == 0 && rSt.Tell() < nMaxFilePos && !bRet );
3299 	if ( !bRet )
3300 		rSt.Seek( nFPosMerk );	// restore orginal FilePos
3301 	return bRet;
3302 }
3303 
3304 FASTBOOL SvxMSDffManager::SeekToRec2( sal_uInt16 nRecId1, sal_uInt16 nRecId2, sal_uLong nMaxFilePos, DffRecordHeader* pRecHd, sal_uLong nSkipCount ) const
3305 {
3306 	FASTBOOL bRet = sal_False;
3307 	sal_uLong nFPosMerk = rStCtrl.Tell();	// FilePos merken fuer ggf. spaetere Restauration
3308 	DffRecordHeader aHd;
3309 	do
3310 	{
3311 		rStCtrl >> aHd;
3312 		if ( aHd.nRecType == nRecId1 || aHd.nRecType == nRecId2 )
3313 		{
3314 			if ( nSkipCount )
3315 				nSkipCount--;
3316 			else
3317 			{
3318 				bRet = sal_True;
3319 				if ( pRecHd )
3320 					*pRecHd = aHd;
3321 				else
3322 					aHd.SeekToBegOfRecord( rStCtrl );
3323 			}
3324 		}
3325 		if ( !bRet )
3326 			aHd.SeekToEndOfRecord( rStCtrl );
3327 	}
3328 	while ( rStCtrl.GetError() == 0 && rStCtrl.Tell() < nMaxFilePos && !bRet );
3329 	if ( !bRet )
3330 		rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
3331 	return bRet;
3332 }
3333 
3334 
3335 FASTBOOL SvxMSDffManager::GetColorFromPalette( sal_uInt16 /* nNum */, Color& rColor ) const
3336 {
3337 	// diese Methode ist in der zum Excel-Import
3338 	// abgeleiteten Klasse zu ueberschreiben...
3339 	rColor.SetColor( COL_WHITE );
3340 	return sal_True;
3341 }
3342 
3343 // sj: the documentation is not complete, especially in ppt the normal rgb for text
3344 // color is written as 0xfeRRGGBB, this can't be explained by the documentation, nearly
3345 // every bit in the upper code is set -> so there seems to be a special handling for
3346 // ppt text colors, i decided not to fix this in MSO_CLR_ToColor because of possible
3347 // side effects, instead MSO_TEXT_CLR_ToColor is called for PPT text colors, to map
3348 // the color code to something that behaves like the other standard color codes used by
3349 // fill and line color
3350 Color SvxMSDffManager::MSO_TEXT_CLR_ToColor( sal_uInt32 nColorCode ) const
3351 {
3352 	// Fuer Textfarben: Header ist 0xfeRRGGBB
3353 	if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 )
3354 		nColorCode &= 0x00ffffff;
3355 	else
3356 	{
3357 		// for colorscheme colors the color index are the lower three bits of the upper byte
3358 		if ( ( nColorCode & 0xf8000000 ) == 0 ) // this must be a colorscheme index
3359 		{
3360 			nColorCode >>= 24;
3361 			nColorCode |= 0x8000000;
3362 		}
3363 	}
3364 	return MSO_CLR_ToColor( nColorCode );
3365 }
3366 
3367 Color SvxMSDffManager::MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContentProperty ) const
3368 {
3369 	Color aColor( mnDefaultColor );
3370 
3371 	// Fuer Textfarben: Header ist 0xfeRRGGBB
3372 	if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 )	// sj: it needs to be checked if 0xfe is used in
3373 		nColorCode &= 0x00ffffff;						// other cases than ppt text -> if not this code can be removed
3374 
3375 	sal_uInt8 nUpper = (sal_uInt8)( nColorCode >> 24 );
3376 
3377 	// sj: below change from 0x1b to 0x19 was done because of i84812 (0x02 -> rgb color),
3378 	// now I have some problems to fix i104685 (there the color value is 0x02000000 whichs requires
3379 	// a 0x2 scheme color to be displayed properly), the color docu seems to be incomplete
3380 	if( nUpper & 0x19 )      // if( nUpper & 0x1f )
3381 	{
3382 		if( ( nUpper & 0x08 ) || ( ( nUpper & 0x10 ) == 0 ) )
3383 		{
3384 			// SCHEMECOLOR
3385 			if ( !GetColorFromPalette( ( nUpper & 8 ) ? (sal_uInt16)nColorCode : nUpper, aColor ) )
3386 			{
3387 				switch( nContentProperty )
3388 				{
3389 					case DFF_Prop_pictureTransparent :
3390 					case DFF_Prop_shadowColor :
3391 					case DFF_Prop_fillBackColor :
3392 					case DFF_Prop_fillColor :
3393 						aColor = Color( COL_WHITE );
3394 					break;
3395 					case DFF_Prop_lineColor :
3396 					{
3397 						aColor = Color( COL_BLACK );
3398 					}
3399 					break;
3400 				}
3401 			}
3402 		}
3403 		else	// SYSCOLOR
3404 		{
3405 			const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
3406 
3407 //			sal_uInt16 nParameter = (sal_uInt8)( nColorCode >> 16);					// SJ: nice compiler optimization bug on windows, though downcasting
3408 			sal_uInt16 nParameter = sal_uInt16(( nColorCode >> 16 ) & 0x00ff);	// the HiByte of nParameter is not zero, an exclusive AND is helping :o
3409 			sal_uInt16 nFunctionBits = (sal_uInt16)( ( nColorCode & 0x00000f00 ) >> 8 );
3410 			sal_uInt16 nAdditionalFlags = (sal_uInt16)( ( nColorCode & 0x0000f000) >> 8 );
3411 			sal_uInt16 nColorIndex = sal_uInt16(nColorCode & 0x00ff);
3412 			sal_uInt32 nPropColor = 0;
3413 
3414 			sal_uInt16	nCProp = 0;
3415 
3416 			switch ( nColorIndex )
3417 			{
3418 				case mso_syscolorButtonFace :			aColor = rStyleSettings.GetFaceColor(); break;
3419 				case mso_syscolorWindowText :			aColor = rStyleSettings.GetWindowTextColor(); break;
3420 				case mso_syscolorMenu :					aColor = rStyleSettings.GetMenuColor(); break;
3421 				case mso_syscolor3DLight :
3422 				case mso_syscolorButtonHighlight :
3423 				case mso_syscolorHighlight :			aColor = rStyleSettings.GetHighlightColor(); break;
3424 				case mso_syscolorHighlightText :		aColor = rStyleSettings.GetHighlightTextColor(); break;
3425 				case mso_syscolorCaptionText :			aColor = rStyleSettings.GetMenuTextColor(); break;
3426 				case mso_syscolorActiveCaption :		aColor = rStyleSettings.GetHighlightColor(); break;
3427 				case mso_syscolorButtonShadow :			aColor = rStyleSettings.GetShadowColor(); break;
3428 				case mso_syscolorButtonText :			aColor = rStyleSettings.GetButtonTextColor(); break;
3429 				case mso_syscolorGrayText :				aColor = rStyleSettings.GetDeactiveColor(); break;
3430 				case mso_syscolorInactiveCaption :		aColor = rStyleSettings.GetDeactiveColor(); break;
3431 				case mso_syscolorInactiveCaptionText :	aColor = rStyleSettings.GetDeactiveColor(); break;
3432 				case mso_syscolorInfoBackground :		aColor = rStyleSettings.GetFaceColor(); break;
3433 				case mso_syscolorInfoText :				aColor = rStyleSettings.GetInfoTextColor(); break;
3434 				case mso_syscolorMenuText :				aColor = rStyleSettings.GetMenuTextColor(); break;
3435 				case mso_syscolorScrollbar :			aColor = rStyleSettings.GetFaceColor(); break;
3436 				case mso_syscolorWindow :				aColor = rStyleSettings.GetWindowColor(); break;
3437 				case mso_syscolorWindowFrame :			aColor = rStyleSettings.GetWindowColor(); break;
3438 
3439 				case mso_colorFillColor :
3440 				{
3441 					nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3442 					nCProp = DFF_Prop_fillColor;
3443 				}
3444 				break;
3445 				case mso_colorLineOrFillColor :		// ( use the line color only if there is a line )
3446 				{
3447 					if ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 )
3448 					{
3449 						nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3450 						nCProp = DFF_Prop_lineColor;
3451 					}
3452 					else
3453 					{
3454 						nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3455 						nCProp = DFF_Prop_fillColor;
3456 					}
3457 				}
3458 				break;
3459 				case mso_colorLineColor :
3460 				{
3461 					nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3462 					nCProp = DFF_Prop_lineColor;
3463 				}
3464 				break;
3465 				case mso_colorShadowColor :
3466 				{
3467 					nPropColor = GetPropertyValue( DFF_Prop_shadowColor, 0x808080 );
3468 					nCProp = DFF_Prop_shadowColor;
3469 				}
3470 				break;
3471 				case mso_colorThis :				// ( use this color ... )
3472 				{
3473 					nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );	//?????????????
3474 					nCProp = DFF_Prop_fillColor;
3475 				}
3476 				break;
3477 				case mso_colorFillBackColor :
3478 				{
3479 					nPropColor = GetPropertyValue( DFF_Prop_fillBackColor, 0xffffff );
3480 					nCProp = DFF_Prop_fillBackColor;
3481 				}
3482 				break;
3483 				case mso_colorLineBackColor :
3484 				{
3485 					nPropColor = GetPropertyValue( DFF_Prop_lineBackColor, 0xffffff );
3486 					nCProp = DFF_Prop_lineBackColor;
3487 				}
3488 				break;
3489 				case mso_colorFillThenLine :		// ( use the fillcolor unless no fill and line )
3490 				{
3491 					nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );	//?????????????
3492 					nCProp = DFF_Prop_fillColor;
3493 				}
3494 				break;
3495 				case mso_colorIndexMask :			// ( extract the color index ) ?
3496 				{
3497 					nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );	//?????????????
3498 					nCProp = DFF_Prop_fillColor;
3499 				}
3500 				break;
3501 			}
3502 			if ( nCProp && ( nPropColor & 0x10000000 ) == 0 )		// beware of looping recursive
3503 				aColor = MSO_CLR_ToColor( nPropColor, nCProp );
3504 
3505 			if( nAdditionalFlags & 0x80 )			// make color gray
3506 			{
3507 				sal_uInt8 nZwi = aColor.GetLuminance();
3508 				aColor = Color( nZwi, nZwi, nZwi );
3509 			}
3510 			switch( nFunctionBits )
3511 			{
3512 				case 0x01 :		// darken color by parameter
3513 				{
3514 					aColor.SetRed( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetRed() ) >> 8 ) );
3515 					aColor.SetGreen( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetGreen() ) >> 8 ) );
3516 					aColor.SetBlue( sal::static_int_cast< sal_uInt8 >( ( nParameter * aColor.GetBlue() ) >> 8 ) );
3517 				}
3518 				break;
3519 				case 0x02 :		// lighten color by parameter
3520 				{
3521 					sal_uInt16 nInvParameter = ( 0x00ff - nParameter ) * 0xff;
3522 					aColor.SetRed( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetRed() ) ) >> 8 ) );
3523 					aColor.SetGreen( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetGreen() ) ) >> 8 ) );
3524 					aColor.SetBlue( sal::static_int_cast< sal_uInt8 >( ( nInvParameter + ( nParameter * aColor.GetBlue() ) ) >> 8 ) );
3525 				}
3526 				break;
3527 				case 0x03 :		// add grey level RGB(p,p,p)
3528 				{
3529 					sal_Int16 nR = (sal_Int16)aColor.GetRed() + (sal_Int16)nParameter;
3530 					sal_Int16 nG = (sal_Int16)aColor.GetGreen() + (sal_Int16)nParameter;
3531 					sal_Int16 nB = (sal_Int16)aColor.GetBlue() + (sal_Int16)nParameter;
3532 					if ( nR > 0x00ff )
3533 						nR = 0x00ff;
3534 					if ( nG > 0x00ff )
3535 						nG = 0x00ff;
3536 					if ( nB > 0x00ff )
3537 						nB = 0x00ff;
3538 					aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB );
3539 				}
3540 				break;
3541 				case 0x04 :		// substract grey level RGB(p,p,p)
3542 				{
3543 					sal_Int16 nR = (sal_Int16)aColor.GetRed() - (sal_Int16)nParameter;
3544 					sal_Int16 nG = (sal_Int16)aColor.GetGreen() - (sal_Int16)nParameter;
3545 					sal_Int16 nB = (sal_Int16)aColor.GetBlue() - (sal_Int16)nParameter;
3546 					if ( nR < 0 )
3547 						nR = 0;
3548 					if ( nG < 0 )
3549 						nG = 0;
3550 					if ( nB < 0 )
3551 						nB = 0;
3552 					aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB );
3553 				}
3554 				break;
3555 				case 0x05 :		// substract from grey level RGB(p,p,p)
3556 				{
3557 					sal_Int16 nR = (sal_Int16)nParameter - (sal_Int16)aColor.GetRed();
3558 					sal_Int16 nG = (sal_Int16)nParameter - (sal_Int16)aColor.GetGreen();
3559 					sal_Int16 nB = (sal_Int16)nParameter - (sal_Int16)aColor.GetBlue();
3560 					if ( nR < 0 )
3561 						nR = 0;
3562 					if ( nG < 0 )
3563 						nG = 0;
3564 					if ( nB < 0 )
3565 						nB = 0;
3566 					aColor = Color( (sal_uInt8)nR, (sal_uInt8)nG, (sal_uInt8)nB );
3567 				}
3568 				break;
3569 				case 0x06 :		// per component: black if < p, white if >= p
3570 				{
3571 					aColor.SetRed( aColor.GetRed() < nParameter ? 0x00 : 0xff );
3572 					aColor.SetGreen( aColor.GetGreen() < nParameter ? 0x00 : 0xff );
3573 					aColor.SetBlue( aColor.GetBlue() < nParameter ? 0x00 : 0xff );
3574 				}
3575 				break;
3576 			}
3577 			if ( nAdditionalFlags & 0x40 )					// top-bit invert
3578 				aColor = Color( aColor.GetRed() ^ 0x80, aColor.GetGreen() ^ 0x80, aColor.GetBlue() ^ 0x80 );
3579 
3580 			if ( nAdditionalFlags & 0x20 )					// invert color
3581 				aColor = Color(0xff - aColor.GetRed(), 0xff - aColor.GetGreen(), 0xff - aColor.GetBlue());
3582 		}
3583 	}
3584 	else if ( ( nUpper & 4 ) && ( ( nColorCode & 0xfffff8 ) == 0 ) )
3585 	{	// case of nUpper == 4 powerpoint takes this as agrument for a colorschemecolor
3586 		GetColorFromPalette( nUpper, aColor );
3587 	}
3588 	else	// hart attributiert, eventuell mit Hinweis auf SYSTEMRGB
3589 		aColor = Color( (sal_uInt8)nColorCode, (sal_uInt8)( nColorCode >> 8 ), (sal_uInt8)( nColorCode >> 16 ) );
3590 	return aColor;
3591 }
3592 
3593 // sj: I just want to set a string for a text object that may contain multiple
3594 // paragraphs. If I now take a look at the follwing code I get the impression that
3595 // our outliner is too complicate to be used properly,
3596 void SvxMSDffManager::ReadObjText( const String& rText, SdrObject* pObj ) const
3597 {
3598 	SdrTextObj* pText = PTR_CAST( SdrTextObj, pObj );
3599 	if ( pText )
3600 	{
3601         SdrOutliner& rOutliner = pText->ImpGetDrawOutliner();
3602 		rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
3603 
3604 		sal_Bool bOldUpdateMode = rOutliner.GetUpdateMode();
3605 		rOutliner.SetUpdateMode( sal_False );
3606 		rOutliner.SetVertical( pText->IsVerticalWriting() );
3607 
3608 		sal_uInt16 nParaIndex = 0;
3609 		sal_uInt32 nParaSize;
3610 		const sal_Unicode* pCurrent, *pBuf = rText.GetBuffer();
3611 		const sal_Unicode* pEnd = rText.GetBuffer() + rText.Len();
3612 
3613 		while( pBuf < pEnd )
3614 		{
3615 			pCurrent = pBuf;
3616 
3617 			for ( nParaSize = 0; pBuf < pEnd; )
3618 			{
3619 				sal_Unicode nChar = *pBuf++;
3620 				if ( nChar == 0xa )
3621 				{
3622 					if ( ( pBuf < pEnd ) && ( *pBuf == 0xd ) )
3623 						pBuf++;
3624 					break;
3625 				}
3626 				else if ( nChar == 0xd )
3627 				{
3628 					if ( ( pBuf < pEnd ) && ( *pBuf == 0xa ) )
3629 						pBuf++;
3630 					break;
3631 				}
3632 				else
3633 					nParaSize++;
3634 			}
3635 			ESelection aSelection( nParaIndex, 0, nParaIndex, 0 );
3636 			String aParagraph( pCurrent, (sal_uInt16)nParaSize );
3637 			if ( !nParaIndex && !aParagraph.Len() )					// SJ: we are crashing if the first paragraph is empty ?
3638 				aParagraph += (sal_Unicode)' ';						// otherwise these two lines can be removed.
3639 			rOutliner.Insert( aParagraph, nParaIndex, 0 );
3640 			rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() );
3641 
3642 			SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() );
3643 			if ( !aSelection.nStartPos )
3644 				aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, sal_False ) );
3645 			aSelection.nStartPos = 0;
3646 			rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection );
3647 			nParaIndex++;
3648 		}
3649 		OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
3650         rOutliner.Clear();
3651 		rOutliner.SetUpdateMode( bOldUpdateMode );
3652 		pText->SetOutlinerParaObject( pNewText );
3653 	}
3654 }
3655 
3656 //static
3657 void SvxMSDffManager::MSDFFReadZString( SvStream& rIn, String& rStr,
3658 									sal_uLong nRecLen, FASTBOOL bUniCode )
3659 {
3660 	sal_uInt16 nLen = (sal_uInt16)nRecLen;
3661 	if( nLen )
3662 	{
3663 		if ( bUniCode )
3664 			nLen >>= 1;
3665 
3666 		String sBuf;
3667 		sal_Unicode* pBuf = sBuf.AllocBuffer( nLen );
3668 
3669 		if( bUniCode )
3670 		{
3671 			rIn.Read( (sal_Char*)pBuf, nLen << 1 );
3672 
3673 #ifdef OSL_BIGENDIAN
3674 			for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf )
3675     	    	*pBuf = SWAPSHORT( *pBuf );
3676 #endif // ifdef OSL_BIGENDIAN
3677 		}
3678 		else
3679 		{
3680 			// use the String-Data as buffer for the 8bit characters and
3681 			// change then all to unicode
3682 			sal_Char* pReadPos = ((sal_Char*)pBuf) + nLen;
3683 			rIn.Read( (sal_Char*)pReadPos, nLen );
3684 			for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf, ++pReadPos )
3685 				*pBuf = ByteString::ConvertToUnicode( *pReadPos, RTL_TEXTENCODING_MS_1252 );
3686 		}
3687 
3688 		rStr = sBuf.EraseTrailingChars( 0 );
3689 	}
3690 	else
3691 		rStr.Erase();
3692 }
3693 
3694 SdrObject* SvxMSDffManager::ImportFontWork( SvStream& rStCt, SfxItemSet& rSet, Rectangle& rBoundRect ) const
3695 {
3696 	SdrObject*	pRet = NULL;
3697 	String		aObjectText;
3698 	String		aFontName;
3699 	sal_Bool		bTextRotate = sal_False;
3700 
3701 	((SvxMSDffManager*)this)->mnFix16Angle = 0;	// we don't want to use this property in future
3702 	if ( SeekToContent( DFF_Prop_gtextUNICODE, rStCt ) )
3703 		MSDFFReadZString( rStCt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), sal_True );
3704 	if ( SeekToContent( DFF_Prop_gtextFont, rStCt ) )
3705 		MSDFFReadZString( rStCt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), sal_True );
3706 	if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 )
3707 	{
3708 		// Text ist senkrecht formatiert, Box Kippen
3709 		sal_Int32 nHalfWidth = ( rBoundRect.GetWidth() + 1) >> 1;
3710 		sal_Int32 nHalfHeight = ( rBoundRect.GetHeight() + 1) >> 1;
3711 		Point aTopLeft( rBoundRect.Left() + nHalfWidth - nHalfHeight,
3712 				rBoundRect.Top() + nHalfHeight - nHalfWidth);
3713 		Size aNewSize( rBoundRect.GetHeight(), rBoundRect.GetWidth() );
3714 		Rectangle aNewRect( aTopLeft, aNewSize );
3715 		rBoundRect = aNewRect;
3716 
3717 		String aSrcText( aObjectText );
3718 		aObjectText.Erase();
3719 		for( sal_uInt16 a = 0; a < aSrcText.Len(); a++ )
3720 		{
3721 			aObjectText += aSrcText.GetChar( a );
3722 			aObjectText += '\n';
3723 		}
3724 		rSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) );
3725 		bTextRotate = sal_True;
3726 	}
3727 	if ( aObjectText.Len() )
3728 	{	// FontWork-Objekt Mit dem Text in aObjectText erzeugen
3729 		SdrObject* pNewObj = new SdrRectObj( OBJ_TEXT, rBoundRect );
3730 		if( pNewObj )
3731 		{
3732 			pNewObj->SetModel( pSdrModel );
3733 			((SdrRectObj*)pNewObj)->SetText( aObjectText );
3734 			SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
3735 			rSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
3736 			rSet.Put( SdrTextAutoGrowHeightItem( sal_False ) );
3737 			rSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
3738             rSet.Put( SvxFontItem( FAMILY_DONTKNOW, aFontName, String(),
3739                             PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
3740 
3741             pNewObj->SetMergedItemSet(rSet);
3742 
3743 			pRet = pNewObj->ConvertToPolyObj( sal_False, sal_False );
3744 			if( !pRet )
3745 				pRet = pNewObj;
3746 			else
3747 			{
3748 				pRet->NbcSetSnapRect( rBoundRect );
3749                 SdrObject::Free( pNewObj );
3750 			}
3751 			if( bTextRotate )
3752 			{
3753 				double a = 9000 * nPi180;
3754 				pRet->NbcRotate( rBoundRect.Center(), 9000, sin( a ), cos( a ) );
3755 			}
3756 		}
3757 	}
3758 	return pRet;
3759 }
3760 
3761 static Size lcl_GetPrefSize(const Graphic& rGraf, MapMode aWanted)
3762 {
3763     MapMode aPrefMapMode(rGraf.GetPrefMapMode());
3764     if (aPrefMapMode == aWanted)
3765         return rGraf.GetPrefSize();
3766     Size aRetSize;
3767     if (aPrefMapMode == MAP_PIXEL)
3768     {
3769         aRetSize = Application::GetDefaultDevice()->PixelToLogic(
3770             rGraf.GetPrefSize(), aWanted);
3771     }
3772     else
3773     {
3774 	    aRetSize = Application::GetDefaultDevice()->LogicToLogic(
3775 		    rGraf.GetPrefSize(), rGraf.GetPrefMapMode(), aWanted);
3776     }
3777     return aRetSize;
3778 }
3779 
3780 // sj: if the parameter pSet is null, then the resulting crop bitmap will be stored in rGraf,
3781 // otherwise rGraf is untouched and pSet is used to store the corresponding SdrGrafCropItem
3782 static void lcl_ApplyCropping( const DffPropSet& rPropSet, SfxItemSet* pSet, Graphic& rGraf )
3783 {
3784 	sal_Int32 nCropTop		= (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromTop, 0 );
3785 	sal_Int32 nCropBottom	= (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromBottom, 0 );
3786 	sal_Int32 nCropLeft		= (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromLeft, 0 );
3787 	sal_Int32 nCropRight	= (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromRight, 0 );
3788 
3789 	if( nCropTop || nCropBottom || nCropLeft || nCropRight )
3790 	{
3791 		double      fFactor;
3792 		Size        aCropSize;
3793 		BitmapEx    aCropBitmap;
3794 		sal_uInt32  nTop( 0 ),  nBottom( 0 ), nLeft( 0 ), nRight( 0 );
3795 
3796 		if ( pSet )	// use crop attributes ?
3797 			aCropSize = lcl_GetPrefSize( rGraf, MAP_100TH_MM );
3798 		else
3799 		{
3800 			aCropBitmap = rGraf.GetBitmapEx();
3801 			aCropSize = aCropBitmap.GetSizePixel();
3802 		}
3803 		if ( nCropTop )
3804 		{
3805 			fFactor = (double)nCropTop / 65536.0;
3806 			nTop = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
3807 		}
3808 		if ( nCropBottom )
3809 		{
3810 			fFactor = (double)nCropBottom / 65536.0;
3811 			nBottom = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
3812 		}
3813 		if ( nCropLeft )
3814 		{
3815 			fFactor = (double)nCropLeft / 65536.0;
3816 			nLeft = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
3817 		}
3818 		if ( nCropRight )
3819 		{
3820 			fFactor = (double)nCropRight / 65536.0;
3821 			nRight = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
3822 		}
3823 		if ( pSet )	// use crop attributes ?
3824 			pSet->Put( SdrGrafCropItem( nLeft, nTop, nRight, nBottom ) );
3825 		else
3826 		{
3827     		Rectangle aCropRect( nLeft, nTop, aCropSize.Width() - nRight, aCropSize.Height() - nBottom );
3828 	    	aCropBitmap.Crop( aCropRect );
3829 		    rGraf = aCropBitmap;
3830 		}
3831 	}
3832 }
3833 
3834 SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, const DffObjData& rObjData ) const
3835 {
3836 	SdrObject*  pRet = NULL;
3837 	String      aFileName;
3838 	String      aLinkFileName, aLinkFilterName;
3839 	Rectangle	aVisArea;
3840 
3841 	MSO_BlipFlags eFlags = (MSO_BlipFlags)GetPropertyValue( DFF_Prop_pibFlags, mso_blipflagDefault );
3842 	sal_uInt32 nBlipId = GetPropertyValue( DFF_Prop_pib, 0 );
3843 	sal_Bool bGrfRead = sal_False,
3844 
3845 	// Grafik verlinkt
3846 	bLinkGrf = 0 != ( eFlags & mso_blipflagLinkToFile );
3847 	{
3848 		Graphic aGraf;	// be sure this graphic is deleted before swapping out
3849 		if( SeekToContent( DFF_Prop_pibName, rSt ) )
3850 			MSDFFReadZString( rSt, aFileName, GetPropertyValue( DFF_Prop_pibName ), sal_True );
3851 
3852 		//   UND, ODER folgendes:
3853 		if( !( eFlags & mso_blipflagDoNotSave ) ) // Grafik embedded
3854 		{
3855             bGrfRead = GetBLIP( nBlipId, aGraf, &aVisArea );
3856 			if ( !bGrfRead )
3857 			{
3858 				/*
3859 				Still no luck, lets look at the end of this record for a FBSE pool,
3860 				this fallback is a specific case for how word does it sometimes
3861 				*/
3862 				rObjData.rSpHd.SeekToEndOfRecord( rSt );
3863 				DffRecordHeader aHd;
3864 				rSt >> aHd;
3865 				if( DFF_msofbtBSE == aHd.nRecType )
3866 				{
3867 					const sal_uLong nSkipBLIPLen = 20;
3868 					const sal_uLong nSkipShapePos = 4;
3869 					const sal_uLong nSkipBLIP = 4;
3870 					const sal_uLong nSkip =
3871 						nSkipBLIPLen + 4 + nSkipShapePos + 4 + nSkipBLIP;
3872 
3873 					if (nSkip <= aHd.nRecLen)
3874 					{
3875 						rSt.SeekRel(nSkip);
3876 						if (0 == rSt.GetError())
3877 							bGrfRead = GetBLIPDirect( rSt, aGraf, &aVisArea );
3878 					}
3879 				}
3880 			}
3881 		}
3882 		if ( bGrfRead )
3883 		{
3884 			// the writer is doing it's own cropping, so this part affects only impress and calc
3885 			if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_CROP_BITMAPS )
3886 				lcl_ApplyCropping( *this, ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ? &rSet : NULL, aGraf );
3887 
3888 			if ( IsProperty( DFF_Prop_pictureTransparent ) )
3889 			{
3890 				sal_uInt32 nTransColor = GetPropertyValue( DFF_Prop_pictureTransparent, 0 );
3891 
3892 				if ( aGraf.GetType() == GRAPHIC_BITMAP )
3893 				{
3894 					BitmapEx	aBitmapEx( aGraf.GetBitmapEx() );
3895 					Bitmap		aBitmap( aBitmapEx.GetBitmap() );
3896 					Bitmap		aMask( aBitmap.CreateMask( MSO_CLR_ToColor( nTransColor, DFF_Prop_pictureTransparent ), 9 ) );
3897 					if ( aBitmapEx.IsTransparent() )
3898 						aMask.CombineSimple( aBitmapEx.GetMask(), BMP_COMBINE_OR );
3899 					aGraf = BitmapEx( aBitmap, aMask );
3900 				}
3901 			}
3902 
3903 			sal_Int32 nContrast = GetPropertyValue( DFF_Prop_pictureContrast, 0x10000 );
3904 			/*
3905 			0x10000 is msoffice 50%
3906 			< 0x10000 is in units of 1/50th of 0x10000 per 1%
3907 			> 0x10000 is in units where
3908 			a msoffice x% is stored as 50/(100-x) * 0x10000
3909 
3910 			plus, a (ui) microsoft % ranges from 0 to 100, OOO
3911 			from -100 to 100, so also normalize into that range
3912 			*/
3913 			if ( nContrast > 0x10000 )
3914 			{
3915 				double fX = nContrast;
3916 				fX /= 0x10000;
3917 				fX /= 51;	// 50 + 1 to round
3918 				fX = 1/fX;
3919 				nContrast = static_cast<sal_Int32>(fX);
3920 				nContrast -= 100;
3921 				nContrast = -nContrast;
3922 				nContrast = (nContrast-50)*2;
3923 			}
3924 			else if ( nContrast == 0x10000 )
3925 				nContrast = 0;
3926 			else
3927 			{
3928 				nContrast *= 101;	//100 + 1 to round
3929 				nContrast /= 0x10000;
3930 				nContrast -= 100;
3931 			}
3932 			sal_Int16	nBrightness		= (sal_Int16)( (sal_Int32)GetPropertyValue( DFF_Prop_pictureBrightness, 0 ) / 327 );
3933 			sal_Int32	nGamma			= GetPropertyValue( DFF_Prop_pictureGamma, 0x10000 );
3934 			GraphicDrawMode eDrawMode	= GRAPHICDRAWMODE_STANDARD;
3935 			switch ( GetPropertyValue( DFF_Prop_pictureActive ) & 6 )
3936 			{
3937 				case 4 : eDrawMode = GRAPHICDRAWMODE_GREYS; break;
3938 				case 6 : eDrawMode = GRAPHICDRAWMODE_MONO; break;
3939 				case 0 :
3940 				{
3941 					//office considers the converted values of (in OOo) 70 to be the
3942 					//"watermark" values, which can vary slightly due to rounding from the
3943 					//above values
3944 					if (( nContrast == -70 ) && ( nBrightness == 70 ))
3945 					{
3946 						nContrast = 0;
3947 						nBrightness = 0;
3948 						eDrawMode = GRAPHICDRAWMODE_WATERMARK;
3949 					};
3950 				}
3951 				break;
3952 			}
3953 
3954 			if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) )
3955 			{
3956 				if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 )
3957 				{
3958 					if ( nBrightness )
3959 						rSet.Put( SdrGrafLuminanceItem( nBrightness ) );
3960 					if ( nContrast )
3961 						rSet.Put( SdrGrafContrastItem( (sal_Int16)nContrast ) );
3962 					if ( nGamma != 0x10000 )
3963 						rSet.Put( SdrGrafGamma100Item( nGamma / 655 ) );
3964 					if ( eDrawMode != GRAPHICDRAWMODE_STANDARD )
3965 						rSet.Put( SdrGrafModeItem( eDrawMode ) );
3966 				}
3967 				else
3968 				{
3969 					if ( eDrawMode == GRAPHICDRAWMODE_WATERMARK )
3970 					{
3971 						nContrast = 60;
3972 						nBrightness = 70;
3973 						eDrawMode = GRAPHICDRAWMODE_STANDARD;
3974 					}
3975 					switch ( aGraf.GetType() )
3976 					{
3977 						case GRAPHIC_BITMAP :
3978 						{
3979 							BitmapEx	aBitmapEx( aGraf.GetBitmapEx() );
3980 							if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
3981 								aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False );
3982 							if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
3983 								aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
3984 							else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
3985 								aBitmapEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
3986 							aGraf = aBitmapEx;
3987 
3988 						}
3989 						break;
3990 
3991 						case GRAPHIC_GDIMETAFILE :
3992 						{
3993 							GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() );
3994 							if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
3995 								aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, sal_False );
3996 							if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
3997 								aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS );
3998 							else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
3999 								aGdiMetaFile.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
4000 							aGraf = aGdiMetaFile;
4001 						}
4002 						break;
4003 						default: break;
4004 					}
4005 				}
4006 			}
4007 		}
4008 
4009 		// sollte es ein OLE-Object sein?
4010 		if( bGrfRead && !bLinkGrf && IsProperty( DFF_Prop_pictureId ) )
4011         {
4012 			// TODO/LATER: in future probably the correct aspect should be provided here
4013 			sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
4014             // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method
4015             pRet = ImportOLE( GetPropertyValue( DFF_Prop_pictureId ), aGraf, rObjData.aBoundRect, aVisArea, rObjData.nCalledByGroup, nAspect );
4016             // <--
4017         }
4018 		if( !pRet )
4019 		{
4020 			pRet = new SdrGrafObj;
4021 			if( bGrfRead )
4022 				((SdrGrafObj*)pRet)->SetGraphic( aGraf );
4023 
4024 			if( bLinkGrf && !bGrfRead )		// sj: #i55484# if the graphic was embedded ( bGrfRead == true ) then
4025 			{								// we do not need to set a link. TODO: not to lose the information where the graphic is linked from
4026 				INetURLObject aAbsURL;
4027 				if ( !INetURLObject( maBaseURL ).GetNewAbsURL( ByteString( aFileName, RTL_TEXTENCODING_UTF8 ), &aAbsURL ) )
4028 				{
4029 		    		String aValidURL;
4030 			    	if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aFileName, aValidURL ) )
4031 				    	aAbsURL = INetURLObject( aValidURL );
4032 				}
4033 				if( aAbsURL.GetProtocol() != INET_PROT_NOT_VALID )
4034 				{
4035 					GraphicFilter* pGrfFilter = GraphicFilter::GetGraphicFilter();
4036 					aLinkFilterName = pGrfFilter->GetImportFormatName(
4037 					                pGrfFilter->GetImportFormatNumberForShortName( aAbsURL.getExtension() ) );
4038 					aLinkFileName = aAbsURL.GetMainURL( INetURLObject::DECODE_TO_IURI );
4039 				}
4040 				else
4041 					aLinkFileName = aFileName;
4042 			}
4043 		}
4044 
4045 		// set the size from BLIP if there is one
4046 		if ( pRet && bGrfRead && !aVisArea.IsEmpty() )
4047 			pRet->SetBLIPSizeRectangle( aVisArea );
4048 
4049 		if ( !pRet->GetName().Len() )					// SJ 22.02.00 : PPT OLE IMPORT:
4050 		{												// name is already set in ImportOLE !!
4051 			// JP 01.12.99: SetName before SetModel - because in the other order the Bug 70098 is active
4052 			if ( ( eFlags & mso_blipflagType ) != mso_blipflagComment )
4053 			{
4054 				INetURLObject aURL;
4055 				aURL.SetSmartURL( aFileName );
4056 				pRet->SetName( aURL.getBase() );
4057 			}
4058 			else
4059 				pRet->SetName( aFileName );
4060 		}
4061 	}
4062 	pRet->SetModel( pSdrModel ); // fuer GraphicLink erforderlich
4063 	pRet->SetLogicRect( rObjData.aBoundRect );
4064 
4065 	if ( pRet->ISA( SdrGrafObj ) )
4066 	{
4067 		if( aLinkFileName.Len() )
4068 		    ((SdrGrafObj*)pRet)->SetGraphicLink( aLinkFileName, aLinkFilterName );
4069 
4070 		if ( bLinkGrf && !bGrfRead )
4071 		{
4072 			((SdrGrafObj*)pRet)->ForceSwapIn();
4073 			Graphic aGraf(((SdrGrafObj*)pRet)->GetGraphic());
4074 			lcl_ApplyCropping( *this, &rSet, aGraf );
4075 		}
4076 		((SdrGrafObj*)pRet)->ForceSwapOut();
4077 	}
4078 
4079 	return pRet;
4080 }
4081 
4082 // PptSlidePersistEntry& rPersistEntry, SdPage* pPage
4083 SdrObject* SvxMSDffManager::ImportObj( SvStream& rSt, void* pClientData,
4084     Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup, sal_Int32* pShapeId )
4085 {
4086     SdrObject* pRet = NULL;
4087     DffRecordHeader aObjHd;
4088     rSt >> aObjHd;
4089 	if ( aObjHd.nRecType == DFF_msofbtSpgrContainer )
4090 	{
4091 		pRet = ImportGroup( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4092     }
4093     else if ( aObjHd.nRecType == DFF_msofbtSpContainer )
4094 	{
4095 		pRet = ImportShape( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4096     }
4097     aObjHd.SeekToBegOfRecord( rSt );	// FilePos restaurieren
4098     return pRet;
4099 }
4100 
4101 SdrObject* SvxMSDffManager::ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4102                                             Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4103 												int nCalledByGroup, sal_Int32* pShapeId )
4104 {
4105 	SdrObject* pRet = NULL;
4106 
4107 	if( pShapeId )
4108 		*pShapeId = 0;
4109 
4110 	rHd.SeekToContent( rSt );
4111 	DffRecordHeader aRecHd;		// the first atom has to be the SpContainer for the GroupObject
4112     rSt >> aRecHd;
4113 	if ( aRecHd.nRecType == DFF_msofbtSpContainer )
4114 	{
4115 		sal_Int32 nGroupRotateAngle = 0;
4116 		sal_Int32 nSpFlags = 0;
4117 		mnFix16Angle = 0;
4118 		aRecHd.SeekToBegOfRecord( rSt );
4119 		pRet = ImportObj( rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup + 1, pShapeId );
4120 		if ( pRet )
4121 		{
4122 			nSpFlags = nGroupShapeFlags;
4123 			nGroupRotateAngle = mnFix16Angle;
4124 
4125 			Rectangle aClientRect( rClientRect );
4126 
4127 			Rectangle aGlobalChildRect;
4128 			if ( !nCalledByGroup || rGlobalChildRect.IsEmpty() )
4129 				aGlobalChildRect = GetGlobalChildAnchor( rHd, rSt, aClientRect );
4130 			else
4131 				aGlobalChildRect = rGlobalChildRect;
4132 
4133 			if ( ( nGroupRotateAngle > 4500 && nGroupRotateAngle <= 13500 )
4134 				|| ( nGroupRotateAngle > 22500 && nGroupRotateAngle <= 31500 ) )
4135 			{
4136 				sal_Int32 nHalfWidth = ( aClientRect.GetWidth() + 1 ) >> 1;
4137 				sal_Int32 nHalfHeight = ( aClientRect.GetHeight() + 1 ) >> 1;
4138 				Point aTopLeft( aClientRect.Left() + nHalfWidth - nHalfHeight,
4139 								aClientRect.Top() + nHalfHeight - nHalfWidth );
4140 				Size aNewSize( aClientRect.GetHeight(), aClientRect.GetWidth() );
4141 				Rectangle aNewRect( aTopLeft, aNewSize );
4142 				aClientRect = aNewRect;
4143 			}
4144 
4145 			// now importing the inner objects of the group
4146 			aRecHd.SeekToEndOfRecord( rSt );
4147 			while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4148 			{
4149 				DffRecordHeader aRecHd2;
4150 				rSt >> aRecHd2;
4151 				if ( aRecHd2.nRecType == DFF_msofbtSpgrContainer )
4152 				{
4153 					Rectangle aGroupClientAnchor, aGroupChildAnchor;
4154 					GetGroupAnchors( aRecHd2, rSt, aGroupClientAnchor, aGroupChildAnchor, aClientRect, aGlobalChildRect );
4155 					aRecHd2.SeekToBegOfRecord( rSt );
4156 					sal_Int32 nShapeId;
4157 					SdrObject* pTmp = ImportGroup( aRecHd2, rSt, pClientData, aGroupClientAnchor, aGroupChildAnchor, nCalledByGroup + 1, &nShapeId );
4158 					if ( pTmp )
4159 					{
4160 						((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4161 						if( nShapeId )
4162 							insertShapeId( nShapeId, pTmp );
4163 					}
4164 				}
4165 				else if ( aRecHd2.nRecType == DFF_msofbtSpContainer )
4166 				{
4167 					aRecHd2.SeekToBegOfRecord( rSt );
4168 					sal_Int32 nShapeId;
4169 					SdrObject* pTmp = ImportShape( aRecHd2, rSt, pClientData, aClientRect, aGlobalChildRect, nCalledByGroup + 1, &nShapeId );
4170 					if ( pTmp )
4171 					{
4172 						((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4173 						if( nShapeId )
4174 							insertShapeId( nShapeId, pTmp );
4175 					}
4176 				}
4177 				aRecHd2.SeekToEndOfRecord( rSt );
4178 			}
4179 
4180 	//		pRet->NbcSetSnapRect( aGroupBound );
4181 			if ( nGroupRotateAngle )
4182 			{
4183 				double a = nGroupRotateAngle * nPi180;
4184 				pRet->NbcRotate( aClientRect.Center(), nGroupRotateAngle, sin( a ), cos( a ) );
4185 			}
4186 			if ( nSpFlags & SP_FFLIPV )		// Vertikal gespiegelt?
4187 			{	// BoundRect in aBoundRect
4188 				Point aLeft( aClientRect.Left(), ( aClientRect.Top() + aClientRect.Bottom() ) >> 1 );
4189 				Point aRight( aLeft.X() + 1000, aLeft.Y() );
4190 				pRet->NbcMirror( aLeft, aRight );
4191 			}
4192 			if ( nSpFlags & SP_FFLIPH )		// Horizontal gespiegelt?
4193 			{	// BoundRect in aBoundRect
4194 				Point aTop( ( aClientRect.Left() + aClientRect.Right() ) >> 1, aClientRect.Top() );
4195 				Point aBottom( aTop.X(), aTop.Y() + 1000 );
4196 				pRet->NbcMirror( aTop, aBottom );
4197 			}
4198 		}
4199 	}
4200 	return pRet;
4201 }
4202 
4203 SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4204                                             Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4205 											int nCalledByGroup, sal_Int32* pShapeId )
4206 {
4207 	SdrObject* pRet = NULL;
4208 
4209 	if( pShapeId )
4210 		*pShapeId = 0;
4211 
4212 	rHd.SeekToBegOfRecord( rSt );
4213 	DffObjData aObjData( rHd, rClientRect, nCalledByGroup );
4214 	aObjData.bRotateTextWithShape = ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_EXCEL ) == 0;
4215 	maShapeRecords.Consume( rSt, sal_False );
4216 	aObjData.bShapeType = maShapeRecords.SeekToContent( rSt, DFF_msofbtSp, SEEK_FROM_BEGINNING );
4217 	if ( aObjData.bShapeType )
4218 	{
4219 		rSt >> aObjData.nShapeId
4220 			>> aObjData.nSpFlags;
4221 		aObjData.eShapeType = (MSO_SPT)maShapeRecords.Current()->nRecInstance;
4222 	}
4223 	else
4224 	{
4225 		aObjData.nShapeId = 0;
4226 		aObjData.nSpFlags = 0;
4227 		aObjData.eShapeType = mso_sptNil;
4228 	}
4229 
4230 	if( pShapeId )
4231 		*pShapeId = aObjData.nShapeId;
4232 
4233 	if ( mbTracing )
4234 		mpTracer->AddAttribute( aObjData.nSpFlags & SP_FGROUP
4235 								? rtl::OUString::createFromAscii( "GroupShape" )
4236 								: rtl::OUString::createFromAscii( "Shape" ),
4237 								rtl::OUString::valueOf( (sal_Int32)aObjData.nShapeId ) );
4238 	aObjData.bOpt = maShapeRecords.SeekToContent( rSt, DFF_msofbtOPT, SEEK_FROM_CURRENT_AND_RESTART );
4239 	if ( aObjData.bOpt )
4240 	{
4241         maShapeRecords.Current()->SeekToBegOfRecord( rSt );
4242 #ifdef DBG_AUTOSHAPE
4243 		ReadPropSet( rSt, pClientData, (sal_uInt32)aObjData.eShapeType );
4244 #else
4245 		ReadPropSet( rSt, pClientData );
4246 #endif
4247 	}
4248 	else
4249 	{
4250 		InitializePropSet( DFF_msofbtOPT );		// get the default PropSet
4251 		( (DffPropertyReader*) this )->mnFix16Angle = 0;
4252 	}
4253 	aObjData.bOpt2 = maShapeRecords.SeekToContent( rSt, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART );
4254 	if ( aObjData.bOpt2 )
4255 	{
4256 		maShapeRecords.Current()->SeekToBegOfRecord( rSt );
4257 		pSecPropSet = new DffPropertyReader( *this );
4258 		pSecPropSet->ReadPropSet( rSt, NULL );
4259 	}
4260 
4261 	aObjData.bChildAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtChildAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4262 	if ( aObjData.bChildAnchor )
4263 	{
4264         sal_Int32 l, o, r, u;
4265         rSt >> l >> o >> r >> u;
4266         Scale( l );
4267         Scale( o );
4268         Scale( r );
4269         Scale( u );
4270         aObjData.aChildAnchor = Rectangle( l, o, r, u );
4271 		if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
4272 		{
4273 			double fl = l;
4274 			double fo = o;
4275 			double fWidth = r - l;
4276 			double fHeight= u - o;
4277 			double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
4278 			double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
4279 			fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
4280 			fo = ( ( o - rGlobalChildRect.Top()  ) * fYScale ) + rClientRect.Top();
4281 			fWidth *= fXScale;
4282 			fHeight *= fYScale;
4283 			aObjData.aChildAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
4284 		}
4285 	}
4286 
4287 	aObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtClientAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4288 	if ( aObjData.bClientAnchor )
4289 		ProcessClientAnchor2( rSt, *maShapeRecords.Current(), pClientData, aObjData );
4290 
4291 	if ( aObjData.bChildAnchor )
4292 		aObjData.aBoundRect = aObjData.aChildAnchor;
4293 
4294 	if ( aObjData.nSpFlags & SP_FBACKGROUND )
4295 		aObjData.aBoundRect = Rectangle( Point(), Size( 1, 1 ) );
4296 
4297 	Rectangle aTextRect;
4298     if ( !aObjData.aBoundRect.IsEmpty() )
4299 	{	// Rotation auf BoundingBox anwenden, BEVOR ien Objekt generiert wurde
4300 		if( mnFix16Angle )
4301 		{
4302 			long nAngle = mnFix16Angle;
4303 			if ( ( nAngle > 4500 && nAngle <= 13500 ) || ( nAngle > 22500 && nAngle <= 31500 ) )
4304 			{
4305 				sal_Int32 nHalfWidth = ( aObjData.aBoundRect.GetWidth() + 1 ) >> 1;
4306 				sal_Int32 nHalfHeight = ( aObjData.aBoundRect.GetHeight() + 1 ) >> 1;
4307 				Point aTopLeft( aObjData.aBoundRect.Left() + nHalfWidth - nHalfHeight,
4308 								aObjData.aBoundRect.Top() + nHalfHeight - nHalfWidth );
4309 				Size aNewSize( aObjData.aBoundRect.GetHeight(), aObjData.aBoundRect.GetWidth() );
4310 				Rectangle aNewRect( aTopLeft, aNewSize );
4311 				aObjData.aBoundRect = aNewRect;
4312 			}
4313 		}
4314 		aTextRect = aObjData.aBoundRect;
4315 		FASTBOOL bGraphic = IsProperty( DFF_Prop_pib ) ||
4316 							IsProperty( DFF_Prop_pibName ) ||
4317 							IsProperty( DFF_Prop_pibFlags );
4318 
4319 		if ( aObjData.nSpFlags & SP_FGROUP )
4320 		{
4321 			pRet = new SdrObjGroup;
4322             /*  After CWS aw033 has been integrated, an empty group object
4323                 cannot store its resulting bounding rectangle anymore. We have
4324                 to return this rectangle via rClientRect now, but only, if
4325                 caller has not passed an own bounding ractangle. */
4326             if ( rClientRect.IsEmpty() )
4327                  rClientRect = aObjData.aBoundRect;
4328 			nGroupShapeFlags = aObjData.nSpFlags;		// #73013#
4329 		}
4330 		else if ( ( aObjData.eShapeType != mso_sptNil ) || IsProperty( DFF_Prop_pVertices ) || bGraphic )
4331 		{
4332 			SfxItemSet	aSet( pSdrModel->GetItemPool() );
4333 
4334 			sal_Bool	bIsConnector = ( ( aObjData.eShapeType >= mso_sptStraightConnector1 ) && ( aObjData.eShapeType <= mso_sptCurvedConnector5 ) );
4335 			sal_Bool	bIsCustomShape = sal_False;
4336 			sal_Int32	nObjectRotation = mnFix16Angle;
4337 			sal_uInt32	nSpFlags = aObjData.nSpFlags;
4338 
4339 			if ( bGraphic )
4340 			{
4341 				pRet = ImportGraphic( rSt, aSet, aObjData );		// SJ: #68396# is no longer true (fixed in ppt2000)
4342 				ApplyAttributes( rSt, aSet, aObjData );
4343 				pRet->SetMergedItemSet(aSet);
4344 			}
4345 			else if ( aObjData.eShapeType == mso_sptLine )
4346 			{
4347 				basegfx::B2DPolygon aPoly;
4348 				aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Left(), aObjData.aBoundRect.Top()));
4349 				aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Right(), aObjData.aBoundRect.Bottom()));
4350 				pRet = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly));
4351 				pRet->SetModel( pSdrModel );
4352 				ApplyAttributes( rSt, aSet, aObjData );
4353 				pRet->SetMergedItemSet(aSet);
4354 			}
4355 			else
4356 			{
4357 				if ( GetCustomShapeContent( aObjData.eShapeType ) || IsProperty( DFF_Prop_pVertices ) )
4358 				{
4359 
4360 					ApplyAttributes( rSt, aSet, aObjData );
4361 
4362 // the com.sun.star.drawing.EnhancedCustomShapeEngine is default, so we do not need to set a hard attribute
4363 //						aSet.Put( SdrCustomShapeEngineItem( String::CreateFromAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) );
4364 					pRet = new SdrObjCustomShape();
4365 					pRet->SetModel( pSdrModel );
4366 
4367 					sal_Bool bIsFontwork = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) != 0;
4368 
4369 					// in case of a FontWork, the text is set by the escher import
4370 					if ( bIsFontwork )
4371 					{
4372 						String				aObjectText;
4373 						String				aFontName;
4374 						MSO_GeoTextAlign	eGeoTextAlign;
4375 
4376 						if ( SeekToContent( DFF_Prop_gtextFont, rSt ) )
4377 						{
4378                             SvxFontItem aLatin(EE_CHAR_FONTINFO), aAsian(EE_CHAR_FONTINFO_CJK), aComplex(EE_CHAR_FONTINFO_CTL);
4379 							GetDefaultFonts( aLatin, aAsian, aComplex );
4380 
4381 							MSDFFReadZString( rSt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), sal_True );
4382                             aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4383                                         PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
4384 							aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4385 										PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CJK ) );
4386 							aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4387 										PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CTL ) );
4388 						}
4389 
4390 						// SJ: applying fontattributes for Fontwork :
4391 						if ( IsHardAttribute( DFF_Prop_gtextFItalic ) )
4392                             aSet.Put( SvxPostureItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0010 ) != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
4393 
4394 						if ( IsHardAttribute( DFF_Prop_gtextFBold ) )
4395                             aSet.Put( SvxWeightItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0020 ) != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
4396 
4397 						// SJ TODO: Vertical Writing is not correct, instead this should be
4398 						// replaced through "CharacterRotation" by 90�, therefore a new Item has to be
4399 						// supported by svx core, api and xml file format
4400 						((SdrObjCustomShape*)pRet)->SetVerticalWriting( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) != 0 );
4401 
4402 						if ( SeekToContent( DFF_Prop_gtextUNICODE, rSt ) )
4403 						{
4404 							MSDFFReadZString( rSt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), sal_True );
4405 							ReadObjText( aObjectText, pRet );
4406 						}
4407 
4408 						eGeoTextAlign = ( (MSO_GeoTextAlign)GetPropertyValue( DFF_Prop_gtextAlign, mso_alignTextCenter ) );
4409 						{
4410 							SdrTextHorzAdjust eHorzAdjust;
4411 							switch( eGeoTextAlign )
4412 							{
4413 								case mso_alignTextLetterJust :
4414 								case mso_alignTextWordJust :
4415 								case mso_alignTextStretch : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break;
4416 								default:
4417 								case mso_alignTextInvalid :
4418 								case mso_alignTextCenter : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break;
4419 								case mso_alignTextLeft : eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break;
4420 								case mso_alignTextRight : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break;
4421 							}
4422 							aSet.Put( SdrTextHorzAdjustItem( eHorzAdjust ) );
4423 
4424 							SdrFitToSizeType eFTS = SDRTEXTFIT_NONE;
4425 							if ( eGeoTextAlign == mso_alignTextStretch )
4426 								eFTS = SDRTEXTFIT_ALLLINES;
4427 							aSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
4428 						}
4429 						if ( IsProperty( DFF_Prop_gtextSpacing ) )
4430 						{
4431 							sal_Int32 nTextWidth = GetPropertyValue( DFF_Prop_gtextSpacing, 100 < 16 ) / 655;
4432 							if ( nTextWidth != 100 )
4433 								aSet.Put( SvxCharScaleWidthItem( (sal_uInt16)nTextWidth, EE_CHAR_FONTWIDTH ) );
4434 						}
4435 						if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x1000 )	// SJ: Font Kerning On ?
4436 							aSet.Put( SvxKerningItem( 1, EE_CHAR_KERNING ) );
4437 					}
4438                     pRet->SetMergedItemSet( aSet );
4439 
4440 					// sj: taking care of rtl, ltr. In case of fontwork mso. seems not to be able to set
4441 					// proper text directions, instead the text default is depending to the string.
4442 					// so we have to calculate the a text direction from string:
4443 					if ( bIsFontwork )
4444 					{
4445 						OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pRet)->GetOutlinerParaObject();
4446 						if ( pParaObj )
4447 						{
4448 							SdrOutliner& rOutliner = ((SdrObjCustomShape*)pRet)->ImpGetDrawOutliner();
4449 							sal_Bool bOldUpdateMode = rOutliner.GetUpdateMode();
4450 							SdrModel* pModel = pRet->GetModel();
4451 							if ( pModel )
4452 								rOutliner.SetStyleSheetPool( (SfxStyleSheetPool*)pModel->GetStyleSheetPool() );
4453 							rOutliner.SetUpdateMode( sal_False );
4454 							rOutliner.SetText( *pParaObj );
4455 							VirtualDevice aVirDev( 1 );
4456 							aVirDev.SetMapMode( MAP_100TH_MM );
4457 							sal_uInt32 i, nParagraphs = rOutliner.GetParagraphCount();
4458 							if ( nParagraphs )
4459 							{
4460 								sal_Bool bCreateNewParaObject = sal_False;
4461 								for ( i = 0; i < nParagraphs; i++ )
4462 								{
4463 									sal_Bool bIsRTL = aVirDev.GetTextIsRTL( rOutliner.GetText( rOutliner.GetParagraph( i ) ), 0, STRING_LEN );
4464 									if ( bIsRTL )
4465 									{
4466 										SfxItemSet aSet2( rOutliner.GetParaAttribs( (sal_uInt16)i ) );
4467 										aSet2.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
4468 										rOutliner.SetParaAttribs( (sal_uInt16)i, aSet2 );
4469 										bCreateNewParaObject = sal_True;
4470 									}
4471 								}
4472 								if  ( bCreateNewParaObject )
4473 								{
4474 									OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
4475 									rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
4476 									((SdrObjCustomShape*)pRet)->NbcSetOutlinerParaObject( pNewText );
4477 								}
4478 							}
4479 					        rOutliner.Clear();
4480 							rOutliner.SetUpdateMode( bOldUpdateMode );
4481 						}
4482 					}
4483 
4484 					// mso_sptArc special treating:
4485 					// sj: since we actually can't render the arc because of its weird SnapRect settings,
4486 					// we will create a new CustomShape, that can be saved/loaded without problems.
4487 					// We will change the shape type, so this code applys only if importing arcs from msoffice.
4488 					if ( aObjData.eShapeType == mso_sptArc )
4489 					{
4490 						const rtl::OUString	sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
4491 						const rtl::OUString	sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
4492 						const rtl::OUString	sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
4493 						const rtl::OUString	sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
4494 						const rtl::OUString	sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
4495 						const rtl::OUString	sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
4496 						const rtl::OUString	sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
4497 						SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
4498 						com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
4499 						com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
4500 
4501 						// before clearing the GeometryItem we have to store the current Coordinates
4502 						const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
4503 						Rectangle aPolyBoundRect;
4504 						Point aStartPt( 0,0 );
4505 						if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) )
4506 						{
4507 							sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength();
4508 							XPolygon aXP( (sal_uInt16)nNumElemVert );
4509 //								const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
4510 							for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ )
4511 							{
4512 								Point aP;
4513 								sal_Int32 nX = 0, nY = 0;
4514 								seqCoordinates[ nPtNum ].First.Value >>= nX;
4515 								seqCoordinates[ nPtNum ].Second.Value >>= nY;
4516 								aP.X() = nX;
4517 								aP.Y() = nY;
4518 								aXP[ (sal_uInt16)nPtNum ] = aP;
4519 							}
4520 							aPolyBoundRect = Rectangle( aXP.GetBoundRect() );
4521 							if ( nNumElemVert >= 3 )
4522 							{ // arc first command is always wr -- clockwise arc
4523 								// the parameters are : (left,top),(right,bottom),start(x,y),end(x,y)
4524 								aStartPt = aXP[2];
4525 							}
4526 						}
4527 						else
4528 							aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 );	// defaulting
4529 
4530 						// clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry
4531 						aGeometryItem.ClearPropertyValue( sHandles );
4532 						aGeometryItem.ClearPropertyValue( sEquations );
4533 						aGeometryItem.ClearPropertyValue( sViewBox );
4534 						aGeometryItem.ClearPropertyValue( sPath );
4535 
4536 						sal_Int32 nEndAngle = 9000;
4537 						sal_Int32 nStartAngle = 0;
4538 						pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
4539 						if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 )
4540 						{
4541 							double fNumber;
4542 							if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
4543 							{
4544 								seqAdjustmentValues[ 0 ].Value >>= fNumber;
4545 								nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4546 							}
4547 							else
4548 							{
4549 								fNumber = 270.0;
4550 								//normal situation:if endAngle != 90,there will be a direct_value,but for damaged curve,the endAngle need to recalculate.
4551 								Point cent = aPolyBoundRect.Center();
4552 								if ( aStartPt.Y() == cent.Y() )
4553 									fNumber = ( aStartPt.X() >= cent.X() ) ? 0:180.0;
4554 								else if ( aStartPt.X() == cent.X() )
4555 									fNumber = ( aStartPt.Y() >= cent.Y() ) ? 90.0: 270.0;
4556 								else
4557 								{
4558 									fNumber = atan2( double( aStartPt.X() - cent.X() ),double( aStartPt.Y() - cent.Y() ) )+ F_PI; // 0..2PI
4559 									fNumber /= F_PI180; // 0..360.0
4560 								}
4561 								nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4562 								seqAdjustmentValues[ 0 ].Value <<= fNumber;
4563 								seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;		// so this value will properly be stored
4564 							}
4565 
4566 							if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
4567 							{
4568 								seqAdjustmentValues[ 1 ].Value >>= fNumber;
4569 								nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4570 							}
4571 							else
4572 							{
4573 								fNumber = 0.0;
4574 								seqAdjustmentValues[ 1 ].Value <<= fNumber;
4575 								seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
4576 							}
4577 
4578 							PropertyValue aPropVal;
4579 							aPropVal.Name = sAdjustmentValues;
4580 							aPropVal.Value <<= seqAdjustmentValues;
4581 							aGeometryItem.SetPropertyValue( aPropVal );		// storing the angle attribute
4582 						}
4583 						if ( nStartAngle != nEndAngle )
4584 						{
4585 							XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2,
4586 								(sal_uInt16)nStartAngle / 10, (sal_uInt16)nEndAngle / 10, sal_True );
4587 							Rectangle aPolyPieRect( aXPoly.GetBoundRect() );
4588 
4589 							double	fYScale, fXScale;
4590 							double	fYOfs, fXOfs;
4591 
4592 							Point aP( aObjData.aBoundRect.Center() );
4593 							Size aS( aObjData.aBoundRect.GetSize() );
4594 							aP.X() -= aS.Width() / 2;
4595 							aP.Y() -= aS.Height() / 2;
4596 							Rectangle aLogicRect( aP, aS );
4597 
4598 							fYOfs = fXOfs = 0.0;
4599 
4600 							if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() )
4601 							{
4602 								fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth();
4603 								if ( nSpFlags & SP_FFLIPH )
4604 									fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale;
4605 								else
4606 									fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale;
4607 							}
4608 							if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() )
4609 							{
4610 								fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight();
4611 								if ( nSpFlags & SP_FFLIPV )
4612 									fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale;
4613 								else
4614 									fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale;
4615 							}
4616 
4617 							fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth();
4618 							fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight();
4619 
4620 							Rectangle aOldBoundRect( aObjData.aBoundRect );
4621 							aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ),
4622 							 	Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) );
4623 
4624 							// creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system
4625 							double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth();
4626 							double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight();
4627 							sal_Int32 nLeft  = (sal_Int32)(( aPolyPieRect.Left()  - aPolyBoundRect.Left() ) * fTextFrameScaleX );
4628 							sal_Int32 nTop   = (sal_Int32)(( aPolyPieRect.Top()   - aPolyBoundRect.Top() )  * fTextFrameScaleY );
4629 							sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
4630 							sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() )  * fTextFrameScaleY );
4631 							com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 );
4632 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First,	   nLeft );
4633 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second,    nTop );
4634 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight );
4635 							EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom );
4636 							PropertyValue aProp;
4637 							aProp.Name = sTextFrames;
4638 							aProp.Value <<= aTextFrame;
4639 							aGeometryItem.SetPropertyValue( sPath, aProp );
4640 
4641 							// sj: taking care of the different rotation points, since the new arc is having a bigger snaprect
4642 							if ( mnFix16Angle )
4643 							{
4644 								sal_Int32 nAngle = mnFix16Angle;
4645 								if ( nSpFlags & SP_FFLIPH )
4646 									nAngle = 36000 - nAngle;
4647 								if ( nSpFlags & SP_FFLIPV )
4648 									nAngle = -nAngle;
4649 								double a = nAngle * F_PI18000;
4650 								double ss = sin( a );
4651 								double cc = cos( a );
4652 								Point aP1( aOldBoundRect.TopLeft() );
4653 								Point aC1( aObjData.aBoundRect.Center() );
4654 								Point aP2( aOldBoundRect.TopLeft() );
4655 								Point aC2( aOldBoundRect.Center() );
4656 								RotatePoint( aP1, aC1, ss, cc );
4657 								RotatePoint( aP2, aC2, ss, cc );
4658 								aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() );
4659 							}
4660 						}
4661 						((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem );
4662 						((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
4663 
4664 						// now setting a new name, so the above correction is only done once when importing from ms
4665 						SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
4666 						const rtl::OUString	sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
4667 						const rtl::OUString	sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) );
4668 						PropertyValue aPropVal;
4669 						aPropVal.Name = sType;
4670 						aPropVal.Value <<= sName;
4671 						aGeoName.SetPropertyValue( aPropVal );
4672 						((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName );
4673 					}
4674 					else
4675 						((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
4676 
4677 					pRet->SetSnapRect( aObjData.aBoundRect );
4678 					EnhancedCustomShape2d aCustomShape2d( pRet );
4679 					aTextRect = aCustomShape2d.GetTextRect();
4680 
4681 					bIsCustomShape = sal_True;
4682 
4683 					if( bIsConnector )
4684 					{
4685 						if( nObjectRotation )
4686 						{
4687 							double a = nObjectRotation * nPi180;
4688 							pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
4689 						}
4690 						// Horizontal gespiegelt?
4691 						if ( nSpFlags & SP_FFLIPH )
4692 						{
4693 							Rectangle aBndRect( pRet->GetSnapRect() );
4694 							Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
4695 							Point aBottom( aTop.X(), aTop.Y() + 1000 );
4696 							pRet->NbcMirror( aTop, aBottom );
4697 						}
4698 						// Vertikal gespiegelt?
4699 						if ( nSpFlags & SP_FFLIPV )
4700 						{
4701 							Rectangle aBndRect( pRet->GetSnapRect() );
4702 							Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
4703 							Point aRight( aLeft.X() + 1000, aLeft.Y() );
4704 							pRet->NbcMirror( aLeft, aRight );
4705 						}
4706 						basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) );
4707                         SdrObject::Free( pRet );
4708 
4709 						pRet = new SdrEdgeObj();
4710 						ApplyAttributes( rSt, aSet, aObjData );
4711 						pRet->SetLogicRect( aObjData.aBoundRect );
4712 						pRet->SetMergedItemSet(aSet);
4713 
4714 						// Konnektoren
4715 						MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight );
4716 
4717 						((SdrEdgeObj*)pRet)->ConnectToNode(sal_True, NULL);
4718 						((SdrEdgeObj*)pRet)->ConnectToNode(sal_False, NULL);
4719 
4720 						Point aPoint1( aObjData.aBoundRect.TopLeft() );
4721 						Point aPoint2( aObjData.aBoundRect.BottomRight() );
4722 
4723 						// Rotationen beachten
4724 						if ( nObjectRotation )
4725 						{
4726 							double a = nObjectRotation * nPi180;
4727 							Point aCenter( aObjData.aBoundRect.Center() );
4728 							double ss = sin(a);
4729 							double cc = cos(a);
4730 
4731 							RotatePoint(aPoint1, aCenter, ss, cc);
4732 							RotatePoint(aPoint2, aCenter, ss, cc);
4733 						}
4734 
4735 						// Linie innerhalb des Bereiches zurechtdrehen/spiegeln
4736 						if ( nSpFlags & SP_FFLIPH )
4737 						{
4738 							sal_Int32 n = aPoint1.X();
4739 							aPoint1.X() = aPoint2.X();
4740 							aPoint2.X() = n;
4741 						}
4742 						if ( nSpFlags & SP_FFLIPV )
4743 						{
4744 							sal_Int32 n = aPoint1.Y();
4745 							aPoint1.Y() = aPoint2.Y();
4746 							aPoint2.Y() = n;
4747 						}
4748 						nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH );
4749 
4750 						pRet->NbcSetPoint(aPoint1, 0L);	// Startpunkt
4751 						pRet->NbcSetPoint(aPoint2, 1L);	// Endpunkt
4752 
4753 						sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist;
4754 						n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0;
4755 						switch( eConnectorStyle )
4756 						{
4757 							case mso_cxstyleBent:
4758 							{
4759 								aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) );
4760 								n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630;
4761 							}
4762 							break;
4763 							case mso_cxstyleCurved:
4764 								aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) );
4765 							break;
4766 							default: // mso_cxstyleStraight || mso_cxstyleNone
4767 								aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) );
4768 							break;
4769 						}
4770 						aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) );
4771 						aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) );
4772 						aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) );
4773 						aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) );
4774 
4775 						((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly );
4776 						pRet->SetMergedItemSet( aSet );
4777 					}
4778 				}
4779 			}
4780 
4781 			if ( pRet )
4782 			{
4783 				if( nObjectRotation )
4784 				{
4785 					double a = nObjectRotation * nPi180;
4786 					pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
4787 				}
4788 				// Horizontal gespiegelt?
4789 				if ( nSpFlags & SP_FFLIPH )
4790 				{
4791 					Rectangle aBndRect( pRet->GetSnapRect() );
4792 					Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
4793 					Point aBottom( aTop.X(), aTop.Y() + 1000 );
4794 					pRet->NbcMirror( aTop, aBottom );
4795 				}
4796 				// Vertikal gespiegelt?
4797 				if ( nSpFlags & SP_FFLIPV )
4798 				{
4799 					Rectangle aBndRect( pRet->GetSnapRect() );
4800 					Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
4801 					Point aRight( aLeft.X() + 1000, aLeft.Y() );
4802 					pRet->NbcMirror( aLeft, aRight );
4803 				}
4804 			}
4805 		}
4806 	}
4807 
4808     // #i51348# #118052# name of the shape
4809     if( pRet )
4810     {
4811         ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt );
4812         if( aObjName.getLength() > 0 )
4813             pRet->SetName( aObjName );
4814     }
4815 
4816 	pRet =
4817 		ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet);
4818 
4819 	if ( pRet )
4820 	{
4821 		sal_Int32 nGroupProperties( GetPropertyValue( DFF_Prop_fPrint ) );
4822 		pRet->SetVisible( ( nGroupProperties & 2 ) == 0 );
4823 		pRet->SetPrintable( ( nGroupProperties & 1 ) != 0 );
4824 	}
4825 
4826 	if ( mbTracing )
4827 		mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP
4828 									? rtl::OUString::createFromAscii( "GroupShape" )
4829 									: rtl::OUString::createFromAscii( "Shape" ) );
4830     //Import alt text as description
4831 	if ( pRet && SeekToContent( DFF_Prop_wzDescription, rSt ) )
4832 	{
4833 		String aAltText;
4834 		MSDFFReadZString( rSt, aAltText, GetPropertyValue( DFF_Prop_wzDescription ), sal_True );
4835 		pRet->SetDescription( aAltText );
4836 	}
4837 
4838 	return pRet;
4839 }
4840 
4841 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect )
4842 {
4843 	Rectangle aChildAnchor;
4844 	rHd.SeekToContent( rSt );
4845 	while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4846 	{
4847 		DffRecordHeader aShapeHd;
4848 		rSt >> aShapeHd;
4849 		if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
4850 				( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
4851 		{
4852 			DffRecordHeader aShapeHd2( aShapeHd );
4853 			if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
4854 				rSt >> aShapeHd2;
4855 			while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
4856 			{
4857 				DffRecordHeader aShapeAtom;
4858 				rSt >> aShapeAtom;
4859 
4860 				if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor )
4861 				{
4862 					if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT )
4863 					{
4864 						sal_Int32 l, t, r, b;
4865 						if ( aShapeAtom.nRecLen == 16 )
4866 						{
4867 							rSt >> l >> t >> r >> b;
4868 						}
4869 						else
4870 						{
4871 							sal_Int16 ls, ts, rs, bs;
4872 							rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ...
4873 							l = ls, t = ts, r = rs, b = bs;
4874 						}
4875 						Scale( l );
4876 						Scale( t );
4877 						Scale( r );
4878 						Scale( b );
4879 						aClientRect = Rectangle( l, t, r, b );
4880 					}
4881 					break;
4882 				}
4883 				else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
4884 				{
4885 					sal_Int32 l, o, r, u;
4886 					rSt >> l >> o >> r >> u;
4887 					Scale( l );
4888 					Scale( o );
4889 					Scale( r );
4890 					Scale( u );
4891 					Rectangle aChild( l, o, r, u );
4892 					aChildAnchor.Union( aChild );
4893 					break;
4894 				}
4895 				aShapeAtom.SeekToEndOfRecord( rSt );
4896 			}
4897 		}
4898 		aShapeHd.SeekToEndOfRecord( rSt );
4899 	}
4900 	return aChildAnchor;
4901 }
4902 
4903 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt,
4904 							Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor,
4905 								const Rectangle& rClientRect, const Rectangle& rGlobalChildRect )
4906 {
4907 	sal_Bool bFirst = sal_True;
4908 	rHd.SeekToContent( rSt );
4909 	DffRecordHeader aShapeHd;
4910 	while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4911 	{
4912 		rSt >> aShapeHd;
4913 		if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
4914 				( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
4915 		{
4916 			DffRecordHeader aShapeHd2( aShapeHd );
4917 			if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
4918 				rSt >> aShapeHd2;
4919 			while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
4920 			{
4921 				DffRecordHeader aShapeAtom;
4922 				rSt >> aShapeAtom;
4923 				if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
4924 				{
4925 					sal_Int32 l, o, r, u;
4926 					rSt >> l >> o >> r >> u;
4927 					Scale( l );
4928 					Scale( o );
4929 					Scale( r );
4930 					Scale( u );
4931 					Rectangle aChild( l, o, r, u );
4932 
4933 					if ( bFirst )
4934 					{
4935 						if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
4936 						{
4937 							double fl = l;
4938 							double fo = o;
4939 							double fWidth = r - l;
4940 							double fHeight= u - o;
4941 							double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
4942 							double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
4943 							fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
4944 							fo = ( ( o - rGlobalChildRect.Top()  ) * fYScale ) + rClientRect.Top();
4945 							fWidth *= fXScale;
4946 							fHeight *= fYScale;
4947 							rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
4948 						}
4949 						bFirst = sal_False;
4950 					}
4951 					else
4952 						rGroupChildAnchor.Union( aChild );
4953 					break;
4954 				}
4955 				aShapeAtom.SeekToEndOfRecord( rSt );
4956 			}
4957 		}
4958 		aShapeHd.SeekToEndOfRecord( rSt );
4959 	}
4960 }
4961 
4962 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt,
4963 									   DffObjData& rObjData,
4964 									   void* pData,
4965 									   Rectangle& rTextRect,
4966 									   SdrObject* pObj
4967 									   )
4968 {
4969 	if( !rTextRect.IsEmpty() )
4970 	{
4971 		SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
4972 		SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
4973 		SvxMSDffImportRec* pTextImpRec = pImpRec;
4974 
4975 		// fill Import Record with data
4976 		pImpRec->nShapeId   = rObjData.nShapeId;
4977 		pImpRec->eShapeType = rObjData.eShapeType;
4978 
4979 		MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue(
4980 															DFF_Prop_WrapText,
4981 															mso_wrapSquare ) );
4982 		rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
4983 											DFF_msofbtClientAnchor,
4984 											SEEK_FROM_CURRENT_AND_RESTART );
4985 		if( rObjData.bClientAnchor )
4986 			ProcessClientAnchor( rSt,
4987 					maShapeRecords.Current()->nRecLen,
4988 					pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
4989 
4990 		rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
4991 											DFF_msofbtClientData,
4992 											SEEK_FROM_CURRENT_AND_RESTART );
4993 		if( rObjData.bClientData )
4994 			ProcessClientData( rSt,
4995 					maShapeRecords.Current()->nRecLen,
4996 					pImpRec->pClientDataBuffer, pImpRec->nClientDataLen );
4997 
4998 
4999 		// process user (== Winword) defined parameters in 0xF122 record
5000 		if(    maShapeRecords.SeekToContent( rSt,
5001 											 DFF_msofbtUDefProp,
5002 											 SEEK_FROM_CURRENT_AND_RESTART )
5003 			&& maShapeRecords.Current()->nRecLen )
5004 		{
5005 			sal_uInt32  nBytesLeft = maShapeRecords.Current()->nRecLen;
5006 			sal_uInt32	nUDData;
5007 			sal_uInt16  nPID;
5008 			while( 5 < nBytesLeft )
5009 			{
5010 				rSt >> nPID;
5011 				if ( rSt.GetError() != 0 )
5012 					break;
5013 				rSt >> nUDData;
5014 				switch( nPID )
5015 				{
5016 					case 0x038F: pImpRec->nXAlign = nUDData; break;
5017 					case 0x0390: pImpRec->nXRelTo = nUDData; break;
5018 					case 0x0391: pImpRec->nYAlign = nUDData; break;
5019 					case 0x0392: pImpRec->nYRelTo = nUDData; break;
5020                     case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break;
5021 				}
5022 				if ( rSt.GetError() != 0 )
5023 					break;
5024 				pImpRec->bHasUDefProp = sal_True;
5025 				nBytesLeft  -= 6;
5026 			}
5027 		}
5028 
5029 		//  Textrahmen, auch Title oder Outline
5030 		SdrObject*  pOrgObj  = pObj;
5031 		SdrRectObj* pTextObj = 0;
5032 		sal_uInt32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
5033 		if( nTextId )
5034 		{
5035 			SfxItemSet aSet( pSdrModel->GetItemPool() );
5036 
5037             //Originally anything that as a mso_sptTextBox was created as a
5038             //textbox, this was changed for #88277# to be created as a simple
5039             //rect to keep impress happy. For the rest of us we'd like to turn
5040             //it back into a textbox again.
5041             FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox);
5042             if (!bTextFrame)
5043             {
5044                 //Either
5045                 //a) its a simple text object or
5046                 //b) its a rectangle with text and square wrapping.
5047                 bTextFrame =
5048                 (
5049                     (pImpRec->eShapeType == mso_sptTextSimple) ||
5050                     (
5051                         (pImpRec->eShapeType == mso_sptRectangle)
5052                         && (eWrapMode == mso_wrapSquare)
5053                         && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
5054                     )
5055                 );
5056             }
5057 
5058             if (bTextFrame)
5059             {
5060                 SdrObject::Free( pObj );
5061                 pObj = pOrgObj = 0;
5062             }
5063 
5064             // Distance of Textbox to it's surrounding Customshape
5065 			sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
5066 			sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
5067 			sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L  );
5068 			sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
5069 
5070 			ScaleEmu( nTextLeft );
5071 			ScaleEmu( nTextRight );
5072 			ScaleEmu( nTextTop );
5073 			ScaleEmu( nTextBottom );
5074 
5075             sal_Int32 nTextRotationAngle=0;
5076             bool bVerticalText = false;
5077             if ( IsProperty( DFF_Prop_txflTextFlow ) )
5078             {
5079                 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue(
5080                     DFF_Prop_txflTextFlow) & 0xFFFF);
5081                 switch( eTextFlow )
5082                 {
5083                     case mso_txflBtoT:
5084                         nTextRotationAngle = 9000;
5085                     break;
5086                     case mso_txflVertN:
5087                     case mso_txflTtoBN:
5088                         nTextRotationAngle = 27000;
5089                         break;
5090                     case mso_txflTtoBA:
5091                         bVerticalText = true;
5092                     break;
5093                     case mso_txflHorzA:
5094                         bVerticalText = true;
5095                         nTextRotationAngle = 9000;
5096                     case mso_txflHorzN:
5097                     default :
5098                         break;
5099                 }
5100             }
5101 
5102             if (nTextRotationAngle)
5103 			{
5104                 while (nTextRotationAngle > 360000)
5105                     nTextRotationAngle-=9000;
5106                 switch (nTextRotationAngle)
5107                 {
5108                     case 9000:
5109                         {
5110                             long nWidth = rTextRect.GetWidth();
5111                             rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5112                             rTextRect.Bottom() = rTextRect.Top() + nWidth;
5113 
5114                             sal_Int32 nOldTextLeft = nTextLeft;
5115                             sal_Int32 nOldTextRight = nTextRight;
5116                             sal_Int32 nOldTextTop = nTextTop;
5117                             sal_Int32 nOldTextBottom = nTextBottom;
5118 
5119                             nTextLeft = nOldTextBottom;
5120                             nTextRight = nOldTextTop;
5121                             nTextTop = nOldTextLeft;
5122                             nTextBottom = nOldTextRight;
5123                         }
5124                         break;
5125                     case 27000:
5126                         {
5127                             long nWidth = rTextRect.GetWidth();
5128                             rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5129                             rTextRect.Bottom() = rTextRect.Top() + nWidth;
5130 
5131                             sal_Int32 nOldTextLeft = nTextLeft;
5132                             sal_Int32 nOldTextRight = nTextRight;
5133                             sal_Int32 nOldTextTop = nTextTop;
5134                             sal_Int32 nOldTextBottom = nTextBottom;
5135 
5136                             nTextLeft = nOldTextTop;
5137                             nTextRight = nOldTextBottom;
5138                             nTextTop = nOldTextRight;
5139                             nTextBottom = nOldTextLeft;
5140                         }
5141                         break;
5142                     default:
5143                         break;
5144                 }
5145 			}
5146 
5147             pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect);
5148             pTextImpRec = new SvxMSDffImportRec(*pImpRec);
5149 
5150             // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
5151             // hier rausrechnen
5152             Rectangle aNewRect(rTextRect);
5153 			aNewRect.Bottom() -= nTextTop + nTextBottom;
5154             aNewRect.Right() -= nTextLeft + nTextRight;
5155 
5156 			// Nur falls es eine einfache Textbox ist, darf der Writer
5157 			// das Objekt durch einen Rahmen ersetzen, ansonsten
5158 			if( bTextFrame )
5159 			{
5160 				SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId );
5161 				aTmpRec.bSortByShapeId = sal_True;
5162 
5163 				sal_uInt16 nFound;
5164 				if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) )
5165 				{
5166 					SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound);
5167 					pTextImpRec->bReplaceByFly   = rInfo.bReplaceByFly;
5168 					pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain;
5169 				}
5170 			}
5171 
5172 			if( !pObj )
5173 				ApplyAttributes( rSt, aSet, rObjData );
5174 
5175             bool bFitText = false;
5176             if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2)
5177             {
5178                 aSet.Put( SdrTextAutoGrowHeightItem( sal_True ) );
5179                 aSet.Put( SdrTextMinFrameHeightItem(
5180                     aNewRect.Bottom() - aNewRect.Top() ) );
5181                 aSet.Put( SdrTextMinFrameWidthItem(
5182                     aNewRect.Right() - aNewRect.Left() ) );
5183                 bFitText = true;
5184             }
5185             else
5186             {
5187                 aSet.Put( SdrTextAutoGrowHeightItem( sal_False ) );
5188                 aSet.Put( SdrTextAutoGrowWidthItem( sal_False ) );
5189             }
5190 
5191 			switch ( (MSO_WrapMode)
5192                 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) )
5193 			{
5194 				case mso_wrapNone :
5195     				aSet.Put( SdrTextAutoGrowWidthItem( sal_True ) );
5196                     if (bFitText)
5197                     {
5198                         //can't do autowidth in flys #i107184#
5199 					    pTextImpRec->bReplaceByFly = false;
5200                     }
5201 				break;
5202 				case mso_wrapByPoints :
5203 					aSet.Put( SdrTextContourFrameItem( sal_True ) );
5204 				break;
5205 				default: break;
5206 			}
5207 
5208 			// Abstaende an den Raendern der Textbox setzen
5209 			aSet.Put( SdrTextLeftDistItem( nTextLeft ) );
5210 			aSet.Put( SdrTextRightDistItem( nTextRight ) );
5211 			aSet.Put( SdrTextUpperDistItem( nTextTop ) );
5212 			aSet.Put( SdrTextLowerDistItem( nTextBottom ) );
5213 			pTextImpRec->nDxTextLeft	= nTextLeft;
5214 			pTextImpRec->nDyTextTop		= nTextTop;
5215 			pTextImpRec->nDxTextRight	= nTextRight;
5216 			pTextImpRec->nDyTextBottom	= nTextBottom;
5217 
5218 			// Textverankerung lesen
5219 			if ( IsProperty( DFF_Prop_anchorText ) )
5220 			{
5221 				MSO_Anchor eTextAnchor =
5222                     (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText );
5223 
5224 				SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER;
5225 				sal_Bool bTVASet(sal_False);
5226 				SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER;
5227 				sal_Bool bTHASet(sal_False);
5228 
5229 				switch( eTextAnchor )
5230 				{
5231 					case mso_anchorTop:
5232 					{
5233 						eTVA = SDRTEXTVERTADJUST_TOP;
5234 						bTVASet = sal_True;
5235 					}
5236 					break;
5237 					case mso_anchorTopCentered:
5238 					{
5239 						eTVA = SDRTEXTVERTADJUST_TOP;
5240 						bTVASet = sal_True;
5241 						bTHASet = sal_True;
5242 					}
5243 					break;
5244 
5245 					case mso_anchorMiddle:
5246 						bTVASet = sal_True;
5247 					break;
5248 					case mso_anchorMiddleCentered:
5249 					{
5250 						bTVASet = sal_True;
5251 						bTHASet = sal_True;
5252 					}
5253 					break;
5254 					case mso_anchorBottom:
5255 					{
5256 						eTVA = SDRTEXTVERTADJUST_BOTTOM;
5257 						bTVASet = sal_True;
5258 					}
5259 					break;
5260 					case mso_anchorBottomCentered:
5261 					{
5262 						eTVA = SDRTEXTVERTADJUST_BOTTOM;
5263 						bTVASet = sal_True;
5264 						bTHASet = sal_True;
5265 					}
5266 					break;
5267 	/*
5268 					case mso_anchorTopBaseline:
5269 					case mso_anchorBottomBaseline:
5270 					case mso_anchorTopCenteredBaseline:
5271 					case mso_anchorBottomCenteredBaseline:
5272 					break;
5273 	*/
5274 					default : break;
5275 				}
5276 				// Einsetzen
5277 				if ( bTVASet )
5278 					aSet.Put( SdrTextVertAdjustItem( eTVA ) );
5279 				if ( bTHASet )
5280 					aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
5281 			}
5282 
5283 			pTextObj->SetMergedItemSet(aSet);
5284             pTextObj->SetModel(pSdrModel);
5285 
5286             if (bVerticalText)
5287                 pTextObj->SetVerticalWriting(sal_True);
5288 
5289             if (nTextRotationAngle)
5290 			{
5291                 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ?
5292                     rTextRect.GetWidth() : rTextRect.GetHeight();
5293                 nMinWH /= 2;
5294                 Point aPivot(rTextRect.TopLeft());
5295                 aPivot.X() += nMinWH;
5296                 aPivot.Y() += nMinWH;
5297 				double a = nTextRotationAngle * nPi180;
5298 				pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a));
5299 			}
5300 
5301 			// rotate text with shape ?
5302 			if ( mnFix16Angle )
5303 			{
5304 				double a = mnFix16Angle * nPi180;
5305 				pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle,
5306                     sin( a ), cos( a ) );
5307 			}
5308 
5309 			if( !pObj )
5310 			{
5311 				pObj = pTextObj;
5312 			}
5313 			else
5314 			{
5315 				if( pTextObj != pObj )
5316 				{
5317 					SdrObject* pGroup = new SdrObjGroup;
5318 					pGroup->GetSubList()->NbcInsertObject( pObj );
5319 					pGroup->GetSubList()->NbcInsertObject( pTextObj );
5320                     if (pOrgObj == pObj)
5321                         pOrgObj = pGroup;
5322                     else
5323 					    pOrgObj = pObj;
5324                     pObj = pGroup;
5325 				}
5326 			}
5327 		}
5328 		else if( !pObj )
5329 		{
5330 			// simple rectangular objects are ignored by ImportObj()  :-(
5331 			// this is OK for Draw but not for Calc and Writer
5332 			// cause here these objects have a default border
5333 			pObj = new SdrRectObj(rTextRect);
5334 			pOrgObj = pObj;
5335 			pObj->SetModel( pSdrModel );
5336             SfxItemSet aSet( pSdrModel->GetItemPool() );
5337 			ApplyAttributes( rSt, aSet, rObjData );
5338 
5339 			const SfxPoolItem* pPoolItem=NULL;
5340 			SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
5341 													 sal_False, &pPoolItem );
5342 			if( SFX_ITEM_DEFAULT == eState )
5343 				aSet.Put( XFillColorItem( String(),
5344 						  Color( mnDefaultColor ) ) );
5345 			pObj->SetMergedItemSet(aSet);
5346 		}
5347 
5348         //Means that fBehindDocument is set
5349         if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
5350 		    pImpRec->bDrawHell = sal_True;
5351         else
5352 		    pImpRec->bDrawHell = sal_False;
5353         if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
5354             pImpRec->bHidden = sal_True;
5355 		pTextImpRec->bDrawHell	= pImpRec->bDrawHell;
5356 		pTextImpRec->bHidden = pImpRec->bHidden;
5357 		pImpRec->nNextShapeId	= GetPropertyValue( DFF_Prop_hspNext, 0 );
5358 		pTextImpRec->nNextShapeId=pImpRec->nNextShapeId;
5359 
5360 		if ( nTextId )
5361 		{
5362 			pTextImpRec->aTextId.nTxBxS = (sal_uInt16)( nTextId >> 16 );
5363 			pTextImpRec->aTextId.nSequence = (sal_uInt16)nTextId;
5364 		}
5365 
5366 		pTextImpRec->nDxWrapDistLeft = GetPropertyValue(
5367 									DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
5368 		pTextImpRec->nDyWrapDistTop = GetPropertyValue(
5369 									DFF_Prop_dyWrapDistTop, 0 ) / 635L;
5370 		pTextImpRec->nDxWrapDistRight = GetPropertyValue(
5371 									DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
5372 		pTextImpRec->nDyWrapDistBottom = GetPropertyValue(
5373 									DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
5374         // 16.16 fraction times total image width or height, as appropriate.
5375 
5376         if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt))
5377         {
5378             delete pTextImpRec->pWrapPolygon;
5379             sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
5380             rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
5381             if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
5382             {
5383                 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert);
5384                 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
5385                 {
5386                     sal_Int32 nX, nY;
5387                     if (nElemSizeVert == 8)
5388                         rSt >> nX >> nY;
5389                     else
5390                     {
5391                         sal_Int16 nSmallX, nSmallY;
5392                         rSt >> nSmallX >> nSmallY;
5393                         nX = nSmallX;
5394                         nY = nSmallY;
5395                     }
5396                     (*(pTextImpRec->pWrapPolygon))[i].X() = nX;
5397                     (*(pTextImpRec->pWrapPolygon))[i].Y() = nY;
5398                 }
5399             }
5400         }
5401 
5402 		pImpRec->nCropFromTop = GetPropertyValue(
5403 									DFF_Prop_cropFromTop, 0 );
5404 		pImpRec->nCropFromBottom = GetPropertyValue(
5405 									DFF_Prop_cropFromBottom, 0 );
5406 		pImpRec->nCropFromLeft = GetPropertyValue(
5407 									DFF_Prop_cropFromLeft, 0 );
5408 		pImpRec->nCropFromRight = GetPropertyValue(
5409 									DFF_Prop_cropFromRight, 0 );
5410 
5411         pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false;
5412         pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false;
5413 
5414 		sal_uInt32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
5415 		pImpRec->eLineStyle = (nLineFlags & 8)
5416 							? (MSO_LineStyle)GetPropertyValue(
5417 												DFF_Prop_lineStyle,
5418 												mso_lineSimple )
5419 							: (MSO_LineStyle)USHRT_MAX;
5420 		pTextImpRec->eLineStyle = pImpRec->eLineStyle;
5421 
5422 		if( pImpRec->nShapeId )
5423 		{
5424 			// Import-Record-Liste ergaenzen
5425 			if( pOrgObj )
5426 			{
5427 				pImpRec->pObj = pOrgObj;
5428 				rImportData.aRecords.Insert( pImpRec );
5429 			}
5430 
5431 			if( pTextObj && (pOrgObj != pTextObj) )
5432 			{
5433 				// Modify ShapeId (must be unique)
5434 				pImpRec->nShapeId |= 0x8000000;
5435 				pTextImpRec->pObj = pTextObj;
5436 				rImportData.aRecords.Insert( pTextImpRec );
5437 			}
5438 
5439 			// Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen
5440 			/*Only store objects which are not deep inside the tree*/
5441 			if( ( rObjData.nCalledByGroup == 0 )
5442 				||
5443 				( (rObjData.nSpFlags & SP_FGROUP)
5444 				 && (rObjData.nCalledByGroup < 2) )
5445 			  )
5446 				StoreShapeOrder( pImpRec->nShapeId,
5447 								( ( (sal_uLong)pImpRec->aTextId.nTxBxS ) << 16 )
5448 									+ pImpRec->aTextId.nSequence, pObj );
5449 		}
5450 		else
5451 			delete pImpRec;
5452 	}
5453 
5454 	return pObj;
5455 };
5456 
5457 void SvxMSDffManager::StoreShapeOrder(sal_uLong			nId,
5458 									  sal_uLong			nTxBx,
5459 									  SdrObject*	pObject,
5460 									  SwFlyFrmFmt*	pFly,
5461 									  short			nHdFtSection) const
5462 {
5463 	sal_uInt16 nShpCnt = pShapeOrders->Count();
5464 	for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5465 	{
5466 		SvxMSDffShapeOrder& rOrder
5467 			= *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5468 
5469 		if( rOrder.nShapeId == nId )
5470 		{
5471 			rOrder.nTxBxComp = nTxBx;
5472 			rOrder.pObj      = pObject;
5473 			rOrder.pFly      = pFly;
5474 			rOrder.nHdFtSection = nHdFtSection;
5475 		}
5476 	}
5477 }
5478 
5479 
5480 void SvxMSDffManager::ExchangeInShapeOrder(	SdrObject*   pOldObject,
5481 											sal_uLong        nTxBx,
5482 											SwFlyFrmFmt* pFly,
5483 											SdrObject*   pObject) const
5484 {
5485 	sal_uInt16 nShpCnt = pShapeOrders->Count();
5486 	for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5487 	{
5488 		SvxMSDffShapeOrder& rOrder
5489 			= *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5490 
5491 		if( rOrder.pObj == pOldObject )
5492 		{
5493 			rOrder.pFly      = pFly;
5494 			rOrder.pObj      = pObject;
5495 			rOrder.nTxBxComp = nTxBx;
5496 		}
5497 	}
5498 }
5499 
5500 
5501 void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const
5502 {
5503 	sal_uInt16 nShpCnt = pShapeOrders->Count();
5504 	for (sal_uInt16 nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5505 	{
5506 		SvxMSDffShapeOrder& rOrder
5507 			= *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5508 
5509 		if( rOrder.pObj == pObject )
5510 		{
5511 			rOrder.pObj      = 0;
5512 			rOrder.pFly      = 0;
5513 			rOrder.nTxBxComp = 0;
5514 		}
5515 	}
5516 }
5517 
5518 
5519 
5520 
5521 //---------------------------------------------------------------------------
5522 //  Hilfs Deklarationen
5523 //---------------------------------------------------------------------------
5524 
5525 /*struct SvxMSDffBLIPInfo                       -> in's Header-File
5526 {
5527 	sal_uInt16 nBLIPType;       // Art des BLIP: z.B. 6 fuer PNG
5528 	sal_uLong  nFilePos;        // Offset des BLIP im Daten-Stream
5529 	sal_uLong  nBLIPSize;       // Anzahl Bytes, die der BLIP im Stream einnimmt
5530 	SvxMSDffBLIPInfo(sal_uInt16 nBType, sal_uLong nFPos, sal_uLong nBSize):
5531 		nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){}
5532 };
5533 */
5534 
5535 SV_IMPL_PTRARR(			SvxMSDffBLIPInfos,		SvxMSDffBLIPInfo_Ptr	);
5536 
5537 SV_IMPL_PTRARR(			SvxMSDffShapeOrders,	SvxMSDffShapeOrder_Ptr	);
5538 
5539 SV_IMPL_OP_PTRARR_SORT(	SvxMSDffShapeInfos,		SvxMSDffShapeInfo_Ptr	);
5540 
5541 SV_IMPL_OP_PTRARR_SORT(	SvxMSDffShapeTxBxSort,	SvxMSDffShapeOrder_Ptr	);
5542 
5543 
5544 // Liste aller SvxMSDffImportRec fuer eine Gruppe
5545 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr)
5546 
5547 //---------------------------------------------------------------------------
5548 //  exportierte Klasse: oeffentliche Methoden
5549 //---------------------------------------------------------------------------
5550 
5551 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_,
5552                                  const String& rBaseURL,
5553 								 long      nOffsDgg_,
5554 								 SvStream* pStData_,
5555 								 SdrModel* pSdrModel_,// s. unten: SetModel()
5556 								 long      nApplicationScale,
5557 								 ColorData mnDefaultColor_,
5558 								 sal_uLong     nDefaultFontHeight_,
5559 								 SvStream* pStData2_,
5560 								 MSFilterTracer* pTracer )
5561 	:DffPropertyReader( *this ),
5562 	 pFormModel( NULL ),
5563 	 pBLIPInfos( new SvxMSDffBLIPInfos  ),
5564 	 pShapeInfos(  new SvxMSDffShapeInfos ),
5565 	 pShapeOrders( new SvxMSDffShapeOrders ),
5566 	 nDefaultFontHeight( nDefaultFontHeight_),
5567 	 nOffsDgg( nOffsDgg_ ),
5568 	 nBLIPCount(  USHRT_MAX ),				// mit Error initialisieren, da wir erst pruefen,
5569 	 nShapeCount( USHRT_MAX ),              // ob Kontroll-Stream korrekte Daten enthaellt
5570      maBaseURL( rBaseURL ),
5571 	 mpFidcls( NULL ),
5572 	 rStCtrl(  rStCtrl_  ),
5573 	 pStData(  pStData_  ),
5574 	 pStData2( pStData2_ ),
5575 	 nSvxMSDffSettings( 0 ),
5576 	 nSvxMSDffOLEConvFlags( 0 ),
5577 	 pSecPropSet( NULL ),
5578      pEscherBlipCache( NULL ),
5579 	 mnDefaultColor( mnDefaultColor_),
5580 	 mpTracer( pTracer ),
5581      mbTracing( sal_False )
5582 {
5583 	if ( mpTracer )
5584 	{
5585 		uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
5586 		aAny >>= mbTracing;
5587 	}
5588 	SetModel( pSdrModel_, nApplicationScale );
5589 
5590 	// FilePos des/der Stream(s) merken
5591 	sal_uLong nOldPosCtrl = rStCtrl.Tell();
5592 	sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
5593 
5594 	// Falls kein Datenstream angegeben, gehen wir davon aus,
5595 	// dass die BLIPs im Steuerstream stehen.
5596 	if( !pStData )
5597 		pStData = &rStCtrl;
5598 
5599 	SetDefaultPropSet( rStCtrl, nOffsDgg );
5600 
5601 	// Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
5602 	GetCtrlData( nOffsDgg );
5603 
5604 	// Text-Box-Story-Ketten-Infos ueberpruefen
5605 	CheckTxBxStoryChain();
5606 
5607 	// alte FilePos des/der Stream(s) restaurieren
5608 	rStCtrl.Seek( nOldPosCtrl );
5609 	if( &rStCtrl != pStData )
5610 		pStData->Seek( nOldPosData );
5611 }
5612 
5613 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer )
5614 	:DffPropertyReader( *this ),
5615 	 pFormModel( NULL ),
5616 	 pBLIPInfos(   new SvxMSDffBLIPInfos  ),
5617 	 pShapeInfos(  new SvxMSDffShapeInfos ),
5618 	 pShapeOrders( new SvxMSDffShapeOrders ),
5619 	 nDefaultFontHeight( 24 ),
5620 	 nOffsDgg( 0 ),
5621 	 nBLIPCount(  USHRT_MAX ),				// mit Error initialisieren, da wir erst pruefen,
5622 	 nShapeCount( USHRT_MAX ),              // ob Kontroll-Stream korrekte Daten enthaellt
5623      maBaseURL( rBaseURL ),
5624 	 mpFidcls( NULL ),
5625 	 rStCtrl(  rStCtrl_  ),
5626 	 pStData( 0 ),
5627 	 pStData2( 0 ),
5628 	 nSvxMSDffSettings( 0 ),
5629 	 nSvxMSDffOLEConvFlags( 0 ),
5630 	 pSecPropSet( NULL ),
5631      pEscherBlipCache( NULL ),
5632 	 mnDefaultColor( COL_DEFAULT ),
5633 	 mpTracer( pTracer ),
5634      mbTracing( sal_False )
5635 {
5636 	if ( mpTracer )
5637 	{
5638 		uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
5639 		aAny >>= mbTracing;
5640 	}
5641 	SetModel( NULL, 0 );
5642 }
5643 
5644 SvxMSDffManager::~SvxMSDffManager()
5645 {
5646     if ( pEscherBlipCache )
5647     {
5648         void* pPtr;
5649         for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() )
5650             delete (EscherBlipCacheEntry*)pPtr;
5651         delete pEscherBlipCache;
5652     }
5653 	delete pSecPropSet;
5654 	delete pBLIPInfos;
5655 	delete pShapeInfos;
5656 	delete pShapeOrders;
5657 	delete pFormModel;
5658 	delete[] mpFidcls;
5659 }
5660 
5661 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags )
5662 {
5663 	nOffsDgg = nOffsDgg_;
5664 	pStData = pStData_;
5665 	nSvxMSDffOLEConvFlags = nOleConvFlags;
5666 
5667 	// FilePos des/der Stream(s) merken
5668 	sal_uLong nOldPosCtrl = rStCtrl.Tell();
5669 
5670 	SetDefaultPropSet( rStCtrl, nOffsDgg );
5671 
5672 	// insert fidcl cluster table
5673 	GetFidclData( nOffsDgg );
5674 
5675 	// Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
5676 	GetCtrlData( nOffsDgg );
5677 
5678 	// Text-Box-Story-Ketten-Infos ueberpruefen
5679 	CheckTxBxStoryChain();
5680 
5681 	// alte FilePos des/der Stream(s) restaurieren
5682 	rStCtrl.Seek( nOldPosCtrl );
5683 }
5684 
5685 void SvxMSDffManager::SetDgContainer( SvStream& rSt )
5686 {
5687 	sal_uInt32 nFilePos = rSt.Tell();
5688 	DffRecordHeader aDgContHd;
5689 	rSt >> aDgContHd;
5690 	// insert this container only if there is also a DgAtom
5691 	if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) )
5692 	{
5693 		DffRecordHeader aRecHd;
5694 		rSt >> aRecHd;
5695 		sal_uInt32 nDrawingId = aRecHd.nRecInstance;
5696 		maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos );
5697 		rSt.Seek( nFilePos );
5698 	}
5699 }
5700 
5701 void SvxMSDffManager::GetFidclData( long nOffsDggL )
5702 {
5703 	if ( nOffsDggL )
5704 	{
5705 		sal_uInt32 nDummy, nMerk = rStCtrl.Tell();
5706 		rStCtrl.Seek( nOffsDggL );
5707 
5708 		DffRecordHeader aRecHd;
5709 		rStCtrl >> aRecHd;
5710 
5711 		DffRecordHeader aDggAtomHd;
5712 		if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) )
5713 		{
5714 			aDggAtomHd.SeekToContent( rStCtrl );
5715 			rStCtrl >> mnCurMaxShapeId
5716 					>> mnIdClusters
5717 					>> nDummy
5718 					>> mnDrawingsSaved;
5719 
5720 			if ( mnIdClusters-- > 2 )
5721 			{
5722 				if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) )
5723 				{
5724 					//mpFidcls = new FIDCL[ mnIdClusters ];
5725                     mpFidcls = new (std::nothrow) FIDCL[ mnIdClusters ];
5726                     if ( mpFidcls ) {
5727                         for ( sal_uInt32 i = 0; i < mnIdClusters; i++ )
5728                         {
5729                             rStCtrl >> mpFidcls[ i ].dgid
5730                                     >> mpFidcls[ i ].cspidCur;
5731                         }
5732                     }
5733 				}
5734 			}
5735 		}
5736 		rStCtrl.Seek( nMerk );
5737 	}
5738 }
5739 
5740 void SvxMSDffManager::CheckTxBxStoryChain()
5741 {
5742 	SvxMSDffShapeInfos* pOld = pShapeInfos;
5743 	sal_uInt16 nCnt				= pOld->Count();
5744 	pShapeInfos				= new SvxMSDffShapeInfos( (nCnt < 255)
5745 													 ? nCnt
5746 													 : 255 );
5747 	// altes Info-Array ueberarbeiten
5748 	// (ist sortiert nach nTxBxComp)
5749 	sal_uLong nChain    = ULONG_MAX;
5750 	sal_uInt16 nObjMark = 0;
5751 	sal_Bool bSetReplaceFALSE = sal_False;
5752 	sal_uInt16 nObj;
5753 	for( nObj = 0; nObj < nCnt; ++nObj )
5754 	{
5755 		SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj );
5756 		if( pObj->nTxBxComp )
5757 		{
5758 			pObj->bLastBoxInChain = sal_False;
5759 			// Gruppenwechsel ?
5760             // --> OD 2008-07-28 #156763#
5761             // the text id also contains an internal drawing container id
5762             // to distinguish between text id of drawing objects in different
5763             // drawing containers.
5764 //            if( nChain != (pObj->nTxBxComp & 0xFFFF0000) )
5765             if( nChain != pObj->nTxBxComp )
5766             // <--
5767             {
5768 				// voriger war letzter seiner Gruppe
5769 				if( nObj )
5770 					pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True;
5771 				// Merker und Hilfs-Flag zuruecksetzen
5772 				nObjMark = nObj;
5773                 // --> OD 2008-07-28 #156763#
5774 //                nChain   = pObj->nTxBxComp & 0xFFFF0000;
5775                 nChain = pObj->nTxBxComp;
5776                 // <--
5777 				bSetReplaceFALSE = !pObj->bReplaceByFly;
5778 			}
5779 			else
5780 			if( !pObj->bReplaceByFly )
5781 			{
5782 				// Objekt, das NICHT durch Rahmen ersetzt werden darf ?
5783 				// Hilfs-Flag setzen
5784 				bSetReplaceFALSE = sal_True;
5785 				// ggfs Flag in Anfang der Gruppe austragen
5786 				for( sal_uInt16 nObj2 = nObjMark; nObj2 < nObj; ++nObj2 )
5787 					pOld->GetObject( nObj2 )->bReplaceByFly = sal_False;
5788 			}
5789 
5790 			if( bSetReplaceFALSE )
5791 			{
5792 				pObj->bReplaceByFly = sal_False;
5793 			}
5794 		}
5795 		// alle Shape-Info-Objekte in pShapeInfos umkopieren
5796 		// (aber nach nShapeId sortieren)
5797 		pObj->bSortByShapeId = sal_True;
5798         // --> OD 2008-07-28 #156763#
5799         pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000;
5800         // <--
5801 		pShapeInfos->Insert( pObj );
5802 	}
5803 	// voriger war letzter seiner Gruppe
5804 	if( nObj )
5805 		pOld->GetObject( nObj-1 )->bLastBoxInChain = sal_True;
5806 	// urspruengliches Array freigeben, ohne Objekte zu zerstoeren
5807 	pOld->Remove((sal_uInt16)0, nCnt);
5808 	delete pOld;
5809 }
5810 
5811 
5812 /*****************************************************************************
5813 
5814 	Einlesen der Shape-Infos im Ctor:
5815 	---------------------------------
5816 	merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos
5817 			   =========                  ============	   =============
5818 	und merken des File-Offsets fuer jedes Blip
5819 				   ============
5820 ******************************************************************************/
5821 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ )
5822 {
5823 	// Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen
5824 	long nOffsDggL = nOffsDgg_;
5825 
5826 	// Kontroll Stream positionieren
5827 	rStCtrl.Seek( nOffsDggL );
5828 
5829 	sal_uInt8   nVer;
5830 	sal_uInt16 nInst;
5831 	sal_uInt16 nFbt;
5832 	sal_uInt32  nLength;
5833 	if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return;
5834 
5835 	sal_Bool bOk;
5836 	sal_uLong nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE;
5837 
5838 	// Fall A: erst Drawing Group Container, dann n Mal Drawing Container
5839 	if( DFF_msofbtDggContainer == nFbt )
5840 	{
5841         GetDrawingGroupContainerData( rStCtrl, nLength );
5842 
5843 		 rStCtrl.Seek( STREAM_SEEK_TO_END );
5844 		sal_uInt32 nMaxStrPos = rStCtrl.Tell();
5845 
5846 		nPos += nLength;
5847         // --> OD 2008-07-28 #156763#
5848         unsigned long nDrawingContainerId = 1;
5849         // <--
5850         do
5851 		{
5852 			rStCtrl.Seek( nPos );
5853 
5854 			bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt );
5855 
5856 			if( !bOk )
5857 			{
5858 				nPos++;				// ????????? TODO: trying to get an one-hit wonder, this code code should be rewritten...
5859 				rStCtrl.Seek( nPos );
5860 				bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength )
5861 						&& ( DFF_msofbtDgContainer == nFbt );
5862 			}
5863 			if( bOk )
5864             {
5865                 // --> OD 2008-07-28 #156763#
5866                 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId );
5867                 // <--
5868             }
5869 			nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
5870             // --> OD 2008-07-28 #156763#
5871             ++nDrawingContainerId;
5872             // <--
5873 		}
5874 		while( ( rStCtrl.GetError() == 0 ) && ( nPos < nMaxStrPos ) && bOk );
5875 	}
5876 }
5877 
5878 
5879 // ab hier: Drawing Group Container  d.h. Dokument - weit gueltige Daten
5880 //                      =======================           ========
5881 //
5882 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, sal_uLong nLenDgg )
5883 {
5884 	sal_uInt8   nVer;
5885 	sal_uInt16 nInst;
5886 	sal_uInt16 nFbt;
5887 	sal_uInt32 nLength;
5888 
5889 	sal_uLong nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0;
5890 
5891 	// Nach einem BStore Container suchen
5892 	do
5893 	{
5894 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
5895 		nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
5896 		if( DFF_msofbtBstoreContainer == nFbt )
5897 		{
5898 			nLenBStoreCont = nLength;       break;
5899 		}
5900 		rSt.SeekRel( nLength );
5901 	}
5902 	while( nRead < nLenDgg );
5903 
5904 	if( !nLenBStoreCont ) return;
5905 
5906 	// Im BStore Container alle Header der Container und Atome auslesen und die
5907 	// relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen.
5908 	// Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit.
5909 
5910 	const sal_uLong nSkipBLIPLen = 20;  // bis zu nBLIPLen zu ueberspringende Bytes
5911 	const sal_uLong nSkipBLIPPos =  4;  // dahinter bis zu nBLIPPos zu skippen
5912 
5913 	sal_uInt32 nBLIPLen = 0, nBLIPPos = 0;
5914 
5915 	nRead = 0;
5916 	do
5917 	{
5918 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
5919 		nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
5920 		if( DFF_msofbtBSE == nFbt )
5921 		{
5922 			nLenFBSE = nLength;
5923 			// ist FBSE gross genug fuer unsere Daten
5924 			sal_Bool bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE );
5925 
5926 			if( bOk )
5927 			{
5928 				rSt.SeekRel( nSkipBLIPLen );
5929 				rSt >> nBLIPLen;
5930 				rSt.SeekRel( nSkipBLIPPos );
5931 				rSt >> nBLIPPos;
5932 				bOk = rSt.GetError() == 0;
5933 
5934 				nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4;
5935 			}
5936 
5937 			if( bOk )
5938 			{
5939 				// Besonderheit:
5940 				// Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist,
5941 				// nehmen wir an, dass das Bild IM FBSE drin steht!
5942 				if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) )
5943 					nBLIPPos = rSt.Tell() + 4;
5944 
5945 				// Das hat ja fein geklappt!
5946 				// Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben.
5947 				nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell());
5948 
5949 				if( USHRT_MAX == nBLIPCount )
5950 					nBLIPCount = 1;
5951 				else
5952 					nBLIPCount++;
5953 
5954 				// Jetzt die Infos fuer spaetere Zugriffe speichern
5955 				pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ),
5956 														  pBLIPInfos->Count() );
5957 			}
5958 		}
5959 		rSt.SeekRel( nLength );
5960 	}
5961 	while( nRead < nLenBStoreCont );
5962 }
5963 
5964 
5965 // ab hier: Drawing Container  d.h. Seiten (Blatt, Dia) - weit gueltige Daten
5966 //                      =================               ======
5967 //
5968 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, sal_uLong nLenDg,
5969                                                const unsigned long nDrawingContainerId )
5970 {
5971 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
5972 
5973 	sal_uLong nReadDg = 0;
5974 
5975 	// Wir stehen in einem Drawing Container (je einer pro Seite)
5976 	// und muessen nun
5977 	// alle enthaltenen Shape Group Container abklappern
5978 	do
5979 	{
5980 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
5981 		nReadDg += DFF_COMMON_RECORD_HEADER_SIZE;
5982 		// Patriarch gefunden (der oberste Shape Group Container) ?
5983 		if( DFF_msofbtSpgrContainer == nFbt )
5984 		{
5985             if(!this->GetShapeGroupContainerData( rSt, nLength, sal_True, nDrawingContainerId )) return;
5986 		}
5987 		else
5988 		// blanker Shape Container ? (ausserhalb vom Shape Group Container)
5989 		if( DFF_msofbtSpContainer == nFbt )
5990 		{
5991             if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return;
5992 		}
5993 		else
5994 			rSt.SeekRel( nLength );
5995 		nReadDg += nLength;
5996 	}
5997 	while( nReadDg < nLenDg );
5998 }
5999 
6000 sal_Bool SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt,
6001 												  sal_uLong nLenShapeGroupCont,
6002                                                   sal_Bool bPatriarch,
6003                                                   const unsigned long nDrawingContainerId )
6004 {
6005 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
6006 	long nStartShapeGroupCont = rSt.Tell();
6007 	// Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite)
6008 	// und muessen nun
6009 	// alle enthaltenen Shape Container abklappern
6010 	sal_Bool  bFirst = !bPatriarch;
6011 	sal_uLong nReadSpGrCont = 0;
6012 	do
6013 	{
6014 		if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) )
6015 			return sal_False;
6016 		nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE;
6017 		// Shape Container ?
6018 		if( DFF_msofbtSpContainer == nFbt )
6019 		{
6020 			sal_uLong nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX;
6021             if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) )
6022 				return sal_False;
6023 			bFirst = sal_False;
6024 		}
6025 		else
6026 		// eingeschachtelter Shape Group Container ?
6027 		if( DFF_msofbtSpgrContainer == nFbt )
6028 		{
6029             if ( !this->GetShapeGroupContainerData( rSt, nLength, sal_False, nDrawingContainerId ) )
6030 				return sal_False;
6031 		}
6032 		else
6033 			rSt.SeekRel( nLength );
6034 		nReadSpGrCont += nLength;
6035 	}
6036 	while( nReadSpGrCont < nLenShapeGroupCont );
6037 	// den Stream wieder korrekt positionieren
6038 	rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont );
6039 	return sal_True;
6040 }
6041 
6042 sal_Bool SvxMSDffManager::GetShapeContainerData( SvStream& rSt,
6043                                              sal_uLong nLenShapeCont,
6044                                              sal_uLong nPosGroup,
6045                                              const unsigned long nDrawingContainerId )
6046 {
6047 	sal_uInt8 nVer;sal_uInt16 nInst;sal_uInt16 nFbt;sal_uInt32 nLength;
6048 	long  nStartShapeCont = rSt.Tell();
6049 	// Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group)
6050 	// und muessen nun
6051 	// die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe)
6052 	// und den ersten BStore Verweis (falls vorhanden) entnehmen
6053 	sal_uLong nLenShapePropTbl = 0;
6054 	sal_uLong nReadSpCont = 0;
6055 
6056 	// File Offset des Shape-Containers bzw. der Gruppe(!) vermerken
6057 	//
6058 	sal_uLong nStartOffs = (ULONG_MAX > nPosGroup) ?
6059 							nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE;
6060 	SvxMSDffShapeInfo aInfo( nStartOffs );
6061 
6062 	// duerfte das Shape durch einen Rahmen ersetzt werden ?
6063 	// (vorausgesetzt, es zeigt sich, dass es eine TextBox ist,
6064 	//  und der Text nicht gedreht ist)
6065 	sal_Bool bCanBeReplaced = (ULONG_MAX > nPosGroup) ? sal_False : sal_True;
6066 
6067 	// wir wissen noch nicht, ob es eine TextBox ist
6068 	MSO_SPT			eShapeType		= mso_sptNil;
6069 	MSO_WrapMode	eWrapMode		= mso_wrapSquare;
6070 //	sal_Bool			bIsTextBox		= sal_False;
6071 
6072 	// Shape analysieren
6073 	//
6074 	do
6075 	{
6076 		if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return sal_False;
6077 		nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE;
6078 		// FSP ?
6079 		if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) )
6080 		{
6081 			// Wir haben den FSP gefunden: Shape Typ und Id vermerken!
6082 			eShapeType = (MSO_SPT)nInst;
6083 			rSt >> aInfo.nShapeId;
6084 			rSt.SeekRel( nLength - 4 );
6085 			nReadSpCont += nLength;
6086 		}
6087 		else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ?
6088 		{
6089 			// Wir haben die Property Table gefunden:
6090 			// nach der Blip Property suchen!
6091 			sal_uLong  nPropRead = 0;
6092 			sal_uInt16 nPropId;
6093 			sal_uInt32  nPropVal;
6094 			nLenShapePropTbl = nLength;
6095 //			sal_uInt32 nPropCount = nInst;
6096 			long nStartShapePropTbl = rSt.Tell();
6097 //			sal_uInt32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6);
6098 			do
6099 			{
6100 				rSt >> nPropId
6101 					>> nPropVal;
6102 				nPropRead += 6;
6103 
6104 				switch( nPropId )
6105 				{
6106 					case DFF_Prop_txflTextFlow :
6107                         //Writer can now handle vertical textflows in its
6108                         //native frames, to only need to do this for the
6109                         //other two formats
6110 
6111                         //Writer will handle all textflow except BtoT
6112 						if (GetSvxMSDffSettings() &
6113                             (SVXMSDFF_SETTINGS_IMPORT_PPT |
6114                              SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6115                         {
6116                             if( 0 != nPropVal )
6117                                 bCanBeReplaced = false;
6118                         }
6119                         else if (
6120                             (nPropVal != mso_txflHorzN) &&
6121                             (nPropVal != mso_txflTtoBA)
6122                                 )
6123                         {
6124                             bCanBeReplaced = false;
6125                         }
6126 					break;
6127 					case DFF_Prop_cdirFont :
6128                         //Writer can now handle right to left and left
6129                         //to right in its native frames, so only do
6130                         //this for the other two formats.
6131 						if (GetSvxMSDffSettings() &
6132                             (SVXMSDFF_SETTINGS_IMPORT_PPT |
6133                              SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6134                         {
6135                             if( 0 != nPropVal )
6136                                 bCanBeReplaced = sal_False;
6137                         }
6138                     break;
6139 					case DFF_Prop_Rotation :
6140 						if( 0 != nPropVal )
6141 							bCanBeReplaced = sal_False;
6142 					break;
6143 
6144 					case DFF_Prop_gtextFStrikethrough :
6145 						if( ( 0x20002000 & nPropVal )  == 0x20002000 )
6146 							bCanBeReplaced = sal_False;
6147 					break;
6148 
6149 					case DFF_Prop_fc3DLightFace :
6150 						if( ( 0x00080008 & nPropVal ) == 0x00080008 )
6151 							bCanBeReplaced = sal_False;
6152 					break;
6153 
6154 					case DFF_Prop_WrapText :
6155 						eWrapMode = (MSO_WrapMode)nPropVal;
6156 					break;
6157 
6158 					default:
6159 					{
6160 						// Bit gesetzt und gueltig?
6161 						if( 0x4000 == ( nPropId & 0xC000 ) )
6162 						{
6163 							// Blip Property gefunden: BStore Idx vermerken!
6164 							nPropRead = nLenShapePropTbl;
6165 						}
6166 						else if( 0x8000 & nPropId )
6167 						{
6168 							// komplexe Prop gefunden:
6169 							// Laenge ist immer 6, nur die Laenge der nach der
6170 							// eigentlichen Prop-Table anhaengenden Extra-Daten
6171 							// ist unterschiedlich
6172 							nPropVal = 6;
6173 						}
6174 					}
6175 					break;
6176 				}
6177 
6178 /*
6179 //JP 21.04.99: Bug 64510
6180 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge
6181 // Performance einbussen hat.
6182 
6183 				if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig?
6184 				{
6185 					// Blip Property gefunden: BStore Idx vermerken!
6186 					aInfo.nBStoreIdx = nPropVal;    // Index im BStore Container
6187 					break;
6188 				}
6189 				else
6190 				if(    (    (    (DFF_Prop_txflTextFlow   == nPropId)
6191 							  || (DFF_Prop_Rotation       == nPropId)
6192 							  || (DFF_Prop_cdirFont       == nPropId) )
6193 						 && (0 != nPropVal) )
6194 
6195 					|| (    (DFF_Prop_gtextFStrikethrough == nPropId)
6196 						 && ( (0x20002000 & nPropVal)  == 0x20002000) ) // also DFF_Prop_gtextFVertical
6197 					|| (    (DFF_Prop_fc3DLightFace       == nPropId)
6198 						 && ( (0x00080008 & nPropVal)  == 0x00080008) )	// also DFF_Prop_f3D
6199 				  )
6200 				{
6201 					bCanBeReplaced = sal_False;  // Mist: gedrehter Text oder 3D-Objekt!
6202 				}
6203 				else
6204 				if( DFF_Prop_WrapText == nPropId )
6205 				{
6206 					eWrapMode = (MSO_WrapMode)nPropVal;
6207 				}
6208 				////////////////////////////////////////////////////////////////
6209 				////////////////////////////////////////////////////////////////
6210 				// keine weitere Property-Auswertung: folge beim Shape-Import //
6211 				////////////////////////////////////////////////////////////////
6212 				////////////////////////////////////////////////////////////////
6213 				else
6214 				if( 0x8000 & nPropId )
6215 				{
6216 					// komplexe Prop gefunden: Laenge lesen und ueberspringen
6217 					if(!SkipBytes( rSt, nPropVal )) return sal_False;
6218 					nPropRead += nPropVal;
6219 				}
6220 */
6221 			}
6222 			while( nPropRead < nLenShapePropTbl );
6223 			rSt.Seek( nStartShapePropTbl + nLenShapePropTbl );
6224 			nReadSpCont += nLenShapePropTbl;
6225 		}
6226 		else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) )	// Text-Box-Story-Eintrag gefunden
6227 		{
6228 			rSt >> aInfo.nTxBxComp;
6229             // --> OD 2008-07-28 #156763#
6230             // Add internal drawing container id to text id.
6231             // Note: The text id uses the first two bytes, while the internal
6232             // drawing container id used the second two bytes.
6233             aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) +
6234                               nDrawingContainerId;
6235             DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId,
6236                         "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." );
6237             // <--
6238 		}
6239 		else
6240 		{
6241 			rSt.SeekRel( nLength );
6242 			nReadSpCont += nLength;
6243 		}
6244 	}
6245 	while( nReadSpCont < nLenShapeCont );
6246 
6247 	//
6248 	// Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern
6249 	//
6250 	if( aInfo.nShapeId )
6251 	{
6252 		// fuer Textboxen ggfs. ersetzen durch Rahmen erlauben
6253 		if(     bCanBeReplaced
6254 			 && aInfo.nTxBxComp
6255 			 && (
6256 					( eShapeType == mso_sptTextSimple )
6257 				 || ( eShapeType == mso_sptTextBox    )
6258 				 || (    (    ( eShapeType == mso_sptRectangle      )
6259 						   || ( eShapeType == mso_sptRoundRectangle )
6260 						 )
6261 				) ) )
6262 		{
6263 			aInfo.bReplaceByFly = sal_True;
6264 		}
6265 		pShapeInfos->Insert(  new SvxMSDffShapeInfo(  aInfo          ) );
6266 		pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ),
6267 							  pShapeOrders->Count() );
6268 	}
6269 
6270 	// und den Stream wieder korrekt positionieren
6271 	rSt.Seek( nStartShapeCont + nLenShapeCont );
6272 	return sal_True;
6273 }
6274 
6275 
6276 
6277 /*****************************************************************************
6278 
6279 	Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id)
6280 	----------------------------------
6281 ******************************************************************************/
6282 sal_Bool SvxMSDffManager::GetShape(sal_uLong nId, SdrObject*&         rpShape,
6283 										  SvxMSDffImportData& rData)
6284 {
6285 	SvxMSDffShapeInfo aTmpRec(0, nId);
6286 	aTmpRec.bSortByShapeId = sal_True;
6287 
6288 	sal_uInt16 nFound;
6289 	if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) )
6290 	{
6291 		SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound );
6292 
6293 		// eventuell altes Errorflag loeschen
6294 		if( rStCtrl.GetError() )
6295 			rStCtrl.ResetError();
6296 		// FilePos des/der Stream(s) merken
6297 		sal_uLong nOldPosCtrl = rStCtrl.Tell();
6298 		sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6299 		// das Shape im Steuer Stream anspringen
6300 		rStCtrl.Seek( rInfo.nFilePos );
6301 
6302 		// Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt!
6303 		if( rStCtrl.GetError() )
6304 			rStCtrl.ResetError();
6305 		else
6306 			rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect );
6307 
6308 		// alte FilePos des/der Stream(s) restaurieren
6309 		rStCtrl.Seek( nOldPosCtrl );
6310 		if( &rStCtrl != pStData )
6311 			pStData->Seek( nOldPosData );
6312 		return ( 0 != rpShape );
6313 	}
6314 	return sal_False;
6315 }
6316 
6317 
6318 
6319 /*      Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr)
6320 	---------------------------------
6321 ******************************************************************************/
6322 sal_Bool SvxMSDffManager::GetBLIP( sal_uLong nIdx_, Graphic& rData, Rectangle* pVisArea ) const
6323 {
6324 	sal_Bool bOk = sal_False;       // Ergebnisvariable initialisieren
6325 	if ( pStData )
6326 	{
6327         // check if a graphic for this blipId is already imported
6328         if ( nIdx_ && pEscherBlipCache )
6329         {
6330             EscherBlipCacheEntry* pEntry;
6331             for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry;
6332                     pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() )
6333             {
6334                 if ( pEntry->nBlip == nIdx_ )
6335                 {	/* if this entry is available, then it should be possible
6336 					to get the Graphic via GraphicObject */
6337 					GraphicObject aGraphicObject( pEntry->aUniqueID );
6338                     rData = aGraphicObject.GetGraphic();
6339 					if ( rData.GetType() != GRAPHIC_NONE )
6340 	                    bOk = sal_True;
6341 					else
6342 						delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove();
6343 					break;
6344                 }
6345             }
6346         }
6347         if ( !bOk )
6348         {
6349 		    sal_uInt16 nIdx = sal_uInt16( nIdx_ );
6350 		    if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return sal_False;
6351 
6352 		    // eventuell alte(s) Errorflag(s) loeschen
6353 		    if( rStCtrl.GetError() )
6354 			    rStCtrl.ResetError();
6355 		    if(    ( &rStCtrl != pStData )
6356 			    && pStData->GetError() )
6357 			    pStData->ResetError();
6358 
6359 		    // FilePos des/der Stream(s) merken
6360 		    sal_uLong nOldPosCtrl = rStCtrl.Tell();
6361 		    sal_uLong nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6362 
6363 		    // passende Info-Struct aus unserem Pointer Array nehmen
6364 		    SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ];
6365 
6366 		    // das BLIP Atom im Daten Stream anspringen
6367 		    pStData->Seek( rInfo.nFilePos );
6368 		    // ggfs. Fehlerstatus zuruecksetzen
6369 		    if( pStData->GetError() )
6370 			    pStData->ResetError();
6371 		    else
6372 			    bOk = GetBLIPDirect( *pStData, rData, pVisArea );
6373 		    if( pStData2 && !bOk )
6374 		    {
6375 			    // Fehler, aber zweite Chance: es gibt noch einen zweiten
6376 			    //         Datenstream, in dem die Grafik liegen koennte!
6377 			    if( pStData2->GetError() )
6378 				    pStData2->ResetError();
6379 			    sal_uLong nOldPosData2 = pStData2->Tell();
6380 			    // das BLIP Atom im zweiten Daten Stream anspringen
6381 			    pStData2->Seek( rInfo.nFilePos );
6382 			    // ggfs. Fehlerstatus zuruecksetzen
6383 			    if( pStData2->GetError() )
6384 				    pStData2->ResetError();
6385 			    else
6386 				    bOk = GetBLIPDirect( *pStData2, rData, pVisArea );
6387 			    // alte FilePos des zweiten Daten-Stream restaurieren
6388 			    pStData2->Seek( nOldPosData2 );
6389 		    }
6390 		    // alte FilePos des/der Stream(s) restaurieren
6391 		    rStCtrl.Seek( nOldPosCtrl );
6392 		    if( &rStCtrl != pStData )
6393 		      pStData->Seek( nOldPosData );
6394 
6395             if ( bOk )
6396             {
6397                 // create new BlipCacheEntry for this graphic
6398 				GraphicObject aGraphicObject( rData );
6399                 if ( !pEscherBlipCache )
6400                     const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List();
6401                 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() );
6402                 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND );
6403             }
6404         }
6405 	}
6406 	return bOk;
6407 }
6408 
6409 /*      Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream)
6410 	---------------------------------
6411 ******************************************************************************/
6412 sal_Bool SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const
6413 {
6414 	sal_uLong nOldPos = rBLIPStream.Tell();
6415 
6416 	int nRes = GRFILTER_OPENERROR;  // Fehlervariable initialisieren
6417 
6418 	// nachschauen, ob es sich auch wirklich um ein BLIP handelt
6419 	sal_uInt32 nLength;
6420 	sal_uInt16 nInst, nFbt( 0 );
6421 	sal_uInt8   nVer;
6422 	if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) )
6423 	{
6424 		Size		aMtfSize100;
6425 		sal_Bool		bMtfBLIP = sal_False;
6426 		sal_Bool		bZCodecCompression = sal_False;
6427 		// Nun exakt auf den Beginn der eingebetteten Grafik positionieren
6428 		sal_uLong nSkip = ( nInst & 0x0001 ) ? 32 : 16;
6429 
6430 		switch( nInst & 0xFFFE )
6431 		{
6432 			case 0x216 :			// Metafile header then compressed WMF
6433 			case 0x3D4 :			// Metafile header then compressed EMF
6434 			case 0x542 :			// Metafile hd. then compressed PICT
6435 			{
6436 				rBLIPStream.SeekRel( nSkip + 20 );
6437 
6438 				// read in size of metafile in EMUS
6439 				rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height();
6440 
6441 				// scale to 1/100mm
6442 				aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360;
6443 
6444 				if ( pVisArea )		// seem that we currently are skipping the visarea position
6445 					*pVisArea = Rectangle( Point(), aMtfSize100 );
6446 
6447 				// skip rest of header
6448 				nSkip = 6;
6449 				bMtfBLIP = bZCodecCompression = sal_True;
6450 			}
6451 			break;
6452 			case 0x46A :			// One byte tag then JPEG (= JFIF) data
6453 			case 0x6E0 :			// One byte tag then PNG data
6454 			case 0x6E2 :			// One byte tag then JPEG in CMYK color space
6455 			case 0x7A8 :
6456 				nSkip += 1;			// One byte tag then DIB data
6457 			break;
6458 		}
6459 		rBLIPStream.SeekRel( nSkip );
6460 
6461 		SvStream* pGrStream = &rBLIPStream;
6462 		SvMemoryStream* pOut = NULL;
6463 		if( bZCodecCompression )
6464 		{
6465 			pOut = new SvMemoryStream( 0x8000, 0x4000 );
6466 			ZCodec aZCodec( 0x8000, 0x8000 );
6467 			aZCodec.BeginCompression();
6468 			aZCodec.Decompress( rBLIPStream, *pOut );
6469 			aZCodec.EndCompression();
6470 			pOut->Seek( STREAM_SEEK_TO_BEGIN );
6471 			pOut->SetResizeOffset( 0 );	// sj: #i102257# setting ResizeOffset of 0 prevents from seeking
6472 										// behind the stream end (allocating too much memory)
6473 			pGrStream = pOut;
6474 		}
6475 
6476 //#define DBG_EXTRACTGRAPHICS
6477 #ifdef DBG_EXTRACTGRAPHICS
6478 
6479 		static sal_Int32 nCount;
6480 
6481 		String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) );
6482 		aFileName.Append( String::CreateFromInt32( nCount++ ) );
6483 		switch( nInst &~ 1 )
6484 		{
6485 			case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break;
6486 			case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break;
6487 			case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break;
6488 			case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
6489 			case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break;
6490 			case 0x6e2 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
6491 			case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break;
6492 		}
6493 
6494 		String aURLStr;
6495 
6496 		if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
6497 		{
6498 			INetURLObject aURL( aURLStr );
6499 
6500 			aURL.removeSegment();
6501 			aURL.removeFinalSlash();
6502 			aURL.Append( aFileName );
6503 
6504 			SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE );
6505 
6506 			if( pDbgOut )
6507 			{
6508 				if ( bZCodecCompression )
6509 				{
6510 					pOut->Seek( STREAM_SEEK_TO_END );
6511 					pDbgOut->Write( pOut->GetData(), pOut->Tell() );
6512 					pOut->Seek( STREAM_SEEK_TO_BEGIN );
6513 				}
6514 				else
6515 				{
6516 					sal_Int32 nDbgLen = nLength - nSkip;
6517 					if ( nDbgLen )
6518 					{
6519 						sal_Char* pDat = new sal_Char[ nDbgLen ];
6520 						pGrStream->Read( pDat, nDbgLen );
6521 						pDbgOut->Write( pDat, nDbgLen );
6522 						pGrStream->SeekRel( -nDbgLen );
6523 						delete[] pDat;
6524 					}
6525 				}
6526 
6527 				delete pDbgOut;
6528 			}
6529 		}
6530 #endif
6531 
6532 		if( ( nInst & 0xFFFE ) == 0x7A8 )
6533 		{	// DIBs direkt holen
6534 			Bitmap aNew;
6535 			if( aNew.Read( *pGrStream, sal_False ) )
6536 			{
6537 				rData = Graphic( aNew );
6538 				nRes = GRFILTER_OK;
6539 			}
6540 		}
6541 		else
6542 		{	// und unsere feinen Filter darauf loslassen
6543 			GraphicFilter* pGF = GraphicFilter::GetGraphicFilter();
6544 			String aEmptyStr;
6545 			nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW );
6546 
6547 			// SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems,
6548 			// then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the
6549 			// scaling has been implemented does not happen anymore.
6550 			//
6551 			// For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the
6552 			// dxarray is empty (this has been solved in wmf/emf but not for pict)
6553 			if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) )
6554 			{
6555 				if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) )
6556 				{	// #75956#, scaling does not work properly, if the graphic is less than 1cm
6557 					GDIMetaFile	aMtf( rData.GetGDIMetaFile() );
6558 					const Size	aOldSize( aMtf.GetPrefSize() );
6559 
6560 					if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) &&
6561 						aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) )
6562 					{
6563 						aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(),
6564 									(double) aMtfSize100.Height() / aOldSize.Height() );
6565 						aMtf.SetPrefSize( aMtfSize100 );
6566 						aMtf.SetPrefMapMode( MAP_100TH_MM );
6567 						rData = aMtf;
6568 					}
6569 				}
6570 			}
6571 		}
6572 		// ggfs. Fehlerstatus zuruecksetzen
6573 		if ( ERRCODE_IO_PENDING == pGrStream->GetError() )
6574 		  pGrStream->ResetError();
6575 		delete pOut;
6576 	}
6577 	rBLIPStream.Seek( nOldPos );    // alte FilePos des Streams restaurieren
6578 
6579 	return ( GRFILTER_OK == nRes ); // Ergebniss melden
6580 }
6581 
6582 /* static */
6583 sal_Bool SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn)
6584 {
6585 	rRec.nFilePos = rIn.Tell();
6586 	return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer,
6587 													rRec.nRecInstance,
6588 													rRec.nRecType,
6589 													rRec.nRecLen );
6590 }
6591 
6592 
6593 /* auch static */
6594 sal_Bool SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt,
6595 											  sal_uInt8&     rVer,
6596 											  sal_uInt16&   rInst,
6597 											  sal_uInt16&   rFbt,
6598 											  sal_uInt32&    rLength )
6599 {
6600 	sal_uInt16 nTmp;
6601 	rSt >> nTmp >> rFbt >> rLength;
6602 	rVer = sal::static_int_cast< sal_uInt8 >(nTmp & 15);
6603 	rInst = nTmp >> 4;
6604 	if ( rLength > ( SAL_MAX_UINT32 - rSt.Tell() ) )	// preserving overflow, optimal would be to check
6605 		rSt.SetError( SVSTREAM_FILEFORMAT_ERROR );		// the record size against the parent header
6606 	return rSt.GetError() == 0;
6607 }
6608 
6609 
6610 
6611 
6612 sal_Bool SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, sal_uLong nDatLen,
6613 										  char*& rpBuff, sal_uInt32& rBuffLen ) const
6614 {
6615 	if( nDatLen )
6616 	{
6617 		rpBuff = new (std::nothrow) char[ nDatLen ];
6618 		rBuffLen = nDatLen;
6619 		rStData.Read( rpBuff, nDatLen );
6620 	}
6621 	return sal_True;
6622 }
6623 
6624 sal_Bool SvxMSDffManager::ProcessClientData(SvStream& rStData, sal_uLong nDatLen,
6625 										char*& rpBuff, sal_uInt32& rBuffLen ) const
6626 {
6627 	if( nDatLen )
6628 	{
6629 		rpBuff = new (std::nothrow) char[ nDatLen ];
6630 		if ( rpBuff )
6631 		{
6632 			rBuffLen = nDatLen;
6633 			rStData.Read( rpBuff, nDatLen );
6634 		}
6635 	}
6636 	return sal_True;
6637 }
6638 
6639 
6640 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ )
6641 {
6642 	return;  // wird von SJ im Draw ueberladen
6643 }
6644 
6645 sal_uLong SvxMSDffManager::Calc_nBLIPPos( sal_uLong nOrgVal, sal_uLong /* nStreamPos */ ) const
6646 {
6647 	return nOrgVal;
6648 }
6649 
6650 sal_Bool SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const
6651 {
6652 	return sal_False;
6653 }
6654 
6655 sal_Bool SvxMSDffManager::ShapeHasText( sal_uLong /* nShapeId */, sal_uLong /* nFilePos */ ) const
6656 {
6657 	return sal_True;
6658 }
6659 
6660 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup>
6661 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId,
6662                                        const Graphic& rGrf,
6663                                        const Rectangle& rBoundRect,
6664 									   const Rectangle& rVisArea,
6665                                        const int /* _nCalledByGroup */,
6666 									   sal_Int64 nAspect ) const
6667 // <--
6668 {
6669     SdrObject* pRet = 0;
6670 	String sStorageName;
6671     SvStorageRef xSrcStg;
6672     ErrCode nError = ERRCODE_NONE;
6673     uno::Reference < embed::XStorage > xDstStg;
6674 	if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
6675 		pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg,
6676                                         rGrf, rBoundRect, rVisArea, pStData, nError,
6677 										nSvxMSDffOLEConvFlags, nAspect );
6678 	return pRet;
6679 }
6680 
6681 sal_Bool SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf )
6682 {
6683 	String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) );
6684 	SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream );
6685 	xStm->SetVersion( pStor->GetVersion() );
6686 	xStm->SetBufferSize( 8192 );
6687 
6688     sal_uInt16 nAspect = ASPECT_CONTENT;
6689     sal_uLong nAdviseModes = 2;
6690 
6691 	Impl_OlePres aEle( FORMAT_GDIMETAFILE );
6692 	// Die Groesse in 1/100 mm umrechnen
6693 	// Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird,
6694 	// versucht SV einen BestMatchden richtigen Wert zu raten.
6695 	Size aSize = rMtf.GetPrefSize();
6696 	MapMode aMMSrc = rMtf.GetPrefMapMode();
6697 	MapMode aMMDst( MAP_100TH_MM );
6698 	aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
6699 	aEle.SetSize( aSize );
6700  	aEle.SetAspect( nAspect );
6701 	aEle.SetAdviseFlags( nAdviseModes );
6702 	aEle.SetMtf( rMtf );
6703     aEle.Write( *xStm );
6704 
6705 	xStm->SetBufferSize( 0 );
6706 	return xStm->GetError() == SVSTREAM_OK;
6707 }
6708 
6709 struct ClsIDs {
6710 	sal_uInt32		nId;
6711 	const sal_Char* pSvrName;
6712 	const sal_Char* pDspName;
6713 };
6714 static ClsIDs aClsIDs[] = {
6715 
6716 	{ 0x000212F0, "MSWordArt",     		"Microsoft Word Art"	 		},
6717 	{ 0x000212F0, "MSWordArt.2",   		"Microsoft Word Art 2.0" 		},
6718 
6719 	// MS Apps
6720 	{ 0x00030000, "ExcelWorksheet",		"Microsoft Excel Worksheet"		},
6721 	{ 0x00030001, "ExcelChart",			"Microsoft Excel Chart"			},
6722 	{ 0x00030002, "ExcelMacrosheet",	"Microsoft Excel Macro"			},
6723 	{ 0x00030003, "WordDocument",		"Microsoft Word Document"		},
6724 	{ 0x00030004, "MSPowerPoint",		"Microsoft PowerPoint"			},
6725 	{ 0x00030005, "MSPowerPointSho",	"Microsoft PowerPoint Slide Show"},
6726 	{ 0x00030006, "MSGraph",			"Microsoft Graph"				},
6727 	{ 0x00030007, "MSDraw",				"Microsoft Draw"				},
6728 	{ 0x00030008, "Note-It",			"Microsoft Note-It"				},
6729 	{ 0x00030009, "WordArt",			"Microsoft Word Art"			},
6730 	{ 0x0003000a, "PBrush",				"Microsoft PaintBrush Picture"	},
6731 	{ 0x0003000b, "Equation",			"Microsoft Equation Editor"		},
6732 	{ 0x0003000c, "Package",			"Package"						},
6733 	{ 0x0003000d, "SoundRec",			"Sound"							},
6734 	{ 0x0003000e, "MPlayer",			"Media Player"					},
6735 	// MS Demos
6736 	{ 0x0003000f, "ServerDemo",			"OLE 1.0 Server Demo"			},
6737 	{ 0x00030010, "Srtest",				"OLE 1.0 Test Demo"				},
6738 	{ 0x00030011, "SrtInv",				"OLE 1.0 Inv Demo"				},
6739 	{ 0x00030012, "OleDemo",			"OLE 1.0 Demo"					},
6740 
6741 	// Coromandel / Dorai Swamy / 718-793-7963
6742 	{ 0x00030013, "CoromandelIntegra",	"Coromandel Integra"			},
6743 	{ 0x00030014, "CoromandelObjServer","Coromandel Object Server"		},
6744 
6745 	// 3-d Visions Corp / Peter Hirsch / 310-325-1339
6746 	{ 0x00030015, "StanfordGraphics",	"Stanford Graphics"				},
6747 
6748 	// Deltapoint / Nigel Hearne / 408-648-4000
6749 	{ 0x00030016, "DGraphCHART",		"DeltaPoint Graph Chart"		},
6750 	{ 0x00030017, "DGraphDATA",			"DeltaPoint Graph Data"			},
6751 
6752 	// Corel / Richard V. Woodend / 613-728-8200 x1153
6753 	{ 0x00030018, "PhotoPaint",			"Corel PhotoPaint"				},
6754 	{ 0x00030019, "CShow",				"Corel Show"					},
6755 	{ 0x0003001a, "CorelChart",			"Corel Chart"					},
6756 	{ 0x0003001b, "CDraw",				"Corel Draw"					},
6757 
6758 	// Inset Systems / Mark Skiba / 203-740-2400
6759 	{ 0x0003001c, "HJWIN1.0",			"Inset Systems"					},
6760 
6761 	// Mark V Systems / Mark McGraw / 818-995-7671
6762 	{ 0x0003001d, "ObjMakerOLE",		"MarkV Systems Object Maker"	},
6763 
6764 	// IdentiTech / Mike Gilger / 407-951-9503
6765 	{ 0x0003001e, "FYI",				"IdentiTech FYI"				},
6766 	{ 0x0003001f, "FYIView",			"IdentiTech FYI Viewer"			},
6767 
6768 	// Inventa Corporation / Balaji Varadarajan / 408-987-0220
6769 	{ 0x00030020, "Stickynote",			"Inventa Sticky Note"			},
6770 
6771 	// ShapeWare Corp. / Lori Pearce / 206-467-6723
6772 	{ 0x00030021, "ShapewareVISIO10",   "Shapeware Visio 1.0"			},
6773 	{ 0x00030022, "ImportServer",		"Spaheware Import Server"		},
6774 
6775 	// test app SrTest
6776 	{ 0x00030023, "SrvrTest",			"OLE 1.0 Server Test"			},
6777 
6778 	// test app ClTest.  Doesn't really work as a server but is in reg db
6779 	{ 0x00030025, "Cltest",				"OLE 1.0 Client Test"			},
6780 
6781 	// Microsoft ClipArt Gallery   Sherry Larsen-Holmes
6782 	{ 0x00030026, "MS_ClipArt_Gallery",	"Microsoft ClipArt Gallery"		},
6783 	// Microsoft Project  Cory Reina
6784 	{ 0x00030027, "MSProject",			"Microsoft Project"				},
6785 
6786 	// Microsoft Works Chart
6787 	{ 0x00030028, "MSWorksChart",		"Microsoft Works Chart"			},
6788 
6789 	// Microsoft Works Spreadsheet
6790 	{ 0x00030029, "MSWorksSpreadsheet",	"Microsoft Works Spreadsheet"	},
6791 
6792 	// AFX apps - Dean McCrory
6793 	{ 0x0003002A, "MinSvr",				"AFX Mini Server"				},
6794 	{ 0x0003002B, "HierarchyList",		"AFX Hierarchy List"			},
6795 	{ 0x0003002C, "BibRef",				"AFX BibRef"					},
6796 	{ 0x0003002D, "MinSvrMI",			"AFX Mini Server MI"			},
6797 	{ 0x0003002E, "TestServ",			"AFX Test Server"				},
6798 
6799 	// Ami Pro
6800 	{ 0x0003002F, "AmiProDocument",		"Ami Pro Document"				},
6801 
6802 	// WordPerfect Presentations For Windows
6803 	{ 0x00030030, "WPGraphics",			"WordPerfect Presentation"		},
6804 	{ 0x00030031, "WPCharts",			"WordPerfect Chart"				},
6805 
6806 	// MicroGrafx Charisma
6807 	{ 0x00030032, "Charisma",			"MicroGrafx Charisma"			},
6808 	{ 0x00030033, "Charisma_30",		"MicroGrafx Charisma 3.0"		},
6809 	{ 0x00030034, "CharPres_30",		"MicroGrafx Charisma 3.0 Pres"	},
6810 	// MicroGrafx Draw
6811 	{ 0x00030035, "Draw",				"MicroGrafx Draw"				},
6812 	// MicroGrafx Designer
6813 	{ 0x00030036, "Designer_40",		"MicroGrafx Designer 4.0"		},
6814 
6815 	// STAR DIVISION
6816 //	{ 0x000424CA, "StarMath",			"StarMath 1.0"					},
6817 	{ 0x00043AD2, "FontWork",			"Star FontWork"					},
6818 //	{ 0x000456EE, "StarMath2",			"StarMath 2.0"					},
6819 
6820 	{ 0, "", "" } };
6821 
6822 
6823 sal_Bool SvxMSDffManager::ConvertToOle2( SvStream& rStm, sal_uInt32 nReadLen,
6824 					const GDIMetaFile * pMtf, const SotStorageRef& rDest )
6825 {
6826 	sal_Bool bMtfRead = sal_False;
6827 	SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ),
6828 													STREAM_WRITE| STREAM_SHARE_DENYALL );
6829 	if( xOle10Stm->GetError() )
6830 		return sal_False;
6831 
6832 	sal_uInt32 nType;
6833 	sal_uInt32 nRecType;
6834 	sal_uInt32 nStrLen;
6835 	String aSvrName;
6836 	sal_uInt32 nDummy0;
6837 	sal_uInt32 nDummy1;
6838 	sal_uInt32 nDataLen;
6839 	sal_uInt8 * pData;
6840 	sal_uInt32 nBytesRead = 0;
6841 	do
6842 	{
6843 		rStm >> nType;
6844 		rStm >> nRecType;
6845 		rStm >> nStrLen;
6846 		if( nStrLen )
6847 		{
6848 			if( 0x10000L > nStrLen )
6849 			{
6850 				sal_Char * pBuf = new sal_Char[ nStrLen ];
6851 				rStm.Read( pBuf, nStrLen );
6852                 aSvrName.Assign( String( pBuf, (sal_uInt16) nStrLen-1, gsl_getSystemTextEncoding() ) );
6853                 delete[] pBuf;
6854 			}
6855 			else
6856 				break;
6857 		}
6858 		rStm >> nDummy0;
6859 		rStm >> nDummy1;
6860 		rStm >> nDataLen;
6861 
6862 		nBytesRead += 6 * sizeof( sal_uInt32 ) + nStrLen + nDataLen;
6863 
6864 		if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen )
6865 		{
6866 			if( xOle10Stm.Is() )
6867 			{
6868 				pData = new sal_uInt8[ nDataLen ];
6869 				if( !pData )
6870 					return sal_False;
6871 
6872 				rStm.Read( pData, nDataLen );
6873 
6874 				// write to ole10 stream
6875 				*xOle10Stm << nDataLen;
6876 				xOle10Stm->Write( pData, nDataLen );
6877 				xOle10Stm = SotStorageStreamRef();
6878 
6879 				// set the compobj stream
6880 				ClsIDs* pIds;
6881 				for( pIds = aClsIDs; pIds->nId; pIds++ )
6882 				{
6883 					if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) )
6884 						break;
6885 				}
6886 //				SvGlobalName* pClsId = NULL;
6887 				String aShort, aFull;
6888 				if( pIds->nId )
6889 				{
6890 					// gefunden!
6891 					sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName );
6892 					rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt,
6893 									String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) );
6894 				}
6895 				else
6896 				{
6897 					sal_uLong nCbFmt = SotExchange::RegisterFormatName( aSvrName );
6898 					rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName );
6899 				}
6900 
6901                 delete[] pData;
6902 			}
6903 			else if( nRecType == 5 && !pMtf )
6904 			{
6905 				sal_uLong nPos = rStm.Tell();
6906 				sal_uInt16 sz[4];
6907 				rStm.Read( sz, 8 );
6908 				//rStm.SeekRel( 8 );
6909 				Graphic aGraphic;
6910 				if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() )
6911 				{
6912 					const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
6913 					MakeContentStream( rDest, rMtf );
6914 					bMtfRead = sal_True;
6915 				}
6916 				// set behind the data
6917 				rStm.Seek( nPos + nDataLen );
6918             }
6919 			else
6920 				rStm.SeekRel( nDataLen );
6921 		}
6922 	} while( !rStm.IsEof() && nReadLen >= nBytesRead );
6923 
6924 	if( !bMtfRead && pMtf )
6925 	{
6926 		MakeContentStream( rDest, *pMtf );
6927 		return sal_True;
6928     }
6929 
6930 	return sal_False;
6931 }
6932 
6933 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName )
6934 {
6935 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 )
6936 	  || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
6937         return "swriter";
6938 	else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 )
6939 	  || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
6940         return "scalc";
6941 	else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 )
6942 	  || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
6943         return "simpress";
6944 	else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 )
6945       || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
6946         return "sdraw";
6947 	else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 )
6948       || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
6949         return "smath";
6950 	else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 )
6951 	  || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
6952         return "schart";
6953     return 0;
6954 }
6955 
6956 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
6957 {
6958 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) )
6959         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) );
6960 
6961 	if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
6962         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) );
6963 
6964 	if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) )
6965         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) );
6966 
6967 	if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
6968         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) );
6969 
6970 	if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
6971         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) );
6972 
6973 	if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
6974         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) );
6975 
6976 	if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
6977         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) );
6978 
6979     if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
6980         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) );
6981 
6982 	if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) )
6983         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) );
6984 
6985     if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
6986         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) );
6987 
6988 	if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
6989         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) );
6990 
6991 	if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
6992         return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) );
6993 
6994     return ::rtl::OUString();
6995 }
6996 
6997 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject >  SvxMSDffManager::CheckForConvertToSOObj( sal_uInt32 nConvertFlags,
6998                         SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage,
6999                         const Graphic& rGrf,
7000 						const Rectangle& rVisArea )
7001 {
7002     uno::Reference < embed::XEmbeddedObject > xObj;
7003     SvGlobalName aStgNm = rSrcStg.GetClassName();
7004     const char* pName = GetInternalServerName_Impl( aStgNm );
7005     String sStarName;
7006     if ( pName )
7007         sStarName = String::CreateFromAscii( pName );
7008     else if ( nConvertFlags )
7009     {
7010         static struct _ObjImpType
7011         {
7012             sal_uInt32 nFlag;
7013             const char* pFactoryNm;
7014             // GlobalNameId
7015             sal_uInt32 n1;
7016             sal_uInt16 n2, n3;
7017             sal_uInt8 b8, b9, b10, b11, b12, b13, b14, b15;
7018         } aArr[] = {
7019             { OLE_MATHTYPE_2_STARMATH, "smath",
7020                 0x0002ce02L, 0x0000, 0x0000,
7021                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7022             { OLE_MATHTYPE_2_STARMATH, "smath",
7023                 0x00021700L, 0x0000, 0x0000,
7024                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7025             { OLE_WINWORD_2_STARWRITER, "swriter",
7026                 0x00020906L, 0x0000, 0x0000,
7027                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7028             { OLE_EXCEL_2_STARCALC, "scalc",                // Excel table
7029                 0x00020810L, 0x0000, 0x0000,
7030                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7031             { OLE_EXCEL_2_STARCALC, "scalc",                // Excel chart
7032                 0x00020820L, 0x0000, 0x0000,
7033                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7034             // 114465: additional Excel OLE chart classId to above.
7035             { OLE_EXCEL_2_STARCALC, "scalc",
7036                 0x00020821L, 0x0000, 0x0000,
7037                 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7038             { OLE_POWERPOINT_2_STARIMPRESS, "simpress",     // PowerPoint presentation
7039                 0x64818d10L, 0x4f9b, 0x11cf,
7040                 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7041             { OLE_POWERPOINT_2_STARIMPRESS, "simpress",     // PowerPoint slide
7042                 0x64818d11L, 0x4f9b, 0x11cf,
7043                 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7044             { 0, 0,
7045 			  0, 0, 0,
7046 			  0, 0, 0, 0, 0, 0, 0, 0 }
7047         };
7048 
7049         for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr )
7050         {
7051             if( nConvertFlags & pArr->nFlag )
7052             {
7053                 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3,
7054                                 pArr->b8, pArr->b9, pArr->b10, pArr->b11,
7055                                 pArr->b12, pArr->b13, pArr->b14, pArr->b15 );
7056 
7057                 if ( aStgNm == aTypeName )
7058                 {
7059                     sStarName = String::CreateFromAscii( pArr->pFactoryNm );
7060                     break;
7061                 }
7062             }
7063         }
7064     }
7065 
7066     if ( sStarName.Len() )
7067     {
7068         //TODO/MBA: check if (and when) storage and stream will be destroyed!
7069         const SfxFilter* pFilter = 0;
7070         SvMemoryStream* pStream = new SvMemoryStream;
7071         if ( pName )
7072         {
7073             // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also
7074             SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ );
7075             *xStr >> *pStream;
7076         }
7077         else
7078         {
7079             SfxFilterMatcher aMatch( sStarName );
7080             SotStorageRef xStorage = new SotStorage( sal_False, *pStream );
7081             rSrcStg.CopyTo( xStorage );
7082             xStorage->Commit();
7083             xStorage.Clear();
7084             String aType = SfxFilter::GetTypeFromStorage( rSrcStg );
7085             if ( aType.Len() )
7086                 pFilter = aMatch.GetFilter4EA( aType );
7087         }
7088 
7089         if ( pName || pFilter )
7090         {
7091             //Reuse current ole name
7092             String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7093             aDstStgName += String::CreateFromInt32(nMSOleObjCntr);
7094 
7095             ::rtl::OUString aFilterName;
7096             if ( pFilter )
7097                 aFilterName = pFilter->GetName();
7098             else
7099                 aFilterName = GetFilterNameFromClassID_Impl( aStgNm );
7100 
7101             uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2);
7102             aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
7103             uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream );
7104             aMedium[0].Value <<= xStream;
7105             aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
7106             aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
7107 
7108             if ( aFilterName.getLength() )
7109             {
7110                 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
7111                 aMedium[2].Value <<= aFilterName;
7112             }
7113 
7114             ::rtl::OUString aName( aDstStgName );
7115             comphelper::EmbeddedObjectContainer aCnt( rDestStorage );
7116             xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7117 
7118             if ( !xObj.is() )
7119             {
7120                 if( aFilterName.getLength() )
7121                 {
7122                     // throw the filter parameter away as workaround
7123                     aMedium.realloc( 2 );
7124                     xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7125                 }
7126 
7127                 if ( !xObj.is() )
7128                      return xObj;
7129             }
7130 
7131             // TODO/LATER: ViewAspect must be passed from outside!
7132             sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT;
7133 
7134             // JP 26.10.2001: Bug 93374 / 91928 the writer
7135             // objects need the correct visarea needs the
7136             // correct visarea, but this is not true for
7137             // PowerPoint (see bugdoc 94908b)
7138             // SJ: 19.11.2001 bug 94908, also chart objects
7139             // needs the correct visarea
7140 
7141 			// If pName is set this is an own embedded object, it should have the correct size internally
7142 			// TODO/LATER: it might make sence in future to set the size stored in internal object
7143             if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) )
7144             {
7145                 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) );
7146                 Size aSz;
7147 				if ( rVisArea.IsEmpty() )
7148 					aSz = lcl_GetPrefSize(rGrf, aMapMode );
7149 				else
7150 				{
7151 					aSz = rVisArea.GetSize();
7152 					aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode );
7153 				}
7154 
7155                 // don't modify the object
7156                 //TODO/LATER: remove those hacks, that needs to be done differently!
7157                 //xIPObj->EnableSetModified( sal_False );
7158                 awt::Size aSize;
7159                 aSize.Width = aSz.Width();
7160                 aSize.Height = aSz.Height();
7161                 xObj->setVisualAreaSize( nViewAspect, aSize );
7162                 //xIPObj->EnableSetModified( sal_True );
7163             }
7164             else if ( sStarName.EqualsAscii( "smath" ) )
7165             {   // SJ: force the object to recalc its visarea
7166                 //TODO/LATER: wait for PrinterChangeNotification
7167                 //xIPObj->OnDocumentPrinterChanged( NULL );
7168             }
7169         }
7170     }
7171 
7172     return xObj;
7173 }
7174 
7175 // TODO/MBA: code review and testing!
7176 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage(
7177 				const String& rStorageName,
7178 				SotStorageRef& rSrcStorage,
7179                 const uno::Reference < embed::XStorage >& xDestStorage,
7180 				const Graphic& rGrf,
7181 				const Rectangle& rBoundRect,
7182 				const Rectangle& rVisArea,
7183 				SvStream* pDataStrm,
7184                 ErrCode& rError,
7185 				sal_uInt32 nConvertFlags,
7186 				sal_Int64 nReccomendedAspect )
7187 {
7188 	sal_Int64 nAspect = nReccomendedAspect;
7189 	SdrOle2Obj* pRet = 0;
7190     if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() )
7191 	{
7192         comphelper::EmbeddedObjectContainer aCnt( xDestStorage );
7193 		// Ist der 01Ole-Stream ueberhaupt vorhanden ?
7194 		// ( ist er z.B. bei FontWork nicht )
7195 		// Wenn nicht -> Einbindung als Grafik
7196 		sal_Bool bValidStorage = sal_False;
7197 		String aDstStgName( String::CreateFromAscii(
7198 								RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7199 
7200 		aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr );
7201 
7202 		{
7203             SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName,
7204 								STREAM_READWRITE| STREAM_SHARE_DENYALL );
7205 			if( xObjStg.Is()  )
7206 			{
7207 				{
7208 					sal_uInt8 aTestA[10];	// exist the \1CompObj-Stream ?
7209 					SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream(
7210 								String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"),
7211 										RTL_TEXTENCODING_MS_1252 ));
7212 					bValidStorage = xSrcTst.Is() && sizeof( aTestA ) ==
7213 									xSrcTst->Read( aTestA, sizeof( aTestA ) );
7214 					if( !bValidStorage )
7215 					{
7216 						// or the \1Ole-Stream ?
7217 						xSrcTst = xObjStg->OpenSotStream(
7218 									String(RTL_CONSTASCII_STRINGPARAM("\1Ole"),
7219 											RTL_TEXTENCODING_MS_1252 ));
7220 						bValidStorage = xSrcTst.Is() && sizeof(aTestA) ==
7221 										xSrcTst->Read(aTestA, sizeof(aTestA));
7222 					}
7223 				}
7224 
7225                 if( bValidStorage )
7226 				{
7227 					if ( nAspect != embed::Aspects::MSOLE_ICON )
7228 					{
7229 						// check whether the object is iconified one
7230 						// usually this information is already known, the only exception
7231 						// is a kind of embedded objects in Word documents
7232 						// TODO/LATER: should the caller be notified if the aspect changes in future?
7233 
7234 						SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream(
7235 							String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ),
7236 							STREAM_STD_READ | STREAM_NOCREATE );
7237 						if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
7238 						{
7239 							sal_uInt8 nByte = 0;
7240 							*xObjInfoSrc >> nByte;
7241 							if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
7242 								nAspect = embed::Aspects::MSOLE_ICON;
7243 						}
7244 					}
7245 
7246                     uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj(
7247                                 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea ));
7248                     if ( xObj.is() )
7249     			    {
7250                         svt::EmbeddedObjectRef aObj( xObj, nAspect );
7251 
7252                         // TODO/LATER: need MediaType
7253                         aObj.SetGraphic( rGrf, ::rtl::OUString() );
7254 
7255                         // TODO/MBA: check setting of PersistName
7256                         pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false);
7257 						// we have the Object, don't create another
7258 						bValidStorage = false;
7259                     }
7260 				}
7261 			}
7262 		}
7263 
7264 		if( bValidStorage )
7265 		{
7266             // object is not an own object
7267             SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE );
7268 
7269 			if ( xObjStor.Is() )
7270 			{
7271 				SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ );
7272 				xSrcStor->CopyTo( xObjStor );
7273 
7274 				if( !xObjStor->GetError() )
7275 					xObjStor->Commit();
7276 
7277 				if( xObjStor->GetError() )
7278 				{
7279 				    rError = xObjStor->GetError();
7280 					bValidStorage = sal_False;
7281 				}
7282 				else if( !xObjStor.Is() )
7283 					bValidStorage = sal_False;
7284 			}
7285 		}
7286 		else if( pDataStrm )
7287 		{
7288 			sal_uInt32 nLen, nDummy;
7289 			*pDataStrm >> nLen >> nDummy;
7290 			if( SVSTREAM_OK != pDataStrm->GetError() ||
7291 				// Id in BugDoc - exist there other Ids?
7292 				// The ConvertToOle2 - does not check for consistent
7293 				0x30008 != nDummy )
7294 				bValidStorage = sal_False;
7295 			else
7296 			{
7297 				// or is it an OLE-1 Stream in the DataStream?
7298                 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName );
7299                 //TODO/MBA: remove metafile conversion from ConvertToOle2
7300                 //when is this code used?!
7301 				GDIMetaFile aMtf;
7302                 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor );
7303                 xObjStor->Commit();
7304 			}
7305         }
7306 
7307 		if( bValidStorage )
7308 		{
7309             uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName );
7310             if( xObj.is() )
7311             {
7312                 // the visual area must be retrieved from the metafile (object doesn't know it so far)
7313 
7314 				if ( nAspect != embed::Aspects::MSOLE_ICON )
7315 				{
7316                 	// working with visual area can switch the object to running state
7317                 	awt::Size aAwtSz;
7318 					try
7319 					{
7320 						// the provided visual area should be used, if there is any
7321 						if ( rVisArea.IsEmpty() )
7322 						{
7323                 			MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
7324                 			Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit)));
7325                 			aAwtSz.Width = aSz.Width();
7326                 			aAwtSz.Height = aSz.Height();
7327 						}
7328 						else
7329 						{
7330 							aAwtSz.Width = rVisArea.GetWidth();
7331 							aAwtSz.Height = rVisArea.GetHeight();
7332 						}
7333                 		//xInplaceObj->EnableSetModified( sal_False );
7334                 		xObj->setVisualAreaSize( nAspect, aAwtSz );
7335                 		//xInplaceObj->EnableSetModified( sal_True );*/
7336 					}
7337 					catch( uno::Exception& )
7338 					{
7339 						OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" );
7340 					}
7341 				}
7342 
7343                 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7344 
7345                 // TODO/LATER: need MediaType
7346                 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7347 
7348                 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false);
7349             }
7350 		}
7351 	}
7352 
7353 	return pRet;
7354 }
7355 
7356 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const
7357 {
7358 	SdrObject* pRet = NULL;
7359 
7360 	if(120 >= sal_uInt16(eTyp))
7361 	{
7362 		pRet = new SdrRectObj();
7363 	}
7364 
7365 	DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM");
7366 
7367 	return pRet;
7368 }
7369 
7370 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
7371 			const String& rPropName, sal_Bool bTestPropertyAvailability )
7372 {
7373     sal_Bool bRetValue = sal_True;
7374 	if ( bTestPropertyAvailability )
7375 	{
7376 		bRetValue = sal_False;
7377 		try
7378 		{
7379 			uno::Reference< beans::XPropertySetInfo >
7380 				aXPropSetInfo( rXPropSet->getPropertySetInfo() );
7381 			if ( aXPropSetInfo.is() )
7382 				bRetValue = aXPropSetInfo->hasPropertyByName( rPropName );
7383 		}
7384 		catch( uno::Exception& )
7385 		{
7386 			bRetValue = sal_False;
7387 		}
7388 	}
7389 	if ( bRetValue )
7390 	{
7391 		try
7392 		{
7393 			rXPropSet->setPropertyValue( rPropName, rAny );
7394 			bRetValue = sal_True;
7395 		}
7396 		catch( uno::Exception& )
7397 		{
7398 			bRetValue = sal_False;
7399 		}
7400 	}
7401     return bRetValue;
7402 }
7403 
7404 SvxMSDffImportRec::SvxMSDffImportRec()
7405     : pObj( 0 ),
7406       pWrapPolygon(0),
7407       pClientAnchorBuffer( 0 ),
7408       nClientAnchorLen(  0 ),
7409       pClientDataBuffer( 0 ),
7410       nClientDataLen(    0 ),
7411       nXAlign( 0 ),	// position n cm from left
7412       nXRelTo( 2 ), //   relative to column
7413       nYAlign( 0 ), // position n cm below
7414       nYRelTo( 2 ), //   relative to paragraph
7415       nLayoutInTableCell( 0 ), // element is laid out in table cell
7416       nTextRotationAngle( 0 ),
7417       nDxTextLeft( 144 ),
7418       nDyTextTop( 72 ),
7419       nDxTextRight(	144 ),
7420       nDyTextBottom( 72 ),
7421       nDxWrapDistLeft( 0 ),
7422       nDyWrapDistTop( 0 ),
7423       nDxWrapDistRight( 0 ),
7424       nDyWrapDistBottom(0 ),
7425       nCropFromTop( 0 ),
7426       nCropFromBottom( 0 ),
7427       nCropFromLeft( 0 ),
7428       nCropFromRight( 0 ),
7429       aTextId( 0, 0 ),
7430       nNextShapeId(	0 ),
7431       nShapeId( 0 ),
7432       eShapeType( mso_sptNil )
7433 {
7434       eLineStyle      = mso_lineSimple; // GPF-Bug #66227#
7435       bDrawHell       = sal_False;
7436       bHidden         = sal_False;
7437 //	  bInGroup		  = sal_False;
7438       bReplaceByFly   = sal_False;
7439       bLastBoxInChain = sal_True;
7440       bHasUDefProp    = sal_False; // was the DFF_msofbtUDefProp record set?
7441       bVFlip = sal_False;
7442       bHFlip = sal_False;
7443       bAutoWidth      = sal_False;
7444 }
7445 
7446 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy)
7447     : pObj(	rCopy.pObj ),
7448       nXAlign( rCopy.nXAlign ),
7449       nXRelTo( rCopy.nXRelTo ),
7450       nYAlign( rCopy.nYAlign ),
7451       nYRelTo( rCopy.nYRelTo ),
7452       nLayoutInTableCell( rCopy.nLayoutInTableCell ),
7453       nTextRotationAngle( rCopy.nTextRotationAngle ),
7454       nDxTextLeft( rCopy.nDxTextLeft	),
7455       nDyTextTop( rCopy.nDyTextTop ),
7456       nDxTextRight( rCopy.nDxTextRight ),
7457       nDyTextBottom( rCopy.nDyTextBottom ),
7458       nDxWrapDistLeft( rCopy.nDxWrapDistLeft ),
7459       nDyWrapDistTop( rCopy.nDyWrapDistTop ),
7460       nDxWrapDistRight( rCopy.nDxWrapDistRight ),
7461       nDyWrapDistBottom(rCopy.nDyWrapDistBottom ),
7462       nCropFromTop( rCopy.nCropFromTop ),
7463       nCropFromBottom( rCopy.nCropFromBottom ),
7464       nCropFromLeft( rCopy.nCropFromLeft ),
7465       nCropFromRight( rCopy.nCropFromRight ),
7466       aTextId( rCopy.aTextId ),
7467       nNextShapeId( rCopy.nNextShapeId ),
7468       nShapeId( rCopy.nShapeId ),
7469       eShapeType( rCopy.eShapeType )
7470 {
7471     eLineStyle       = rCopy.eLineStyle; // GPF-Bug #66227#
7472     bDrawHell        = rCopy.bDrawHell;
7473     bHidden          = rCopy.bHidden;
7474 //			bInGroup		 = rCopy.bInGroup;
7475     bReplaceByFly    = rCopy.bReplaceByFly;
7476     bAutoWidth       = rCopy.bAutoWidth;
7477     bLastBoxInChain  = rCopy.bLastBoxInChain;
7478     bHasUDefProp     = rCopy.bHasUDefProp;
7479     bVFlip = rCopy.bVFlip;
7480     bHFlip = rCopy.bHFlip;
7481     nClientAnchorLen = rCopy.nClientAnchorLen;
7482     if( rCopy.nClientAnchorLen )
7483     {
7484         pClientAnchorBuffer = new char[ nClientAnchorLen ];
7485         memcpy( pClientAnchorBuffer,
7486                 rCopy.pClientAnchorBuffer,
7487                 nClientAnchorLen );
7488     }
7489     else
7490         pClientAnchorBuffer = 0;
7491 
7492     nClientDataLen = rCopy.nClientDataLen;
7493     if( rCopy.nClientDataLen )
7494     {
7495         pClientDataBuffer = new char[ nClientDataLen ];
7496         memcpy( pClientDataBuffer,
7497                 rCopy.pClientDataBuffer,
7498                 nClientDataLen );
7499     }
7500     else
7501         pClientDataBuffer = 0;
7502 
7503     if (rCopy.pWrapPolygon)
7504         pWrapPolygon = new Polygon(*rCopy.pWrapPolygon);
7505     else
7506         pWrapPolygon = 0;
7507 }
7508 
7509 SvxMSDffImportRec::~SvxMSDffImportRec()
7510 {
7511     if (pClientAnchorBuffer)
7512         delete[] pClientAnchorBuffer;
7513     if (pClientDataBuffer)
7514         delete[] pClientDataBuffer;
7515     if (pWrapPolygon)
7516         delete pWrapPolygon;
7517 }
7518 
7519 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
7520 
7521 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape )
7522 {
7523 	maShapeIdContainer[nShapeId] = pShape;
7524 }
7525 
7526 void SvxMSDffManager::removeShapeId( SdrObject* pShape )
7527 {
7528 	SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() );
7529 	const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() );
7530 	while( aIter != aEnd )
7531 	{
7532 		if( (*aIter).second == pShape )
7533 		{
7534 			maShapeIdContainer.erase( aIter );
7535 			break;
7536 		}
7537 		aIter++;
7538 	}
7539 }
7540 
7541 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId )
7542 {
7543 	SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) );
7544 	return aIter != maShapeIdContainer.end() ? (*aIter).second : 0;
7545 }
7546