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