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