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