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