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