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