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