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