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