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