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