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