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