update ooo310-m15
[ooovba.git] / svx / source / msfilter / msdffimp.cxx
blob98b96cfc4f90f762dfa099a3e26ea0364a3f18d8
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: msdffimp.cxx,v $
10 * $Revision: 1.157 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
34 #include <com/sun/star/embed/Aspects.hpp>
36 #include <math.h>
37 #include <limits.h>
38 #include <vector>
39 #include <osl/endian.h>
40 #include <tools/solar.h> // UINTXX
41 #include <rtl/math.hxx>
43 #include <sot/clsids.hxx>
44 #include <toolkit/helper/vclunohelper.hxx>
45 #include <unotools/streamwrap.hxx>
46 #include <comphelper/processfactory.hxx>
47 #include <sot/exchange.hxx>
48 #include <sot/storinfo.hxx>
49 #include <vcl/cvtgrf.hxx>
51 #include "viscache.hxx"
53 // SvxItem-Mapping. Wird benoetigt um die SvxItem-Header erfolgreich zu includen
54 #include <svx/eeitem.hxx>
55 #ifndef _EDITDATA_HXX
56 #include <svx/editdata.hxx>
57 #endif
59 #include <svtools/urihelper.hxx>
61 // textitem.hxx editdata.hxx
78 // paraitem.hxx editdata.hxx
81 #include <tools/stream.hxx>
82 #include <tools/debug.hxx>
83 #ifndef _TOOLS_ZCODEC_HXX
84 #include <tools/zcodec.hxx>
85 #endif
86 #ifndef _UNOTOOLS_UCBSTREAMHELPER_HXX
87 #include <unotools/ucbstreamhelper.hxx>
88 #endif
89 #include <unotools/localfilehelper.hxx>
90 #include <svx/escherex.hxx>
91 #include <basegfx/range/b2drange.hxx>
92 #include <com/sun/star/container/XIdentifierContainer.hpp>
93 #include <com/sun/star/drawing/XGluePointsSupplier.hpp>
94 #include <com/sun/star/drawing/Position3D.hpp>
95 #include <com/sun/star/drawing/Direction3D.hpp>
96 #include <com/sun/star/drawing/GluePoint2.hpp>
97 #include <com/sun/star/drawing/XShapes.hpp>
98 #include <svx/charscaleitem.hxx>
99 #include <svx/kernitem.hxx>
100 #include <svtools/filter.hxx>
101 #include <tools/string.hxx>
102 #ifndef _TOOLS_URLOBJ_HXX
103 #include <tools/urlobj.hxx>
104 #endif
105 #include <vcl/virdev.hxx>
106 #include <vcl/bmpacc.hxx>
107 #ifndef _SVSTOR_HXX //autogen
108 #include <sot/storage.hxx>
109 #endif
110 #include <sfx2/docfac.hxx>
111 #include <sfx2/docfilt.hxx>
112 #include <sfx2/docfile.hxx>
113 #include <sfx2/fcontnr.hxx>
114 #include <sfx2/module.hxx>
115 //#ifndef _SFX_INTERNO_HXX
116 //#include <sfx2/interno.hxx>
117 //#endif
119 #ifndef _SDGCPITM_HXX
121 //#endif
122 #include <svx/sdgcpitm.hxx>
123 #endif
124 #include <svx/sdgmoitm.hxx>
125 #include <svx/tstpitem.hxx>
126 #include <svx/fmmodel.hxx>
127 #include <svx/svdmodel.hxx>
128 #include <svx/svdobj.hxx>
129 #include <svx/svdpage.hxx>
130 #include <svx/svdogrp.hxx>
131 #include <svx/svdograf.hxx>
132 #include <svx/svdotext.hxx>
133 #include <svx/svdorect.hxx>
134 #ifndef _SVDOCAPT_HXX
135 #include <svx/svdocapt.hxx>
136 #endif
137 #include <svx/svdoedge.hxx>
138 #include <svx/svdocirc.hxx>
139 #include <svx/svdoutl.hxx>
140 #include <svx/svdoole2.hxx>
141 #include <svx/svdopath.hxx>
142 #include <svx/frmdir.hxx>
143 #include <svx/frmdiritem.hxx>
144 #include <svx/svdtrans.hxx>
145 #include <svx/sxenditm.hxx>
146 #include <svx/sdgluitm.hxx>
147 #include <svx/fhgtitem.hxx>
148 #include <svx/wghtitem.hxx>
149 #include <svx/postitem.hxx>
150 #include <svx/udlnitem.hxx>
151 #include <svx/crsditem.hxx>
152 #include <svx/shdditem.hxx>
153 #include <fontitem.hxx>
154 #include <svx/colritem.hxx>
155 #include <svx/sxekitm.hxx>
156 #include <bulitem.hxx>
157 #include <svx/polysc3d.hxx>
158 #include <svx/extrud3d.hxx>
159 #include "svditer.hxx"
160 #include <svx/xpoly.hxx>
161 #include "xattr.hxx"
163 #ifndef _IMPGRF_HXX //autogen
164 #include "impgrf.hxx"
165 #endif
166 #include <svx/msdffimp.hxx> // extern sichtbare Header-Datei
167 #include <svx/outliner.hxx>
168 #include <svx/outlobj.hxx>
169 #include <svx/editobj.hxx>
170 #include <svx/editeng.hxx>
171 #include "msashape.hxx"
172 #include "msashape3d.hxx"
173 #include "gallery.hxx"
174 #include <com/sun/star/drawing/ShadeMode.hpp>
175 #include <svtools/itempool.hxx>
176 #include <vcl/svapp.hxx>
177 #include <svx/svx3ditems.hxx>
178 #include <svx/svdoashp.hxx>
179 #include <svx/sdasaitm.hxx>
180 #ifndef _UCBHELPER_CONTENT_HXX_
181 #include <ucbhelper/content.hxx>
182 #endif
183 #ifndef _UCBHELPER_CONTENTBROKER_HXX_
184 #include <ucbhelper/contentbroker.hxx>
185 #endif
186 #include <vos/xception.hxx>
187 #ifndef _VOS_NO_NAMESPACE
188 using namespace vos;
189 #endif
190 #include "../customshapes/EnhancedCustomShapeTypeNames.hxx"
191 #include "../customshapes/EnhancedCustomShapeGeometry.hxx"
192 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
193 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
194 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
195 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
196 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
197 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
198 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
199 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
200 #ifndef __com_sun_star_beans_PropertyValues_hpp__
201 #include <com/sun/star/beans/PropertyValues.hpp>
202 #endif
203 #include <com/sun/star/drawing/ProjectionMode.hpp>
204 #include "../customshapes/EnhancedCustomShape2d.hxx"
206 using namespace ::com::sun::star ;
207 using namespace ::com::sun::star::drawing;
208 using namespace uno ;
209 using namespace beans ;
210 using namespace drawing ;
211 using namespace container ;
213 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
215 // static counter for OLE-Objects
216 static sal_uInt32 nMSOleObjCntr = 0;
217 #define MSO_OLE_Obj "MSO_OLE_Obj"
220 /*************************************************************************/
221 BOOL Impl_OlePres::Read( SvStream & rStm )
223 ULONG nBeginPos = rStm.Tell();
224 INT32 n;
225 rStm >> n;
226 if( n != -1 )
228 pBmp = new Bitmap;
229 rStm >> *pBmp;
230 if( rStm.GetError() == SVSTREAM_OK )
232 nFormat = FORMAT_BITMAP;
233 aSize = pBmp->GetPrefSize();
234 MapMode aMMSrc;
235 if( !aSize.Width() || !aSize.Height() )
237 // letzte Chance
238 aSize = pBmp->GetSizePixel();
239 aMMSrc = MAP_PIXEL;
241 else
242 aMMSrc = pBmp->GetPrefMapMode();
243 MapMode aMMDst( MAP_100TH_MM );
244 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
245 return TRUE;
247 else
249 delete pBmp;
250 pBmp = NULL;
252 pMtf = new GDIMetaFile();
253 rStm.ResetError();
254 rStm >> *pMtf;
255 if( rStm.GetError() == SVSTREAM_OK )
257 nFormat = FORMAT_GDIMETAFILE;
258 aSize = pMtf->GetPrefSize();
259 MapMode aMMSrc = pMtf->GetPrefMapMode();
260 MapMode aMMDst( MAP_100TH_MM );
261 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
262 return TRUE;
264 else
266 delete pMtf;
267 pMtf = NULL;
273 rStm.ResetError();
274 rStm.Seek( nBeginPos );
275 nFormat = ReadClipboardFormat( rStm );
276 // JobSetup, bzw. TargetDevice ueberlesen
277 // Information aufnehmen, um sie beim Schreiben nicht zu verlieren
278 nJobLen = 0;
279 rStm >> nJobLen;
280 if( nJobLen >= 4 )
282 nJobLen -= 4;
283 if( nJobLen )
285 pJob = new BYTE[ nJobLen ];
286 rStm.Read( pJob, nJobLen );
289 else
291 rStm.SetError( SVSTREAM_GENERALERROR );
292 return FALSE;
294 UINT32 nAsp;
295 rStm >> nAsp;
296 USHORT nSvAsp = USHORT( nAsp );
297 SetAspect( nSvAsp );
298 rStm.SeekRel( 4 ); //L-Index ueberlesen
299 rStm >> nAdvFlags;
300 rStm.SeekRel( 4 ); //Compression
301 UINT32 nWidth = 0;
302 UINT32 nHeight = 0;
303 UINT32 nSize = 0;
304 rStm >> nWidth >> nHeight >> nSize;
305 aSize.Width() = nWidth;
306 aSize.Height() = nHeight;
308 if( nFormat == FORMAT_GDIMETAFILE )
310 pMtf = new GDIMetaFile();
311 ReadWindowMetafile( rStm, *pMtf, NULL );
313 else if( nFormat == FORMAT_BITMAP )
315 pBmp = new Bitmap();
316 rStm >> *pBmp;
318 else
320 BYTE * p = new BYTE[ nSize ];
321 rStm.Read( p, nSize );
322 delete p;
323 return FALSE;
325 return TRUE;
328 /************************************************************************/
329 void Impl_OlePres::Write( SvStream & rStm )
331 WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE );
332 rStm << (INT32)(nJobLen +4); // immer leeres TargetDevice
333 if( nJobLen )
334 rStm.Write( pJob, nJobLen );
335 rStm << (UINT32)nAspect;
336 rStm << (INT32)-1; //L-Index immer -1
337 rStm << (INT32)nAdvFlags;
338 rStm << (INT32)0; //Compression
339 rStm << (INT32)aSize.Width();
340 rStm << (INT32)aSize.Height();
341 ULONG nPos = rStm.Tell();
342 rStm << (INT32)0;
344 if( GetFormat() == FORMAT_GDIMETAFILE && pMtf )
346 // Immer auf 1/100 mm, bis Mtf-Loesung gefunden
347 // Annahme (keine Skalierung, keine Org-Verschiebung)
348 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ),
349 "X-Skalierung im Mtf" );
350 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ),
351 "Y-Skalierung im Mtf" );
352 DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(),
353 "Origin-Verschiebung im Mtf" );
354 MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit();
355 if( MAP_100TH_MM != nMU )
357 Size aPrefS( pMtf->GetPrefSize() );
358 Size aS( aPrefS );
359 aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM );
361 pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ),
362 Fraction( aS.Height(), aPrefS.Height() ) );
363 pMtf->SetPrefMapMode( MAP_100TH_MM );
364 pMtf->SetPrefSize( aS );
366 WriteWindowMetafileBits( rStm, *pMtf );
368 else
370 DBG_ERROR( "unknown format" );
372 ULONG nEndPos = rStm.Tell();
373 rStm.Seek( nPos );
374 rStm << (UINT32)(nEndPos - nPos - 4);
375 rStm.Seek( nEndPos );
378 Impl_OlePres * CreateCache_Impl( SotStorage * pStor )
380 SotStorageStreamRef xOleObjStm =pStor->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ),
381 STREAM_READ | STREAM_NOCREATE );
382 if( xOleObjStm->GetError() )
383 return NULL;
384 SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm );
385 if( xOleObjStor->GetError() )
386 return NULL;
388 String aStreamName;
389 if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) ) ) )
390 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) );
391 else if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ) ) )
392 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) );
394 if( aStreamName.Len() == 0 )
395 return NULL;
398 for( USHORT i = 1; i < 10; i++ )
400 SotStorageStreamRef xStm = xOleObjStor->OpenSotStream( aStreamName,
401 STREAM_READ | STREAM_NOCREATE );
402 if( xStm->GetError() )
403 break;
405 xStm->SetBufferSize( 8192 );
406 Impl_OlePres * pEle = new Impl_OlePres( 0 );
407 if( pEle->Read( *xStm ) && !xStm->GetError() )
409 if( pEle->GetFormat() == FORMAT_GDIMETAFILE || pEle->GetFormat() == FORMAT_BITMAP )
410 return pEle;
412 delete pEle;
413 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres00" ) );
414 aStreamName += String( i );
416 return NULL;
421 //---------------------------------------------------------------------------
422 // Hilfs Klassen aus MSDFFDEF.HXX
423 //---------------------------------------------------------------------------
425 SvStream& operator>>( SvStream& rIn, DffRecordHeader& rRec )
427 rRec.nFilePos = rIn.Tell();
428 UINT16 nTmp(0);
429 rIn >> nTmp;
430 rRec.nImpVerInst = nTmp;
431 rRec.nRecVer = sal::static_int_cast< BYTE >(nTmp & 0x000F);
432 rRec.nRecInstance = nTmp >> 4;
433 rIn >> rRec.nRecType;
434 rIn >> rRec.nRecLen;
435 return rIn;
438 // Masse fuer dashed lines
439 #define LLEN_MIDDLE (450)
440 #define LLEN_SPACE_MIDDLE (360)
441 #define LLEN_LONG (LLEN_MIDDLE * 2)
442 #define LLEN_SPACE_LONG (LLEN_SPACE_MIDDLE + 20)
443 #define LLEN_POINT (LLEN_MIDDLE / 4)
444 #define LLEN_SPACE_POINT (LLEN_SPACE_MIDDLE / 4)
446 SvStream& operator>>( SvStream& rIn, DffPropSet& rRec )
448 rRec.InitializePropSet();
450 DffRecordHeader aHd;
451 rIn >> aHd;
452 UINT32 nPropCount = aHd.nRecInstance;
454 // FilePos der ComplexData merken
455 UINT32 nComplexDataFilePos = rIn.Tell() + ( nPropCount * 6 );
457 for( UINT32 nPropNum = 0; nPropNum < nPropCount; nPropNum++ )
459 sal_uInt16 nTmp;
460 sal_uInt32 nRecType, nContent, nContentEx = 0xffff0000;
461 rIn >> nTmp
462 >> nContent;
464 nRecType = nTmp & 0x3fff;
466 if ( nRecType > 0x3ff )
467 break;
468 if ( ( nRecType & 0x3f ) == 0x3f )
469 { // clear flags that have to be cleared
470 rRec.mpContents[ nRecType ] &= ( ( nContent >> 16 ) ^ 0xffffffff );
471 // set flags that have to be set
472 rRec.mpContents[ nRecType ] |= nContent;
473 nContentEx |= ( nContent >> 16 );
474 rRec.Replace( nRecType, (void*)nContentEx );
476 else
478 DffPropFlags aPropFlag = { 1, 0, 0, 0 };
479 if ( nTmp & 0x4000 )
480 aPropFlag.bBlip = sal_True;
481 if ( nTmp & 0x8000 )
482 aPropFlag.bComplex = sal_True;
483 if ( aPropFlag.bComplex && nContent && ( nComplexDataFilePos < aHd.GetRecEndFilePos() ) )
485 // normally nContent is the complete size of the complex property,
486 // but this is not always true for IMsoArrays ( what the hell is a IMsoArray ? )
488 // I love special threatments :-(
489 if ( ( nRecType == DFF_Prop_pVertices ) || ( nRecType == DFF_Prop_pSegmentInfo )
490 || ( nRecType == DFF_Prop_fillShadeColors ) || ( nRecType == DFF_Prop_lineDashStyle )
491 || ( nRecType == DFF_Prop_pWrapPolygonVertices ) || ( nRecType == DFF_Prop_connectorPoints )
492 || ( nRecType == DFF_Prop_Handles ) || ( nRecType == DFF_Prop_pFormulas )
493 || ( nRecType == DFF_Prop_textRectangles ) )
495 // now check if the current content size is possible, or 6 bytes too small
496 sal_uInt32 nOldPos = rIn.Tell();
497 sal_Int16 nNumElem, nNumElemReserved, nSize;
499 rIn.Seek( nComplexDataFilePos );
500 rIn >> nNumElem >> nNumElemReserved >> nSize;
501 if ( nNumElemReserved >= nNumElem )
503 // the size of these array elements is nowhere defined,
504 // what if the size is negative ?
505 // ok, we will make it positive and shift it.
506 // for -16 this works
507 if ( nSize < 0 )
508 nSize = ( -nSize ) >> 2;
509 sal_uInt32 nDataSize = (sal_uInt32)( nSize * nNumElem );
511 // sometimes the content size is 6 bytes too small (array header information is missing )
512 if ( nDataSize == nContent )
513 nContent += 6;
515 // check if array fits into the PropertyContainer
516 if ( ( nComplexDataFilePos + nContent ) > aHd.GetRecEndFilePos() )
517 nContent = 0;
519 else
520 nContent = 0;
521 rIn.Seek( nOldPos );
523 if ( nContent )
525 nContentEx = nComplexDataFilePos; // insert the filepos of this property;
526 nComplexDataFilePos += nContent; // store filepos, that is used for the next complex property
528 else // a complex property needs content
529 aPropFlag.bSet = sal_False; // otherwise something is wrong
531 rRec.mpContents[ nRecType ] = nContent;
532 rRec.mpFlags[ nRecType ] = aPropFlag;
533 rRec.Insert( nRecType, (void*)nContentEx );
536 aHd.SeekToEndOfRecord( rIn );
537 return rIn;
540 void DffPropSet::InitializePropSet() const
543 cmc:
544 " Boolean properties are grouped in bitfields by property set; note that
545 the Boolean properties in each property set are contiguous. They are saved
546 under the property ID of the last Boolean property in the set, and are
547 placed in the value field in reverse order starting with the last property
548 in the low bit. "
550 e.g.
552 fEditedWrap
553 fBehindDocument
554 fOnDblClickNotify
555 fIsButton
556 fOneD
557 fHidden
558 fPrint
560 are all part of a group and all are by default false except for fPrint,
561 which equates to a default bit sequence for the group of 0000001 -> 0x1
563 If at a later stage word sets fBehindDocument away from the default it
564 will be done by having a property named fPrint whose bitsequence will have
565 the fBehindDocument bit set. e.g. a DFF_Prop_fPrint with value 0x200020
566 has set bit 6 on so as to enable fBehindDocument (as well as disabling
567 everything else)
570 memset( ( (DffPropSet*) this )->mpFlags, 0, 0x400 * sizeof(DffPropFlags) );
571 ( (DffPropSet*) this )->Clear();
573 DffPropFlags nFlags = { 1, 0, 0, 1 };
575 ( (DffPropSet*) this )->mpContents[ DFF_Prop_LockAgainstGrouping ] = 0x0000; //0x01ff0000;
576 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_LockAgainstGrouping ] = nFlags;
577 ( (DffPropSet*) this )->Insert( DFF_Prop_LockAgainstGrouping, (void*)0xffff0000 );
579 ( (DffPropSet*) this )->mpContents[ DFF_Prop_FitTextToShape ] = 0x0010; //0x001f0010;
580 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_FitTextToShape ] = nFlags;
581 ( (DffPropSet*) this )->Insert( DFF_Prop_FitTextToShape, (void*)0xffff0000 );
583 ( (DffPropSet*) this )->mpContents[ DFF_Prop_gtextFStrikethrough ] = 0x0000; //0xffff0000;
584 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_gtextFStrikethrough ] = nFlags;
585 ( (DffPropSet*) this )->Insert( DFF_Prop_gtextFStrikethrough, (void*)0xffff0000 );
587 ( (DffPropSet*) this )->mpContents[ DFF_Prop_pictureActive ] = 0x0000; //0x000f0000;
588 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_pictureActive ] = nFlags;
589 ( (DffPropSet*) this )->Insert( DFF_Prop_pictureActive, (void*)0xffff0000 );
591 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fFillOK ] = 0x0039; //0x003f0039;
592 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fFillOK ] = nFlags;
593 ( (DffPropSet*) this )->Insert( DFF_Prop_fFillOK, (void*)0xffff0000 );
595 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoFillHitTest ] = 0x001c; //0x001f001c;
596 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoFillHitTest ] = nFlags;
597 ( (DffPropSet*) this )->Insert( DFF_Prop_fNoFillHitTest, (void*)0xffff0000 );
599 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoLineDrawDash ] = 0x001e; //0x001f000e;
600 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoLineDrawDash ] = nFlags;
601 ( (DffPropSet*) this )->Insert( DFF_Prop_fNoLineDrawDash, (void*)0xffff0000 );
603 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fshadowObscured ] = 0x0000; //0x00030000;
604 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fshadowObscured ] = nFlags;
605 ( (DffPropSet*) this )->Insert( DFF_Prop_fshadowObscured, (void*)0xffff0000 );
607 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fPerspective ] = 0x0000; //0x00010000;
608 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPerspective ] = nFlags;
609 ( (DffPropSet*) this )->Insert( DFF_Prop_fPerspective, (void*)0xffff0000 );
611 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DLightFace ] = 0x0001; //0x000f0001;
612 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DLightFace ] = nFlags;
613 ( (DffPropSet*) this )->Insert( DFF_Prop_fc3DLightFace, (void*)0xffff0000 );
615 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DFillHarsh ] = 0x0016; //0x001f0016;
616 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DFillHarsh ] = nFlags;
617 ( (DffPropSet*) this )->Insert( DFF_Prop_fc3DFillHarsh, (void*)0xffff0000 );
619 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fBackground ] = 0x0000; //0x001f0000;
620 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fBackground ] = nFlags;
621 ( (DffPropSet*) this )->Insert( DFF_Prop_fBackground, (void*)0xffff0000 );
623 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fCalloutLengthSpecified ] = 0x0010; //0x00ef0010;
624 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fCalloutLengthSpecified ] = nFlags;
625 ( (DffPropSet*) this )->Insert( DFF_Prop_fCalloutLengthSpecified, (void*)0xffff0000 );
627 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fPrint ] = 0x0001; //0x00ef0001;
628 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPrint ] = nFlags;
629 ( (DffPropSet*) this )->Insert( DFF_Prop_fPrint, (void*)0xffff0000 );
631 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fillColor ] = 0xffffff;
632 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fillColor ] = nFlags;
633 ( (DffPropSet*) this )->Insert( DFF_Prop_fillColor, (void*)0xffff0000 );
636 void DffPropSet::Merge( DffPropSet& rMaster ) const
638 for ( void* pDummy = rMaster.First(); pDummy; pDummy = rMaster.Next() )
640 UINT32 nRecType = rMaster.GetCurKey();
641 if ( ( nRecType & 0x3f ) == 0x3f ) // this is something called FLAGS
643 UINT32 nCurrentFlags = mpContents[ nRecType ];
644 UINT32 nMergeFlags = rMaster.mpContents[ nRecType ];
645 nMergeFlags &= ( nMergeFlags >> 16 ) | 0xffff0000; // clearing low word
646 nMergeFlags &= ( ( nCurrentFlags & 0xffff0000 ) // remove allready hard set
647 | ( nCurrentFlags >> 16 ) ) ^ 0xffffffff; // attributes from mergeflags
648 nCurrentFlags &= ( ( nMergeFlags & 0xffff0000 ) // apply zero master bits
649 | ( nMergeFlags >> 16 ) ) ^ 0xffffffff;
650 nCurrentFlags |= (UINT16)nMergeFlags; // apply filled master bits
651 ( (DffPropSet*) this )->mpContents[ nRecType ] = nCurrentFlags;
654 sal_uInt32 nNewContentEx = (sal_uInt32)(sal_uIntPtr)rMaster.GetCurObject();
655 if ( ((DffPropSet*)this)->Seek( nRecType ) )
656 nNewContentEx |= (sal_uInt32)(sal_uIntPtr)GetCurObject();
657 ( (DffPropSet*) this )->Replace( nRecType, (void*)nNewContentEx );
659 else
661 if ( !IsProperty( nRecType ) || !IsHardAttribute( nRecType ) )
663 ( (DffPropSet*) this )->mpContents[ nRecType ] = rMaster.mpContents[ nRecType ];
664 DffPropFlags nFlags( rMaster.mpFlags[ nRecType ] );
665 nFlags.bSoftAttr = TRUE;
666 ( (DffPropSet*) this )->mpFlags[ nRecType ] = nFlags;
667 ( (DffPropSet*) this )->Insert( nRecType, pDummy );
673 BOOL DffPropSet::IsHardAttribute( UINT32 nId ) const
675 BOOL bRetValue = TRUE;
676 nId &= 0x3ff;
677 if ( ( nId & 0x3f ) >= 48 ) // is this a flag id
679 if ( ((DffPropSet*)this)->Seek( nId | 0x3f ) )
681 sal_uInt32 nContentEx = (sal_uInt32)(sal_uIntPtr)GetCurObject();
682 bRetValue = ( nContentEx & ( 1 << ( 0xf - ( nId & 0xf ) ) ) ) != 0;
685 else
686 bRetValue = ( mpFlags[ nId ].bSoftAttr == 0 );
687 return bRetValue;
690 UINT32 DffPropSet::GetPropertyValue( UINT32 nId, UINT32 nDefault ) const
692 nId &= 0x3ff;
693 return ( mpFlags[ nId ].bSet ) ? mpContents[ nId ] : nDefault;
696 bool DffPropSet::GetPropertyBool( UINT32 nId, bool bDefault ) const
698 UINT32 nBaseId = nId | 31; // base ID to get the UINT32 property value
699 UINT32 nMask = 1 << (nBaseId - nId); // bit mask of the boolean property
701 UINT32 nPropValue = GetPropertyValue( nBaseId, bDefault ? nMask : 0 );
702 return (nPropValue & nMask) != 0;
705 ::rtl::OUString DffPropSet::GetPropertyString( UINT32 nId, SvStream& rStrm ) const
707 sal_Size nOldPos = rStrm.Tell();
708 ::rtl::OUStringBuffer aBuffer;
709 sal_uInt32 nBufferSize = GetPropertyValue( nId );
710 if( (nBufferSize > 0) && SeekToContent( nId, rStrm ) )
712 sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufferSize / 2 );
713 aBuffer.ensureCapacity( nStrLen );
714 for( sal_Int32 nCharIdx = 0; nCharIdx < nStrLen; ++nCharIdx )
716 sal_uInt16 nChar = 0;
717 rStrm >> nChar;
718 if( nChar > 0 )
719 aBuffer.append( static_cast< sal_Unicode >( nChar ) );
720 else
721 break;
724 rStrm.Seek( nOldPos );
725 return aBuffer.makeStringAndClear();
728 void DffPropSet::SetPropertyValue( UINT32 nId, UINT32 nValue ) const
730 if ( !mpFlags[ nId ].bSet )
732 ( (DffPropSet*) this )->Insert( nId, (void*)nValue );
733 ( (DffPropSet*) this )->mpFlags[ nId ].bSet = TRUE;
735 ( (DffPropSet*) this )->mpContents[ nId ] = nValue;
738 BOOL DffPropSet::SeekToContent( UINT32 nRecType, SvStream& rStrm ) const
740 nRecType &= 0x3ff;
741 if ( mpFlags[ nRecType ].bSet )
743 if ( mpFlags[ nRecType ].bComplex )
745 if ( ((DffPropSet*)this)->Seek( nRecType ) )
747 sal_uInt32 nOffset = (sal_uInt32)(sal_uIntPtr)GetCurObject();
748 if ( nOffset && ( ( nOffset & 0xffff0000 ) != 0xffff0000 ) )
750 rStrm.Seek( nOffset );
751 return TRUE;
756 return FALSE;
759 DffPropertyReader::DffPropertyReader( const SvxMSDffManager& rMan ) :
760 rManager( rMan ),
761 pDefaultPropSet( NULL )
763 InitializePropSet();
766 void DffPropertyReader::SetDefaultPropSet( SvStream& rStCtrl, UINT32 nOffsDgg ) const
768 delete pDefaultPropSet;
769 UINT32 nMerk = rStCtrl.Tell();
770 rStCtrl.Seek( nOffsDgg );
771 DffRecordHeader aRecHd;
772 rStCtrl >> aRecHd;
773 if ( aRecHd.nRecType == DFF_msofbtDggContainer )
775 if ( rManager.SeekToRec( rStCtrl, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
777 ( (DffPropertyReader*) this )->pDefaultPropSet = new DffPropSet;
778 rStCtrl >> *pDefaultPropSet;
781 rStCtrl.Seek( nMerk );
784 #ifdef DBG_CUSTOMSHAPE
785 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData, UINT32 nShapeId ) const
786 #else
787 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData ) const
788 #endif
790 ULONG nFilePos = rIn.Tell();
791 rIn >> (DffPropertyReader&)*this;
793 if ( IsProperty( DFF_Prop_hspMaster ) )
795 if ( rManager.SeekToShape( rIn, pClientData, GetPropertyValue( DFF_Prop_hspMaster ) ) )
797 DffRecordHeader aRecHd;
798 rIn >> aRecHd;
799 if ( rManager.SeekToRec( rIn, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
801 DffPropSet aMasterPropSet;
802 rIn >> aMasterPropSet;
803 Merge( aMasterPropSet );
807 // if ( pDefaultPropSet )
808 // Merge( *( pDefaultPropSet ) );
810 ( (DffPropertyReader*) this )->mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) );
812 #ifdef DBG_CUSTOMSHAPE
814 String aURLStr;
816 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( String( RTL_CONSTASCII_STRINGPARAM( "d:\\ashape.dbg" ) ), aURLStr ) )
818 SvStream* pOut = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_WRITE );
820 if( pOut )
822 pOut->Seek( STREAM_SEEK_TO_END );
824 if ( IsProperty( DFF_Prop_adjustValue ) || IsProperty( DFF_Prop_pVertices ) )
826 pOut->WriteLine( "" );
827 ByteString aString( "ShapeId: " );
828 aString.Append( ByteString::CreateFromInt32( nShapeId ) );
829 pOut->WriteLine( aString );
831 for ( sal_uInt32 i = DFF_Prop_adjustValue; i <= DFF_Prop_adjust10Value; i++ )
833 if ( IsProperty( i ) )
835 ByteString aString( "Prop_adjustValue" );
836 aString.Append( ByteString::CreateFromInt32( ( i - DFF_Prop_adjustValue ) + 1 ) );
837 aString.Append( ":" );
838 aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
839 pOut->WriteLine( aString );
842 sal_Int32 i;
843 for ( i = 320; i < 383; i++ )
845 if ( ( i >= DFF_Prop_adjustValue ) && ( i <= DFF_Prop_adjust10Value ) )
846 continue;
847 if ( IsProperty( i ) )
849 if ( SeekToContent( i, rIn ) )
851 INT32 nLen = (INT32)GetPropertyValue( i );
852 if ( nLen )
854 pOut->WriteLine( "" );
855 ByteString aDesc( "Property:" );
856 aDesc.Append( ByteString::CreateFromInt32( i ) );
857 aDesc.Append( ByteString( " Size:" ) );
858 aDesc.Append( ByteString::CreateFromInt32( nLen ) );
859 pOut->WriteLine( aDesc );
860 INT16 nNumElem, nNumElemMem, nNumSize;
861 rIn >> nNumElem >> nNumElemMem >> nNumSize;
862 aDesc = ByteString( "Entries: " );
863 aDesc.Append( ByteString::CreateFromInt32( nNumElem ) );
864 aDesc.Append( ByteString( " Size:" ) );
865 aDesc.Append( ByteString::CreateFromInt32( nNumSize ) );
866 pOut->WriteLine( aDesc );
867 if ( nNumSize < 0 )
868 nNumSize = ( ( -nNumSize ) >> 2 );
869 if ( !nNumSize )
870 nNumSize = 16;
871 nLen -= 6;
872 while ( nLen > 0 )
874 ByteString aString;
875 for ( UINT32 j = 0; nLen && ( j < ( nNumSize >> 1 ) ); j++ )
877 for ( UINT32 k = 0; k < 2; k++ )
879 if ( nLen )
881 BYTE nVal;
882 rIn >> nVal;
883 if ( ( nVal >> 4 ) > 9 )
884 *pOut << (BYTE)( ( nVal >> 4 ) + 'A' - 10 );
885 else
886 *pOut << (BYTE)( ( nVal >> 4 ) + '0' );
888 if ( ( nVal & 0xf ) > 9 )
889 *pOut << (BYTE)( ( nVal & 0xf ) + 'A' - 10 );
890 else
891 *pOut << (BYTE)( ( nVal & 0xf ) + '0' );
893 nLen--;
896 *pOut << (char)( ' ' );
898 pOut->WriteLine( aString );
902 else
904 ByteString aString( "Property" );
905 aString.Append( ByteString::CreateFromInt32( i ) );
906 aString.Append( ":" );
907 aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
908 pOut->WriteLine( aString );
913 delete pOut;
917 #endif
919 rIn.Seek( nFilePos );
923 INT32 DffPropertyReader::Fix16ToAngle( INT32 nContent ) const
925 INT32 nAngle = 0;
926 if ( nContent )
928 nAngle = ( (INT16)( nContent >> 16) * 100L ) + ( ( ( nContent & 0x0000ffff) * 100L ) >> 16 );
929 nAngle = NormAngle360( -nAngle );
931 return nAngle;
934 DffPropertyReader::~DffPropertyReader()
936 delete pDefaultPropSet;
939 ////////////////////////////////////////////////////////////////////////////////////////////////////
941 SvStream& operator>>( SvStream& rIn, SvxMSDffConnectorRule& rRule )
943 rIn >> rRule.nRuleId
944 >> rRule.nShapeA
945 >> rRule.nShapeB
946 >> rRule.nShapeC
947 >> rRule.ncptiA
948 >> rRule.ncptiB;
950 return rIn;
953 SvxMSDffSolverContainer::SvxMSDffSolverContainer()
957 SvxMSDffSolverContainer::~SvxMSDffSolverContainer()
959 for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)aCList.First();
960 pPtr; pPtr = (SvxMSDffConnectorRule*)aCList.Next() )
961 delete pPtr;
964 SvStream& operator>>( SvStream& rIn, SvxMSDffSolverContainer& rContainer )
966 DffRecordHeader aHd;
967 rIn >> aHd;
968 if ( aHd.nRecType == DFF_msofbtSolverContainer )
970 DffRecordHeader aCRule;
971 while ( ( rIn.GetError() == 0 ) && ( rIn.Tell() < aHd.GetRecEndFilePos() ) )
973 rIn >> aCRule;
974 if ( aCRule.nRecType == DFF_msofbtConnectorRule )
976 SvxMSDffConnectorRule* pRule = new SvxMSDffConnectorRule;
977 rIn >> *pRule;
978 rContainer.aCList.Insert( pRule, LIST_APPEND );
980 aCRule.SeekToEndOfRecord( rIn );
983 return rIn;
986 void SvxMSDffManager::SolveSolver( const SvxMSDffSolverContainer& rSolver )
988 sal_Int32 i, nCnt;
989 for ( i = 0, nCnt = rSolver.aCList.Count(); i < nCnt; i++ )
991 SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)rSolver.aCList.GetObject( i );
992 if ( pPtr->pCObj )
994 for ( int nN = 0; nN < 2; nN++ )
996 SdrObject* pO;
997 sal_uInt32 nC, nSpFlags;
998 sal_Bool bTail;
999 if ( !nN )
1001 bTail = sal_True;
1002 pO = pPtr->pAObj;
1003 nC = pPtr->ncptiA;
1004 nSpFlags = pPtr->nSpFlagsA;
1006 else
1008 bTail = sal_False;
1009 pO = pPtr->pBObj;
1010 nC = pPtr->ncptiB;
1011 nSpFlags = pPtr->nSpFlagsB;
1013 if ( pO )
1015 Any aAny;
1016 SdrGluePoint aGluePoint;
1017 Reference< XShape > aXShape( pO->getUnoShape(), UNO_QUERY );
1018 Reference< XShape > aXConnector( pPtr->pCObj->getUnoShape(), UNO_QUERY );
1019 SdrGluePointList* pList = pO->ForceGluePointList();
1021 sal_Bool bValidGluePoint = sal_False;
1022 sal_Int32 nId = nC;
1023 sal_uInt32 nInventor = pO->GetObjInventor();
1025 if( nInventor == SdrInventor )
1027 sal_uInt32 nObjId = pO->GetObjIdentifier();
1028 switch( nObjId )
1030 case OBJ_GRUP :
1031 case OBJ_GRAF :
1032 case OBJ_RECT :
1033 case OBJ_TEXT :
1034 case OBJ_PAGE :
1035 case OBJ_TEXTEXT :
1036 case OBJ_wegFITTEXT :
1037 case OBJ_wegFITALLTEXT :
1038 case OBJ_TITLETEXT :
1039 case OBJ_OUTLINETEXT :
1041 if ( nC & 1 )
1043 if ( nSpFlags & SP_FFLIPH )
1044 nC ^= 2; // 1 <-> 3
1046 else
1048 if ( nSpFlags & SP_FFLIPV )
1049 nC ^= 1; // 0 <-> 2
1051 switch( nC )
1053 case 0 :
1054 nId = 0; // SDRVERTALIGN_TOP;
1055 break;
1056 case 1 :
1057 nId = 3; // SDRHORZALIGN_RIGHT;
1058 break;
1059 case 2 :
1060 nId = 2; // SDRVERTALIGN_BOTTOM;
1061 break;
1062 case 3 :
1063 nId = 1; // SDRHORZALIGN_LEFT;
1064 break;
1066 if ( nId <= 3 )
1067 bValidGluePoint = sal_True;
1069 break;
1070 case OBJ_POLY :
1071 case OBJ_PLIN :
1072 case OBJ_LINE :
1073 case OBJ_PATHLINE :
1074 case OBJ_PATHFILL :
1075 case OBJ_FREELINE :
1076 case OBJ_FREEFILL :
1077 case OBJ_SPLNLINE :
1078 case OBJ_SPLNFILL :
1079 case OBJ_PATHPOLY :
1080 case OBJ_PATHPLIN :
1082 if ( pList && ( pList->GetCount() > nC ) )
1084 bValidGluePoint = sal_True;
1085 nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
1087 else
1089 sal_Bool bNotFound = sal_True;
1091 PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aXShape ) );
1092 sal_uInt16 k, j, nPolySize = aPolyPoly.Count();
1093 if ( nPolySize )
1095 sal_uInt32 nPointCount = 0;
1096 Rectangle aBoundRect( aPolyPoly.GetBoundRect() );
1097 if ( aBoundRect.GetWidth() && aBoundRect.GetHeight() )
1099 for ( k = 0; bNotFound && ( k < nPolySize ); k++ )
1101 const Polygon& rPolygon = aPolyPoly.GetObject( k );
1102 for ( j = 0; bNotFound && ( j < rPolygon.GetSize() ); j++ )
1104 PolyFlags eFlags = rPolygon.GetFlags( j );
1105 if ( eFlags == POLY_NORMAL )
1107 if ( nC == nPointCount )
1109 const Point& rPoint = rPolygon.GetPoint( j );
1110 double fXRel = rPoint.X() - aBoundRect.Left();
1111 double fYRel = rPoint.Y() - aBoundRect.Top();
1112 sal_Int32 nWidth = aBoundRect.GetWidth();
1113 if ( !nWidth )
1114 nWidth = 1;
1115 sal_Int32 nHeight= aBoundRect.GetHeight();
1116 if ( !nHeight )
1117 nHeight = 1;
1118 fXRel /= (double)nWidth;
1119 fXRel *= 10000;
1120 fYRel /= (double)nHeight;
1121 fYRel *= 10000;
1122 aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) );
1123 aGluePoint.SetPercent( sal_True );
1124 aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
1125 aGluePoint.SetEscDir( SDRESC_SMART );
1126 nId = (sal_Int32)((*pList)[ pList->Insert( aGluePoint ) ].GetId() + 3 );
1127 bNotFound = sal_False;
1129 nPointCount++;
1135 if ( !bNotFound )
1137 bValidGluePoint = sal_True;
1141 break;
1143 case OBJ_CUSTOMSHAPE :
1145 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pO)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1146 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
1147 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
1148 sal_Int16 nGluePointType = EnhancedCustomShapeGluePointType::SEGMENTS;
1149 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePointType );
1150 if ( pAny )
1151 *pAny >>= nGluePointType;
1152 else
1154 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
1155 rtl::OUString sShapeType;
1156 pAny = aGeometryItem.GetPropertyValueByName( sType );
1157 if ( pAny )
1158 *pAny >>= sShapeType;
1159 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
1160 nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType );
1162 if ( nGluePointType == EnhancedCustomShapeGluePointType::CUSTOM )
1164 if ( pList && ( pList->GetCount() > nC ) )
1166 bValidGluePoint = sal_True;
1167 nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
1170 else if ( nGluePointType == EnhancedCustomShapeGluePointType::RECT )
1172 if ( nC & 1 )
1174 if ( nSpFlags & SP_FFLIPH )
1175 nC ^= 2; // 1 <-> 3
1177 else
1179 if ( nSpFlags & SP_FFLIPV )
1180 nC ^= 1; // 0 <-> 2
1182 switch( nC )
1184 case 0 :
1185 nId = 0; // SDRVERTALIGN_TOP;
1186 break;
1187 case 1 :
1188 nId = 3; // SDRHORZALIGN_RIGHT;
1189 break;
1190 case 2 :
1191 nId = 2; // SDRVERTALIGN_BOTTOM;
1192 break;
1193 case 3 :
1194 nId = 1; // SDRHORZALIGN_LEFT;
1195 break;
1197 if ( nId <= 3 )
1198 bValidGluePoint = sal_True;
1200 else if ( nGluePointType == EnhancedCustomShapeGluePointType::SEGMENTS )
1202 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
1203 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
1205 sal_uInt32 k, nPt = nC;
1206 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
1207 pAny = aGeometryItem.GetPropertyValueByName( sPath, sSegments );
1208 if ( pAny )
1210 if ( *pAny >>= aSegments )
1212 for ( nPt = 0, k = 1; nC && ( k < (sal_uInt32)aSegments.getLength() ); k++ )
1214 sal_Int16 j, nCnt2 = aSegments[ k ].Count;
1215 if ( aSegments[ k ].Command != EnhancedCustomShapeSegmentCommand::UNKNOWN )
1217 for ( j = 0; nC && ( j < nCnt2 ); j++ )
1219 switch( aSegments[ k ].Command )
1221 case EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
1222 case EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
1223 case EnhancedCustomShapeSegmentCommand::LINETO :
1224 case EnhancedCustomShapeSegmentCommand::MOVETO :
1226 nC--;
1227 nPt++;
1229 break;
1230 case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
1231 case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
1232 break;
1234 case EnhancedCustomShapeSegmentCommand::CURVETO :
1236 nC--;
1237 nPt += 3;
1239 break;
1241 case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
1242 case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
1244 nC--;
1245 nPt += 3;
1247 break;
1248 case EnhancedCustomShapeSegmentCommand::ARCTO :
1249 case EnhancedCustomShapeSegmentCommand::ARC :
1250 case EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
1251 case EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
1253 nC--;
1254 nPt += 4;
1256 break;
1263 pAny = aGeometryItem.GetPropertyValueByName( sPath, sCoordinates );
1264 if ( pAny )
1266 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
1267 *pAny >>= aCoordinates;
1268 if ( nPt < (sal_uInt32)aCoordinates.getLength() )
1270 nId = 4;
1271 com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPara = aCoordinates[ nPt ];
1272 sal_Int32 nX = 0, nY = 0;
1273 if ( ( rPara.First.Value >>= nX ) && ( rPara.Second.Value >>= nY ) )
1275 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
1276 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
1277 pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePoints );
1278 if ( pAny )
1279 *pAny >>= aGluePoints;
1280 sal_Int32 nGluePoints = aGluePoints.getLength();
1281 aGluePoints.realloc( nGluePoints + 1 );
1282 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].First, nX );
1283 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].Second, nY );
1284 PropertyValue aProp;
1285 aProp.Name = sGluePoints;
1286 aProp.Value <<= aGluePoints;
1287 aGeometryItem.SetPropertyValue( sPath, aProp );
1288 bValidGluePoint = sal_True;
1289 ((SdrObjCustomShape*)pO)->SetMergedItem( aGeometryItem );
1290 SdrGluePointList* pLst = pO->ForceGluePointList();
1291 if ( pLst->GetCount() > nGluePoints )
1292 nId = (sal_Int32)((*pLst)[ (sal_uInt16)nGluePoints ].GetId() + 3 );
1298 break;
1300 if ( bValidGluePoint )
1302 Reference< XPropertySet > xPropSet( aXConnector, UNO_QUERY );
1303 if ( xPropSet.is() )
1305 if ( nN )
1307 String aPropName( RTL_CONSTASCII_USTRINGPARAM( "EndShape" ) );
1308 aAny <<= aXShape;
1309 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1310 aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "EndGluePointIndex" ) );
1311 aAny <<= nId;
1312 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1314 else
1316 String aPropName( RTL_CONSTASCII_USTRINGPARAM( "StartShape" ) );
1317 aAny <<= aXShape;
1318 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1319 aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "StartGluePointIndex" ) );
1320 aAny <<= nId;
1321 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1324 // Not sure what this is good for, repaint or broadcast of object change.
1325 //( Thus i am adding repaint here
1326 pO->SetChanged();
1327 pO->BroadcastObjectChange();
1337 ////////////////////////////////////////////////////////////////////////////////////////////////////
1339 static basegfx::B2DPolygon GetLineArrow( const sal_Int32 nLineWidth, const MSO_LineEnd eLineEnd,
1340 const MSO_LineEndWidth eLineWidth, const MSO_LineEndLength eLineLenght,
1341 sal_Int32& rnArrowWidth, sal_Bool& rbArrowCenter,
1342 String& rsArrowName )
1344 basegfx::B2DPolygon aRetval;
1345 double fLineWidth = nLineWidth < 70 ? 70.0 : nLineWidth;
1346 double fLenghtMul, fWidthMul;
1347 sal_Int32 nLineNumber;
1348 switch( eLineLenght )
1350 default :
1351 case mso_lineMediumLenArrow : fLenghtMul = 3.0; nLineNumber = 2; break;
1352 case mso_lineShortArrow : fLenghtMul = 2.0; nLineNumber = 1; break;
1353 case mso_lineLongArrow : fLenghtMul = 5.0; nLineNumber = 3; break;
1355 switch( eLineWidth )
1357 default :
1358 case mso_lineMediumWidthArrow : fWidthMul = 3.0; nLineNumber += 3; break;
1359 case mso_lineNarrowArrow : fWidthMul = 2.0; break;
1360 case mso_lineWideArrow : fWidthMul = 5.0; nLineNumber += 6; break;
1362 rbArrowCenter = sal_False;
1363 switch ( eLineEnd )
1365 case mso_lineArrowEnd :
1367 basegfx::B2DPolygon aTriangle;
1368 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, 0.0 ));
1369 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth ));
1370 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
1371 aTriangle.setClosed(true);
1372 aRetval = aTriangle;
1373 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowEnd " ), RTL_TEXTENCODING_UTF8 );
1375 break;
1377 case mso_lineArrowOpenEnd :
1379 switch( eLineLenght )
1381 default :
1382 case mso_lineMediumLenArrow : fLenghtMul = 4.5; break;
1383 case mso_lineShortArrow : fLenghtMul = 3.5; break;
1384 case mso_lineLongArrow : fLenghtMul = 6.0; break;
1386 switch( eLineWidth )
1388 default :
1389 case mso_lineMediumWidthArrow : fWidthMul = 4.5; break;
1390 case mso_lineNarrowArrow : fWidthMul = 3.5; break;
1391 case mso_lineWideArrow : fWidthMul = 6.0; break;
1393 basegfx::B2DPolygon aTriangle;
1394 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1395 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth * 0.91 ));
1396 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.85, fLenghtMul * fLineWidth ));
1397 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, fLenghtMul * fLineWidth * 0.36 ));
1398 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.15, fLenghtMul * fLineWidth ));
1399 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.91 ));
1400 aTriangle.setClosed(true);
1401 aRetval = aTriangle;
1402 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOpenEnd " ), RTL_TEXTENCODING_UTF8 );
1404 break;
1405 case mso_lineArrowStealthEnd :
1407 basegfx::B2DPolygon aTriangle;
1408 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1409 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth ));
1410 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth * 0.60 ));
1411 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
1412 aTriangle.setClosed(true);
1413 aRetval = aTriangle;
1414 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowStealthEnd " ), RTL_TEXTENCODING_UTF8 );
1416 break;
1417 case mso_lineArrowDiamondEnd :
1419 basegfx::B2DPolygon aTriangle;
1420 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1421 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth * 0.50 ));
1422 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth ));
1423 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.50 ));
1424 aTriangle.setClosed(true);
1425 aRetval = aTriangle;
1426 rbArrowCenter = sal_True;
1427 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowDiamondEnd " ), RTL_TEXTENCODING_UTF8 );
1429 break;
1430 case mso_lineArrowOvalEnd :
1432 aRetval = XPolygon( Point( (sal_Int32)( fWidthMul * fLineWidth * 0.50 ), 0 ),
1433 (sal_Int32)( fWidthMul * fLineWidth * 0.50 ),
1434 (sal_Int32)( fLenghtMul * fLineWidth * 0.50 ), 0, 3600 ).getB2DPolygon();
1435 rbArrowCenter = sal_True;
1436 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOvalEnd " ), RTL_TEXTENCODING_UTF8 );
1438 break;
1439 default: break;
1441 rsArrowName.Append( String::CreateFromInt32( nLineNumber ) );
1442 rnArrowWidth = (sal_Int32)( fLineWidth * fWidthMul );
1444 return aRetval;
1447 void DffPropertyReader::ApplyLineAttributes( SfxItemSet& rSet, const MSO_SPT eShapeType ) const // #i28269#
1449 UINT32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
1451 if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( eShapeType ))
1453 nLineFlags &= ~0x08;
1456 if ( nLineFlags & 8 )
1458 // Linienattribute
1459 sal_Int32 nLineWidth = (INT32)GetPropertyValue( DFF_Prop_lineWidth, 9525 );
1461 MSO_LineDashing eLineDashing = (MSO_LineDashing)GetPropertyValue( DFF_Prop_lineDashing, mso_lineSolid );
1462 if ( eLineDashing == mso_lineSolid )
1463 rSet.Put(XLineStyleItem( XLINE_SOLID ) );
1464 else
1466 // MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare );
1468 XDashStyle eDash = XDASH_RECT;
1469 sal_uInt16 nDots = 1;
1470 sal_uInt32 nDotLen = nLineWidth / 360;
1471 sal_uInt16 nDashes = 0;
1472 sal_uInt32 nDashLen = ( 8 * nLineWidth ) / 360;
1473 sal_uInt32 nDistance = ( 3 * nLineWidth ) / 360;;
1475 switch ( eLineDashing )
1477 default:
1478 case mso_lineDotSys :
1480 nDots = 1;
1481 nDashes = 0;
1482 nDistance = nDotLen;
1484 break;
1486 case mso_lineDashGEL :
1488 nDots = 0;
1489 nDashes = 1;
1490 nDashLen = ( 4 * nLineWidth ) / 360;
1492 break;
1494 case mso_lineDashDotGEL :
1496 nDots = 1;
1497 nDashes = 1;
1498 nDashLen = ( 4 * nLineWidth ) / 360;
1500 break;
1502 case mso_lineLongDashGEL :
1504 nDots = 0;
1505 nDashes = 1;
1507 break;
1509 case mso_lineLongDashDotGEL :
1511 nDots = 1;
1512 nDashes = 1;
1514 break;
1516 case mso_lineLongDashDotDotGEL:
1518 nDots = 2;
1519 nDashes = 1;
1521 break;
1524 rSet.Put( XLineDashItem( String(), XDash( eDash, nDots, nDotLen, nDashes, nDashLen, nDistance ) ) );
1525 rSet.Put( XLineStyleItem( XLINE_DASH ) );
1527 rSet.Put( XLineColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_lineColor ), DFF_Prop_lineColor ) ) );
1528 if ( IsProperty( DFF_Prop_lineOpacity ) )
1530 double nTrans = GetPropertyValue(DFF_Prop_lineOpacity, 0x10000);
1531 nTrans = (nTrans * 100) / 65536;
1532 rSet.Put(XLineTransparenceItem(
1533 sal_uInt16(100 - ::rtl::math::round(nTrans))));
1536 rManager.ScaleEmu( nLineWidth );
1537 rSet.Put( XLineWidthItem( nLineWidth ) );
1539 // SJ: LineJoint (setting each time a line is set, because our internal joint type has another default)
1540 MSO_LineJoin eLineJointDefault = mso_lineJoinMiter;
1541 if ( eShapeType == mso_sptMin )
1542 eLineJointDefault = mso_lineJoinRound;
1543 MSO_LineJoin eLineJoint = (MSO_LineJoin)GetPropertyValue( DFF_Prop_lineJoinStyle, eLineJointDefault );
1544 XLineJoint eXLineJoint( XLINEJOINT_MITER );
1545 if ( eLineJoint == mso_lineJoinBevel )
1546 eXLineJoint = XLINEJOINT_BEVEL;
1547 else if ( eLineJoint == mso_lineJoinRound )
1548 eXLineJoint = XLINEJOINT_ROUND;
1549 rSet.Put( XLineJointItem( eXLineJoint ) );
1551 if ( nLineFlags & 0x10 )
1553 ///////////////
1554 // LineStart //
1555 ///////////////
1556 if ( IsProperty( DFF_Prop_lineStartArrowhead ) )
1558 MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineStartArrowhead );
1559 MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineStartArrowWidth, mso_lineMediumWidthArrow );
1560 MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineStartArrowLength, mso_lineMediumLenArrow );
1562 sal_Int32 nArrowWidth;
1563 sal_Bool bArrowCenter;
1564 String aArrowName;
1565 basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName ));
1567 rSet.Put( XLineStartWidthItem( nArrowWidth ) );
1568 rSet.Put( XLineStartItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
1569 rSet.Put( XLineStartCenterItem( bArrowCenter ) );
1571 /////////////
1572 // LineEnd //
1573 /////////////
1574 if ( IsProperty( DFF_Prop_lineEndArrowhead ) )
1576 MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineEndArrowhead );
1577 MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineEndArrowWidth, mso_lineMediumWidthArrow );
1578 MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineEndArrowLength, mso_lineMediumLenArrow );
1580 sal_Int32 nArrowWidth;
1581 sal_Bool bArrowCenter;
1582 String aArrowName;
1583 basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName ));
1585 rSet.Put( XLineEndWidthItem( nArrowWidth ) );
1586 rSet.Put( XLineEndItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
1587 rSet.Put( XLineEndCenterItem( bArrowCenter ) );
1589 if ( IsProperty( DFF_Prop_lineEndCapStyle ) )
1591 MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle );
1592 const SfxPoolItem* pPoolItem = NULL;
1593 if ( rSet.GetItemState( XATTR_LINEDASH, FALSE, &pPoolItem ) == SFX_ITEM_SET )
1595 XDashStyle eNewStyle = XDASH_RECT;
1596 if ( eLineCap == mso_lineEndCapRound )
1597 eNewStyle = XDASH_ROUND;
1598 const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue();
1599 if ( rOldDash.GetDashStyle() != eNewStyle )
1601 XDash aNew( rOldDash );
1602 aNew.SetDashStyle( eNewStyle );
1603 rSet.Put( XLineDashItem( XubString(), aNew ) );
1609 else
1610 rSet.Put( XLineStyleItem( XLINE_NONE ) );
1614 void DffPropertyReader::ApplyFillAttributes( SvStream& rIn, SfxItemSet& rSet, const MSO_SPT eShapeType ) const
1616 UINT32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
1618 if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( eShapeType ))
1620 nFillFlags &= ~0x10;
1623 if ( nFillFlags & 0x10 )
1625 MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
1626 XFillStyle eXFill = XFILL_NONE;
1627 switch( eMSO_FillType )
1629 case mso_fillSolid : // Fill with a solid color
1630 eXFill = XFILL_SOLID;
1631 break;
1632 case mso_fillPattern : // Fill with a pattern (bitmap)
1633 case mso_fillTexture : // A texture (pattern with its own color map)
1634 case mso_fillPicture : // Center a picture in the shape
1635 eXFill = XFILL_BITMAP;
1636 break;
1637 case mso_fillShade : // Shade from start to end points
1638 case mso_fillShadeCenter : // Shade from bounding rectangle to end point
1639 case mso_fillShadeShape : // Shade from shape outline to end point
1640 case mso_fillShadeScale : // Similar to mso_fillShade, but the fillAngle
1641 case mso_fillShadeTitle : // special type - shade to title --- for PP
1642 eXFill = XFILL_GRADIENT;
1643 break;
1644 // case mso_fillBackground : // Use the background fill color/pattern
1645 default: break;
1647 rSet.Put( XFillStyleItem( eXFill ) );
1649 if (IsProperty(DFF_Prop_fillOpacity))
1651 double nTrans = GetPropertyValue(DFF_Prop_fillOpacity);
1652 nTrans = (nTrans * 100) / 65536;
1653 rSet.Put(XFillTransparenceItem(
1654 sal_uInt16(100 - ::rtl::math::round(nTrans))));
1657 if ( eXFill == XFILL_GRADIENT )
1659 sal_Int32 nAngle = 3600 - ( ( Fix16ToAngle( GetPropertyValue( DFF_Prop_fillAngle, 0 ) ) + 5 ) / 10 );
1661 // Rotationswinkel in Bereich zwingen
1662 while ( nAngle >= 3600 )
1663 nAngle -= 3600;
1664 while ( nAngle < 0 )
1665 nAngle += 3600;
1667 sal_Int32 nFocus = GetPropertyValue( DFF_Prop_fillFocus, 0 );
1668 XGradientStyle eGrad = XGRAD_LINEAR;
1669 sal_Int32 nChgColors = 0;
1671 if ( nFocus < 0 ) // Bei negativem Focus sind die Farben zu tauschen
1673 nFocus =- nFocus;
1674 nChgColors ^= 1;
1676 if( nFocus > 40 && nFocus < 60 )
1678 eGrad = XGRAD_AXIAL; // Besser gehts leider nicht
1681 USHORT nFocusX = (USHORT)nFocus;
1682 USHORT nFocusY = (USHORT)nFocus;
1684 switch( eMSO_FillType )
1686 case mso_fillShadeShape :
1688 eGrad = XGRAD_RECT;
1689 nFocusY = nFocusX = 50;
1690 nChgColors ^= 1;
1692 break;
1693 case mso_fillShadeCenter :
1695 eGrad = XGRAD_RECT;
1696 nFocusX = ( IsProperty( DFF_Prop_fillToRight ) ) ? 100 : 0;
1697 nFocusY = ( IsProperty( DFF_Prop_fillToBottom ) ) ? 100 : 0;
1698 nChgColors ^= 1;
1700 break;
1701 default: break;
1703 Color aCol1( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ) );
1704 Color aCol2( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ) );
1706 if ( nChgColors )
1708 Color aZwi( aCol1 );
1709 aCol1 = aCol2;
1710 aCol2 = aZwi;
1712 XGradient aGrad( aCol2, aCol1, eGrad, nAngle, nFocusX, nFocusY );
1713 aGrad.SetStartIntens( 100 );
1714 aGrad.SetEndIntens( 100 );
1715 rSet.Put( XFillGradientItem( String(), aGrad ) );
1717 else if ( eXFill == XFILL_BITMAP )
1719 if( IsProperty( DFF_Prop_fillBlip ) )
1721 Graphic aGraf;
1722 // first try to get BLIP from cache
1723 BOOL bOK = rManager.GetBLIP( GetPropertyValue( DFF_Prop_fillBlip ), aGraf, NULL );
1724 // then try directly from stream (i.e. Excel chart hatches/bitmaps)
1725 if ( !bOK )
1726 bOK = SeekToContent( DFF_Prop_fillBlip, rIn ) && rManager.GetBLIPDirect( rIn, aGraf, NULL );
1727 if ( bOK )
1729 Bitmap aBmp( aGraf.GetBitmap() );
1731 if ( eMSO_FillType == mso_fillPattern )
1733 Color aCol1( COL_WHITE ), aCol2( COL_WHITE );
1734 if ( IsProperty( DFF_Prop_fillColor ) )
1735 aCol1 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor );
1736 if ( IsProperty( DFF_Prop_fillBackColor ) )
1737 aCol2 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor ), DFF_Prop_fillBackColor );
1739 XOBitmap aXOBitmap;
1741 // Bitmap einsetzen
1742 aXOBitmap.SetBitmap( aBmp );
1743 aXOBitmap.SetBitmapType( XBITMAP_IMPORT );
1745 if( aBmp.GetSizePixel().Width() == 8 && aBmp.GetSizePixel().Height() == 8 && aBmp.GetColorCount() == 2)
1747 aXOBitmap.Bitmap2Array();
1748 aXOBitmap.SetBitmapType( XBITMAP_8X8 );
1749 aXOBitmap.SetPixelSize( aBmp.GetSizePixel() );
1751 if( aXOBitmap.GetBackgroundColor() == COL_BLACK )
1753 aXOBitmap.SetPixelColor( aCol1 );
1754 aXOBitmap.SetBackgroundColor( aCol2 );
1756 else
1758 aXOBitmap.SetPixelColor( aCol2 );
1759 aXOBitmap.SetBackgroundColor( aCol1 );
1762 rSet.Put( XFillBitmapItem( String(), aXOBitmap ) );
1764 else if ( eMSO_FillType == mso_fillTexture )
1766 XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
1767 rSet.Put( XFillBmpTileItem( sal_True ) );
1768 rSet.Put( XFillBitmapItem( String(), aXBmp ) );
1769 rSet.Put( XFillBmpSizeXItem( GetPropertyValue( DFF_Prop_fillWidth, 0 ) / 360 ) );
1770 rSet.Put( XFillBmpSizeYItem( GetPropertyValue( DFF_Prop_fillHeight, 0 ) / 360 ) );
1771 rSet.Put( XFillBmpSizeLogItem( sal_True ) );
1773 else
1775 XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
1776 rSet.Put( XFillBitmapItem( String(), aXBmp ) );
1777 rSet.Put( XFillBmpTileItem( sal_False ) );
1783 else
1784 rSet.Put( XFillStyleItem( XFILL_NONE ) );
1787 void DffPropertyReader::ApplyCustomShapeTextAttributes( SfxItemSet& rSet ) const
1789 // sal_uInt32 nTextFlags = aTextObj.GetTextFlags();
1790 sal_Bool bVerticalText = sal_False;
1791 sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ) / 360; // 0.25 cm (emu)
1792 sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ) / 360; // 0.25 cm (emu)
1793 sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ) / 360; // 0.13 cm (emu)
1794 sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 ) /360; // 0.13 cm (emu)
1796 SdrTextVertAdjust eTVA;
1797 SdrTextHorzAdjust eTHA;
1799 if ( IsProperty( DFF_Prop_txflTextFlow ) )
1801 MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
1802 switch( eTextFlow )
1804 case mso_txflTtoBA : /* #68110# */ // Top to Bottom @-font, oben -> unten
1805 case mso_txflTtoBN : // Top to Bottom non-@, oben -> unten
1806 case mso_txflVertN : // Vertical, non-@, oben -> unten
1807 bVerticalText = sal_True; // nTextRotationAngle += 27000;
1808 break;
1809 default: break;
1812 sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 );
1813 if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) )
1814 bVerticalText = !bVerticalText;
1816 if ( bVerticalText )
1818 eTVA = SDRTEXTVERTADJUST_BLOCK;
1819 eTHA = SDRTEXTHORZADJUST_CENTER;
1821 // Textverankerung lesen
1822 MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
1824 switch( eTextAnchor )
1826 case mso_anchorTop:
1827 case mso_anchorTopCentered:
1828 case mso_anchorTopBaseline:
1829 case mso_anchorTopCenteredBaseline:
1830 eTHA = SDRTEXTHORZADJUST_RIGHT;
1831 break;
1833 case mso_anchorMiddle :
1834 case mso_anchorMiddleCentered:
1835 eTHA = SDRTEXTHORZADJUST_CENTER;
1836 break;
1838 case mso_anchorBottom:
1839 case mso_anchorBottomCentered:
1840 case mso_anchorBottomBaseline:
1841 case mso_anchorBottomCenteredBaseline:
1842 eTHA = SDRTEXTHORZADJUST_LEFT;
1843 break;
1845 // if there is a 100% use of following attributes, the textbox can been aligned also in vertical direction
1846 switch ( eTextAnchor )
1848 case mso_anchorTopCentered :
1849 case mso_anchorMiddleCentered :
1850 case mso_anchorBottomCentered :
1851 case mso_anchorTopCenteredBaseline:
1852 case mso_anchorBottomCenteredBaseline:
1853 eTVA = SDRTEXTVERTADJUST_CENTER;
1854 break;
1856 default :
1857 eTVA = SDRTEXTVERTADJUST_TOP;
1858 break;
1861 else
1863 eTVA = SDRTEXTVERTADJUST_CENTER;
1864 eTHA = SDRTEXTHORZADJUST_BLOCK;
1866 // Textverankerung lesen
1867 MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
1869 switch( eTextAnchor )
1871 case mso_anchorTop:
1872 case mso_anchorTopCentered:
1873 case mso_anchorTopBaseline:
1874 case mso_anchorTopCenteredBaseline:
1875 eTVA = SDRTEXTVERTADJUST_TOP;
1876 break;
1878 case mso_anchorMiddle :
1879 case mso_anchorMiddleCentered:
1880 eTVA = SDRTEXTVERTADJUST_CENTER;
1881 break;
1883 case mso_anchorBottom:
1884 case mso_anchorBottomCentered:
1885 case mso_anchorBottomBaseline:
1886 case mso_anchorBottomCenteredBaseline:
1887 eTVA = SDRTEXTVERTADJUST_BOTTOM;
1888 break;
1890 // if there is a 100% usage of following attributes, the textbox can be aligned also in horizontal direction
1891 switch ( eTextAnchor )
1893 case mso_anchorTopCentered :
1894 case mso_anchorMiddleCentered :
1895 case mso_anchorBottomCentered :
1896 case mso_anchorTopCenteredBaseline:
1897 case mso_anchorBottomCenteredBaseline:
1898 eTHA = SDRTEXTHORZADJUST_CENTER; // the text has to be displayed using the full width;
1899 break;
1901 default :
1902 eTHA = SDRTEXTHORZADJUST_LEFT;
1903 break;
1906 rSet.Put( SvxFrameDirectionItem( bVerticalText ? FRMDIR_VERT_TOP_RIGHT : FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR ) );
1908 rSet.Put( SdrTextVertAdjustItem( eTVA ) );
1909 rSet.Put( SdrTextHorzAdjustItem( eTHA ) );
1911 rSet.Put( SdrTextLeftDistItem( nTextLeft ) );
1912 rSet.Put( SdrTextRightDistItem( nTextRight ) );
1913 rSet.Put( SdrTextUpperDistItem( nTextTop ) );
1914 rSet.Put( SdrTextLowerDistItem( nTextBottom ) );
1916 rSet.Put( SdrTextWordWrapItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_True : sal_False ) );
1917 rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
1919 // rSet.Put( SdrTextAutoGrowWidthItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_False : sal_True ) );
1920 // rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
1923 void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxItemSet& rSet, const MSO_SPT eShapeType, const sal_uInt32 /* nShapeFlags */ ) const
1926 sal_uInt32 nAdjustmentsWhichNeedsToBeConverted = 0;
1928 ///////////////////////////////////////
1929 // creating SdrCustomShapeGeometryItem //
1930 ///////////////////////////////////////
1931 typedef uno::Sequence< beans::PropertyValue > PropSeq;
1932 typedef std::vector< beans::PropertyValue > PropVec;
1933 typedef PropVec::iterator PropVecIter;
1934 PropVecIter aIter;
1935 PropVecIter aEnd;
1938 // aPropVec will be filled with all PropertyValues
1939 PropVec aPropVec;
1940 PropertyValue aProp;
1942 /////////////////////////////////////////////////////////////////////
1943 // "Type" property, including the predefined CustomShape type name //
1944 /////////////////////////////////////////////////////////////////////
1945 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
1946 aProp.Name = sType;
1947 aProp.Value <<= EnhancedCustomShapeTypeNames::Get( eShapeType );
1948 aPropVec.push_back( aProp );
1951 /////////////////
1952 // "MirroredX" //
1953 /////////////////
1954 if ( nShapeFlags & SP_FFLIPH )
1956 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
1957 sal_Bool bMirroredX = sal_True;
1958 aProp.Name = sMirroredX;
1959 aProp.Value <<= bMirroredX;
1960 aPropVec.push_back( aProp );
1962 /////////////////
1963 // "MirroredY" //
1964 /////////////////
1965 if ( nShapeFlags & SP_FFLIPV )
1967 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
1968 sal_Bool bMirroredY = sal_True;
1969 aProp.Name = sMirroredY;
1970 aProp.Value <<= bMirroredY;
1971 aPropVec.push_back( aProp );
1974 ///////////////
1975 // "ViewBox" //
1976 ///////////////
1978 sal_Int32 nCoordWidth = 21600; // needed to replace handle type center with absolute value
1979 sal_Int32 nCoordHeight= 21600;
1980 if ( IsProperty( DFF_Prop_geoLeft ) || IsProperty( DFF_Prop_geoTop ) || IsProperty( DFF_Prop_geoRight ) || IsProperty( DFF_Prop_geoBottom ) )
1982 com::sun::star::awt::Rectangle aViewBox;
1983 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
1984 aViewBox.X = GetPropertyValue( DFF_Prop_geoLeft, 0 );
1985 aViewBox.Y = GetPropertyValue( DFF_Prop_geoTop, 0 );
1986 aViewBox.Width = nCoordWidth = ((sal_Int32)GetPropertyValue( DFF_Prop_geoRight, 21600 ) ) - aViewBox.X;
1987 aViewBox.Height = nCoordHeight = ((sal_Int32)GetPropertyValue( DFF_Prop_geoBottom, 21600 ) ) - aViewBox.Y;
1988 aProp.Name = sViewBox;
1989 aProp.Value <<= aViewBox;
1990 aPropVec.push_back( aProp );
1992 /////////////////////
1993 // TextRotateAngle //
1994 /////////////////////
1995 if ( IsProperty( DFF_Prop_txflTextFlow ) || IsProperty( DFF_Prop_cdirFont ) )
1997 sal_Int32 nTextRotateAngle = 0;
1998 MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
1999 /* sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ); */
2001 if ( eTextFlow == mso_txflBtoT ) // Bottom to Top non-@, unten -> oben
2002 nTextRotateAngle += 90;
2003 switch( GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ) ) // SJ: mso_cdir90 and mso_cdir270 will be simulated by
2004 { // activating vertical writing for the text objects
2005 case mso_cdir90 :
2007 if ( eTextFlow == mso_txflTtoBA )
2008 nTextRotateAngle -= 180;
2010 break;
2011 case mso_cdir180: nTextRotateAngle -= 180; break;
2012 case mso_cdir270:
2014 if ( eTextFlow != mso_txflTtoBA )
2015 nTextRotateAngle -= 180;
2017 break;
2018 default: break;
2020 if ( nTextRotateAngle )
2022 double fTextRotateAngle = nTextRotateAngle;
2023 const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
2024 aProp.Name = sTextRotateAngle;
2025 aProp.Value <<= fTextRotateAngle;
2026 aPropVec.push_back( aProp );
2029 //////////////////////////////////////////
2030 // "Extrusion" PropertySequence element //
2031 //////////////////////////////////////////
2032 sal_Bool bExtrusionOn = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 8 ) != 0;
2033 if ( bExtrusionOn )
2035 PropVec aExtrusionPropVec;
2037 // "Extrusion"
2038 const rtl::OUString sExtrusionOn( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
2039 aProp.Name = sExtrusionOn;
2040 aProp.Value <<= bExtrusionOn;
2041 aExtrusionPropVec.push_back( aProp );
2043 // "Brightness"
2044 if ( IsProperty( DFF_Prop_c3DAmbientIntensity ) )
2046 const rtl::OUString sExtrusionBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
2047 double fBrightness = (sal_Int32)GetPropertyValue( DFF_Prop_c3DAmbientIntensity );
2048 fBrightness /= 655.36;
2049 aProp.Name = sExtrusionBrightness;
2050 aProp.Value <<= fBrightness;
2051 aExtrusionPropVec.push_back( aProp );
2053 // "Depth" in 1/100mm
2054 if ( IsProperty( DFF_Prop_c3DExtrudeBackward ) || IsProperty( DFF_Prop_c3DExtrudeForward ) )
2056 const rtl::OUString sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
2057 double fBackDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeBackward, 1270 * 360 )) / 360.0;
2058 double fForeDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeForward ), 0 ) / 360.0;
2059 double fDepth = fBackDepth + fForeDepth;
2060 double fFraction = fDepth != 0.0 ? fForeDepth / fDepth : 0;
2061 EnhancedCustomShapeParameterPair aDepthParaPair;
2062 aDepthParaPair.First.Value <<= fDepth;
2063 aDepthParaPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2064 aDepthParaPair.Second.Value <<= fFraction;
2065 aDepthParaPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2066 aProp.Name = sDepth;
2067 aProp.Value <<= aDepthParaPair;
2068 aExtrusionPropVec.push_back( aProp );
2070 // "Diffusion"
2071 if ( IsProperty( DFF_Prop_c3DDiffuseAmt ) )
2073 const rtl::OUString sExtrusionDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
2074 double fDiffusion = (sal_Int32)GetPropertyValue( DFF_Prop_c3DDiffuseAmt );
2075 fDiffusion /= 655.36;
2076 aProp.Name = sExtrusionDiffusion;
2077 aProp.Value <<= fDiffusion;
2078 aExtrusionPropVec.push_back( aProp );
2080 // "NumberOfLineSegments"
2081 if ( IsProperty( DFF_Prop_c3DTolerance ) )
2083 const rtl::OUString sExtrusionNumberOfLineSegments( RTL_CONSTASCII_USTRINGPARAM ( "NumberOfLineSegments" ) );
2084 aProp.Name = sExtrusionNumberOfLineSegments;
2085 aProp.Value <<= (sal_Int32)GetPropertyValue( DFF_Prop_c3DTolerance );
2086 aExtrusionPropVec.push_back( aProp );
2088 // "LightFace"
2089 const rtl::OUString sExtrusionLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) );
2090 sal_Bool bExtrusionLightFace = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 1 ) != 0;
2091 aProp.Name = sExtrusionLightFace;
2092 aProp.Value <<= bExtrusionLightFace;
2093 aExtrusionPropVec.push_back( aProp );
2094 // "FirstLightHarsh"
2095 const rtl::OUString sExtrusionFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) );
2096 sal_Bool bExtrusionFirstLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 2 ) != 0;
2097 aProp.Name = sExtrusionFirstLightHarsh;
2098 aProp.Value <<= bExtrusionFirstLightHarsh;
2099 aExtrusionPropVec.push_back( aProp );
2100 // "SecondLightHarsh"
2101 const rtl::OUString sExtrusionSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) );
2102 sal_Bool bExtrusionSecondLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 1 ) != 0;
2103 aProp.Name = sExtrusionSecondLightHarsh;
2104 aProp.Value <<= bExtrusionSecondLightHarsh;
2105 aExtrusionPropVec.push_back( aProp );
2106 // "FirstLightLevel"
2107 if ( IsProperty( DFF_Prop_c3DKeyIntensity ) )
2109 const rtl::OUString sExtrusionFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) );
2110 double fFirstLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyIntensity );
2111 fFirstLightLevel /= 655.36;
2112 aProp.Name = sExtrusionFirstLightLevel;
2113 aProp.Value <<= fFirstLightLevel;
2114 aExtrusionPropVec.push_back( aProp );
2116 // "SecondLightLevel"
2117 if ( IsProperty( DFF_Prop_c3DFillIntensity ) )
2119 const rtl::OUString sExtrusionSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) );
2120 double fSecondLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DFillIntensity );
2121 fSecondLightLevel /= 655.36;
2122 aProp.Name = sExtrusionSecondLightLevel;
2123 aProp.Value <<= fSecondLightLevel;
2124 aExtrusionPropVec.push_back( aProp );
2126 // "FirtstLightDirection"
2127 if ( IsProperty( DFF_Prop_c3DKeyX ) || IsProperty( DFF_Prop_c3DKeyY ) || IsProperty( DFF_Prop_c3DKeyZ ) )
2129 double fLightX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyX, 50000 ));
2130 double fLightY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyY, 0 ));
2131 double fLightZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyZ, 10000 ));
2132 ::com::sun::star::drawing::Direction3D aExtrusionFirstLightDirection( fLightX, fLightY, fLightZ );
2133 const rtl::OUString sExtrusionFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
2134 aProp.Name = sExtrusionFirstLightDirection;
2135 aProp.Value <<= aExtrusionFirstLightDirection;
2136 aExtrusionPropVec.push_back( aProp );
2138 // "SecondLightDirection"
2139 if ( IsProperty( DFF_Prop_c3DFillX ) || IsProperty( DFF_Prop_c3DFillY ) || IsProperty( DFF_Prop_c3DFillZ ) )
2141 double fLight2X = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillX, (sal_uInt32)-50000 ));
2142 double fLight2Y = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillY, 0 ));
2143 double fLight2Z = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillZ, 10000 ));
2144 ::com::sun::star::drawing::Direction3D aExtrusionSecondLightDirection( fLight2X, fLight2Y, fLight2Z );
2145 const rtl::OUString sExtrusionSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
2146 aProp.Name = sExtrusionSecondLightDirection;
2147 aProp.Value <<= aExtrusionSecondLightDirection;
2148 aExtrusionPropVec.push_back( aProp );
2151 /* LockRotationCenter, OrientationAngle and Orientation needs to be converted to use the properties AngleX, AngleY and RotationAngle instead.
2152 // "LockRotationCenter"
2153 const rtl::OUString sExtrusionLockRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "LockRotationCenter" ) );
2154 sal_Bool bExtrusionLockRotationCenter = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 16 ) != 0;
2155 aProp.Name = sExtrusionLockRotationCenter;
2156 aProp.Value <<= bExtrusionLockRotationCenter;
2157 aExtrusionPropVec.push_back( aProp );
2159 // "Orientation"
2160 if ( IsProperty( DFF_Prop_c3DRotationAxisX ) || IsProperty( DFF_Prop_c3DRotationAxisY ) || IsProperty( DFF_Prop_c3DRotationAxisZ ) )
2162 double fRotX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 ));
2163 double fRotY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 ));
2164 double fRotZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 ));
2165 ::com::sun::star::drawing::Direction3D aExtrusionDirection( fRotX, fRotY, fRotZ );
2166 const rtl::OUString sExtrusionDirection( RTL_CONSTASCII_USTRINGPARAM ( "Orientation" ) );
2167 aProp.Name = sExtrusionDirection;
2168 aProp.Value <<= aExtrusionDirection;
2169 aExtrusionPropVec.push_back( aProp );
2171 // "OrientationAngle" in Grad
2172 if ( IsProperty( DFF_Prop_c3DRotationAngle ) )
2174 const rtl::OUString sExtrusionOrientationAngle( RTL_CONSTASCII_USTRINGPARAM ( "OrientationAngle" ) );
2175 double fOrientationAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAngle )) / 65536.0;
2176 aProp.Name = sExtrusionOrientationAngle;
2177 aProp.Value <<= fOrientationAngle;
2178 aExtrusionPropVec.push_back( aProp );
2182 // "Metal"
2183 const rtl::OUString sExtrusionMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
2184 sal_Bool bExtrusionMetal = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 4 ) != 0;
2185 aProp.Name = sExtrusionMetal;
2186 aProp.Value <<= bExtrusionMetal;
2187 aExtrusionPropVec.push_back( aProp );
2188 // if ( IsProperty( DFF_Prop_c3DExtrudePlane ) )
2189 // {
2190 // UPS
2191 // }
2192 // "ShadeMode"
2193 if ( IsProperty( DFF_Prop_c3DRenderMode ) )
2195 const rtl::OUString sExtrusionShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
2196 sal_uInt32 nExtrusionRenderMode = GetPropertyValue( DFF_Prop_c3DRenderMode );
2197 com::sun::star::drawing::ShadeMode eExtrusionShadeMode( com::sun::star::drawing::ShadeMode_FLAT );
2198 if ( nExtrusionRenderMode == mso_Wireframe )
2199 eExtrusionShadeMode = com::sun::star::drawing::ShadeMode_DRAFT;
2201 aProp.Name = sExtrusionShadeMode;
2202 aProp.Value <<= eExtrusionShadeMode;
2203 aExtrusionPropVec.push_back( aProp );
2205 // "RotateAngle" in Grad
2206 if ( IsProperty( DFF_Prop_c3DXRotationAngle ) || IsProperty( DFF_Prop_c3DYRotationAngle ) )
2208 const rtl::OUString sExtrusionAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) );
2209 double fAngleX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXRotationAngle, 0 )) / 65536.0;
2210 double fAngleY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYRotationAngle, 0 )) / 65536.0;
2211 EnhancedCustomShapeParameterPair aRotateAnglePair;
2212 aRotateAnglePair.First.Value <<= fAngleX;
2213 aRotateAnglePair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2214 aRotateAnglePair.Second.Value <<= fAngleY;
2215 aRotateAnglePair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2216 aProp.Name = sExtrusionAngle;
2217 aProp.Value <<= aRotateAnglePair;
2218 aExtrusionPropVec.push_back( aProp );
2221 // "AutoRotationCenter"
2222 if ( ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 8 ) == 0 )
2224 // "RotationCenter"
2225 if ( IsProperty( DFF_Prop_c3DRotationCenterX ) || IsProperty( DFF_Prop_c3DRotationCenterY ) || IsProperty( DFF_Prop_c3DRotationCenterZ ) )
2227 ::com::sun::star::drawing::Direction3D aRotationCenter(
2228 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 )) / 360.0,
2229 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 )) / 360.0,
2230 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterZ, 0 )) / 360.0 );
2232 const rtl::OUString sExtrusionRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) );
2233 aProp.Name = sExtrusionRotationCenter;
2234 aProp.Value <<= aRotationCenter;
2235 aExtrusionPropVec.push_back( aProp );
2238 // "Shininess"
2239 if ( IsProperty( DFF_Prop_c3DShininess ) )
2241 const rtl::OUString sExtrusionShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) );
2242 double fShininess = (sal_Int32)GetPropertyValue( DFF_Prop_c3DShininess );
2243 fShininess /= 655.36;
2244 aProp.Name = sExtrusionShininess;
2245 aProp.Value <<= fShininess;
2246 aExtrusionPropVec.push_back( aProp );
2248 // "Skew"
2249 if ( IsProperty( DFF_Prop_c3DSkewAmount ) || IsProperty( DFF_Prop_c3DSkewAngle ) )
2251 const rtl::OUString sExtrusionSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
2252 double fSkewAmount = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAmount, 50 );
2253 double fSkewAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAngle, sal::static_int_cast< UINT32 >(-135 * 65536) )) / 65536.0;
2255 EnhancedCustomShapeParameterPair aSkewPair;
2256 aSkewPair.First.Value <<= fSkewAmount;
2257 aSkewPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2258 aSkewPair.Second.Value <<= fSkewAngle;
2259 aSkewPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2260 aProp.Name = sExtrusionSkew;
2261 aProp.Value <<= aSkewPair;
2262 aExtrusionPropVec.push_back( aProp );
2264 // "Specularity"
2265 if ( IsProperty( DFF_Prop_c3DSpecularAmt ) )
2267 const rtl::OUString sExtrusionSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
2268 double fSpecularity = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSpecularAmt );
2269 fSpecularity /= 1333;
2270 aProp.Name = sExtrusionSpecularity;
2271 aProp.Value <<= fSpecularity;
2272 aExtrusionPropVec.push_back( aProp );
2274 // "ProjectionMode"
2275 const rtl::OUString sExtrusionProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
2276 ProjectionMode eProjectionMode = GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 4 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE;
2277 aProp.Name = sExtrusionProjectionMode;
2278 aProp.Value <<= eProjectionMode;
2279 aExtrusionPropVec.push_back( aProp );
2281 // "ViewPoint" in 1/100mm
2282 if ( IsProperty( DFF_Prop_c3DXViewpoint ) || IsProperty( DFF_Prop_c3DYViewpoint ) || IsProperty( DFF_Prop_c3DZViewpoint ) )
2284 double fViewX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXViewpoint, 1249920 )) / 360.0;
2285 double fViewY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYViewpoint, (sal_uInt32)-1249920 ))/ 360.0;
2286 double fViewZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DZViewpoint, 9000000 )) / 360.0;
2287 ::com::sun::star::drawing::Position3D aExtrusionViewPoint( fViewX, fViewY, fViewZ );
2288 const rtl::OUString sExtrusionViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
2289 aProp.Name = sExtrusionViewPoint;
2290 aProp.Value <<= aExtrusionViewPoint;
2291 aExtrusionPropVec.push_back( aProp );
2293 // "Origin"
2294 if ( IsProperty( DFF_Prop_c3DOriginX ) || IsProperty( DFF_Prop_c3DOriginY ) )
2296 const rtl::OUString sExtrusionOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
2297 double fOriginX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginX, 0 ));
2298 double fOriginY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginY, 0 ));
2299 fOriginX /= 65536;
2300 fOriginY /= 65536;
2301 EnhancedCustomShapeParameterPair aOriginPair;
2302 aOriginPair.First.Value <<= fOriginX;
2303 aOriginPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2304 aOriginPair.Second.Value <<= fOriginY;
2305 aOriginPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2306 aProp.Name = sExtrusionOrigin;
2307 aProp.Value <<= aOriginPair;
2308 aExtrusionPropVec.push_back( aProp );
2310 // "ExtrusionColor"
2311 const rtl::OUString sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
2312 sal_Bool bExtrusionColor = IsProperty( DFF_Prop_c3DExtrusionColor ); // ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 2 ) != 0;
2313 aProp.Name = sExtrusionColor;
2314 aProp.Value <<= bExtrusionColor;
2315 aExtrusionPropVec.push_back( aProp );
2316 if ( IsProperty( DFF_Prop_c3DExtrusionColor ) )
2317 rSet.Put( XSecondaryFillColorItem( String(), rManager.MSO_CLR_ToColor(
2318 GetPropertyValue( DFF_Prop_c3DExtrusionColor ), DFF_Prop_c3DExtrusionColor ) ) );
2319 // pushing the whole Extrusion element
2320 const rtl::OUString sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
2321 PropSeq aExtrusionPropSeq( aExtrusionPropVec.size() );
2322 aIter = aExtrusionPropVec.begin();
2323 aEnd = aExtrusionPropVec.end();
2324 beans::PropertyValue* pExtrusionValues = aExtrusionPropSeq.getArray();
2325 while ( aIter != aEnd )
2326 *pExtrusionValues++ = *aIter++;
2327 aProp.Name = sExtrusion;
2328 aProp.Value <<= aExtrusionPropSeq;
2329 aPropVec.push_back( aProp );
2332 /////////////////////////////////////////
2333 // "Equations" PropertySequence element //
2334 /////////////////////////////////////////
2335 if ( IsProperty( DFF_Prop_pFormulas ) )
2337 sal_uInt16 i;
2338 sal_uInt16 nNumElem = 0;
2339 sal_uInt16 nNumElemMem = 0;
2340 sal_uInt16 nElemSize = 8;
2342 if ( SeekToContent( DFF_Prop_pFormulas, rIn ) )
2343 rIn >> nNumElem >> nNumElemMem >> nElemSize;
2345 sal_Int16 nP1, nP2, nP3;
2346 sal_uInt16 nFlags;
2348 uno::Sequence< rtl::OUString > aEquations( nNumElem );
2349 for ( i = 0; i < nNumElem; i++ )
2351 rIn >> nFlags >> nP1 >> nP2 >> nP3;
2352 aEquations[ i ] = EnhancedCustomShape2d::GetEquation( nFlags, nP1, nP2, nP3 );
2354 // pushing the whole Equations element
2355 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
2356 aProp.Name = sEquations;
2357 aProp.Value <<= aEquations;
2358 aPropVec.push_back( aProp );
2361 ////////////////////////////////////////
2362 // "Handles" PropertySequence element //
2363 ////////////////////////////////////////
2364 if ( IsProperty( DFF_Prop_Handles ) )
2366 sal_uInt16 i;
2367 sal_uInt16 nNumElem = 0;
2368 sal_uInt16 nNumElemMem = 0;
2369 sal_uInt16 nElemSize = 36;
2371 if ( SeekToContent( DFF_Prop_Handles, rIn ) )
2372 rIn >> nNumElem >> nNumElemMem >> nElemSize;
2373 if ( nElemSize == 36 )
2375 uno::Sequence< beans::PropertyValues > aHandles( nNumElem );
2376 for ( i = 0; i < nNumElem; i++ )
2378 PropVec aHandlePropVec;
2379 sal_uInt32 nFlags;
2380 sal_Int32 nPositionX, nPositionY, nCenterX, nCenterY, nRangeXMin, nRangeXMax, nRangeYMin, nRangeYMax;
2381 rIn >> nFlags
2382 >> nPositionX
2383 >> nPositionY
2384 >> nCenterX
2385 >> nCenterY
2386 >> nRangeXMin
2387 >> nRangeXMax
2388 >> nRangeYMin
2389 >> nRangeYMax;
2391 if ( nPositionX == 2 ) // replacing center position with absolute value
2392 nPositionX = nCoordWidth / 2;
2393 if ( nPositionY == 2 )
2394 nPositionY = nCoordHeight / 2;
2395 EnhancedCustomShapeParameterPair aPosition;
2396 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, nPositionX, sal_True, sal_True );
2397 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, nPositionY, sal_True, sal_False );
2398 const rtl::OUString sHandlePosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
2399 aProp.Name = sHandlePosition;
2400 aProp.Value <<= aPosition;
2401 aHandlePropVec.push_back( aProp );
2403 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
2405 sal_Bool bMirroredX = sal_True;
2406 const rtl::OUString sHandleMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
2407 aProp.Name = sHandleMirroredX;
2408 aProp.Value <<= bMirroredX;
2409 aHandlePropVec.push_back( aProp );
2411 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
2413 sal_Bool bMirroredY = sal_True;
2414 const rtl::OUString sHandleMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
2415 aProp.Name = sHandleMirroredY;
2416 aProp.Value <<= bMirroredY;
2417 aHandlePropVec.push_back( aProp );
2419 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
2421 sal_Bool bSwitched = sal_True;
2422 const rtl::OUString sHandleSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
2423 aProp.Name = sHandleSwitched;
2424 aProp.Value <<= bSwitched;
2425 aHandlePropVec.push_back( aProp );
2427 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
2429 if ( nCenterX == 2 )
2430 nCenterX = nCoordWidth / 2;
2431 if ( nCenterY == 2 )
2432 nCenterY = nCoordHeight / 2;
2433 if ( ( nPositionY >= 0x256 ) || ( nPositionY <= 0x107 ) ) // position y
2434 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
2435 EnhancedCustomShapeParameterPair aPolar;
2436 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True );
2437 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
2438 const rtl::OUString sHandlePolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
2439 aProp.Name = sHandlePolar;
2440 aProp.Value <<= aPolar;
2441 aHandlePropVec.push_back( aProp );
2443 if ( nFlags & MSDFF_HANDLE_FLAGS_MAP )
2445 if ( nCenterX == 2 )
2446 nCenterX = nCoordWidth / 2;
2447 if ( nCenterY == 2 )
2448 nCenterY = nCoordHeight / 2;
2449 EnhancedCustomShapeParameterPair aMap;
2450 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True );
2451 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
2452 const rtl::OUString sHandleMap( RTL_CONSTASCII_USTRINGPARAM ( "Map" ) );
2453 aProp.Name = sHandleMap;
2454 aProp.Value <<= aMap;
2455 aHandlePropVec.push_back( aProp );
2457 if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
2459 if ( (sal_uInt32)nRangeXMin != 0x80000000 )
2461 if ( nRangeXMin == 2 )
2462 nRangeXMin = nCoordWidth / 2;
2463 EnhancedCustomShapeParameter aRangeXMinimum;
2464 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, nRangeXMin,
2465 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
2466 const rtl::OUString sHandleRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
2467 aProp.Name = sHandleRangeXMinimum;
2468 aProp.Value <<= aRangeXMinimum;
2469 aHandlePropVec.push_back( aProp );
2471 if ( (sal_uInt32)nRangeXMax != 0x7fffffff )
2473 if ( nRangeXMax == 2 )
2474 nRangeXMax = nCoordWidth / 2;
2475 EnhancedCustomShapeParameter aRangeXMaximum;
2476 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, nRangeXMax,
2477 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
2478 const rtl::OUString sHandleRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
2479 aProp.Name = sHandleRangeXMaximum;
2480 aProp.Value <<= aRangeXMaximum;
2481 aHandlePropVec.push_back( aProp );
2483 if ( (sal_uInt32)nRangeYMin != 0x80000000 )
2485 if ( nRangeYMin == 2 )
2486 nRangeYMin = nCoordHeight / 2;
2487 EnhancedCustomShapeParameter aRangeYMinimum;
2488 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, nRangeYMin,
2489 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
2490 const rtl::OUString sHandleRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
2491 aProp.Name = sHandleRangeYMinimum;
2492 aProp.Value <<= aRangeYMinimum;
2493 aHandlePropVec.push_back( aProp );
2495 if ( (sal_uInt32)nRangeYMax != 0x7fffffff )
2497 if ( nRangeYMax == 2 )
2498 nRangeYMax = nCoordHeight / 2;
2499 EnhancedCustomShapeParameter aRangeYMaximum;
2500 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, nRangeYMax,
2501 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
2502 const rtl::OUString sHandleRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
2503 aProp.Name = sHandleRangeYMaximum;
2504 aProp.Value <<= aRangeYMaximum;
2505 aHandlePropVec.push_back( aProp );
2508 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
2510 if ( (sal_uInt32)nRangeXMin != 0x7fffffff )
2512 if ( nRangeXMin == 2 )
2513 nRangeXMin = nCoordWidth / 2;
2514 EnhancedCustomShapeParameter aRadiusRangeMinimum;
2515 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, nRangeXMin,
2516 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
2517 const rtl::OUString sHandleRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
2518 aProp.Name = sHandleRadiusRangeMinimum;
2519 aProp.Value <<= aRadiusRangeMinimum;
2520 aHandlePropVec.push_back( aProp );
2522 if ( (sal_uInt32)nRangeXMax != 0x80000000 )
2524 if ( nRangeXMax == 2 )
2525 nRangeXMax = nCoordWidth / 2;
2526 EnhancedCustomShapeParameter aRadiusRangeMaximum;
2527 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, nRangeXMax,
2528 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
2529 const rtl::OUString sHandleRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
2530 aProp.Name = sHandleRadiusRangeMaximum;
2531 aProp.Value <<= aRadiusRangeMaximum;
2532 aHandlePropVec.push_back( aProp );
2535 if ( aHandlePropVec.size() )
2537 PropSeq aHandlePropSeq( aHandlePropVec.size() );
2538 aIter = aHandlePropVec.begin();
2539 aEnd = aHandlePropVec.end();
2540 beans::PropertyValue* pHandleValues = aHandlePropSeq.getArray();
2541 while ( aIter != aEnd )
2542 *pHandleValues++ = *aIter++;
2543 aHandles[ i ] = aHandlePropSeq;
2546 // pushing the whole Handles element
2547 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
2548 aProp.Name = sHandles;
2549 aProp.Value <<= aHandles;
2550 aPropVec.push_back( aProp );
2553 else
2555 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( eShapeType );
2556 if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
2558 sal_Int32 i, nCnt = pDefCustomShape->nHandles;
2559 const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
2560 for ( i = 0; i < nCnt; i++, pData++ )
2562 if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR )
2564 if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) )
2565 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
2570 /////////////////////////////////////
2571 // "Path" PropertySequence element //
2572 /////////////////////////////////////
2574 PropVec aPathPropVec;
2576 // "Path/ExtrusionAllowed"
2577 if ( IsHardAttribute( DFF_Prop_f3DOK ) )
2579 const rtl::OUString sExtrusionAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ExtrusionAllowed" ) );
2580 sal_Bool bExtrusionAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 16 ) != 0;
2581 aProp.Name = sExtrusionAllowed;
2582 aProp.Value <<= bExtrusionAllowed;
2583 aPathPropVec.push_back( aProp );
2585 // "Path/ConcentricGradientFillAllowed"
2586 if ( IsHardAttribute( DFF_Prop_fFillShadeShapeOK ) )
2588 const rtl::OUString sConcentricGradientFillAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ConcentricGradientFillAllowed" ) );
2589 sal_Bool bConcentricGradientFillAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 2 ) != 0;
2590 aProp.Name = sConcentricGradientFillAllowed;
2591 aProp.Value <<= bConcentricGradientFillAllowed;
2592 aPathPropVec.push_back( aProp );
2594 // "Path/TextPathAllowed"
2595 if ( IsHardAttribute( DFF_Prop_fGtextOK ) || ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) )
2597 const rtl::OUString sTextPathAllowed( RTL_CONSTASCII_USTRINGPARAM ( "TextPathAllowed" ) );
2598 sal_Bool bTextPathAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 4 ) != 0;
2599 aProp.Name = sTextPathAllowed;
2600 aProp.Value <<= bTextPathAllowed;
2601 aPathPropVec.push_back( aProp );
2603 // Path/Coordinates
2604 if ( IsProperty( DFF_Prop_pVertices ) )
2606 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
2608 sal_uInt16 i;
2609 sal_uInt16 nNumElemVert = 0;
2610 sal_uInt16 nNumElemMemVert = 0;
2611 sal_uInt16 nElemSizeVert = 8;
2613 if ( SeekToContent( DFF_Prop_pVertices, rIn ) )
2614 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
2615 if ( nNumElemVert )
2617 sal_Int32 nX, nY;
2618 sal_Int16 nTmpA, nTmpB;
2619 aCoordinates.realloc( nNumElemVert );
2620 for ( i = 0; i < nNumElemVert; i++ )
2622 if ( nElemSizeVert == 8 )
2624 rIn >> nX
2625 >> nY;
2627 else
2629 rIn >> nTmpA
2630 >> nTmpB;
2632 nX = nTmpA;
2633 nY = nTmpB;
2635 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].First, nX );
2636 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].Second, nY );
2639 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
2640 aProp.Name = sCoordinates;
2641 aProp.Value <<= aCoordinates;
2642 aPathPropVec.push_back( aProp );
2644 // Path/Segments
2645 if ( IsProperty( DFF_Prop_pSegmentInfo ) )
2647 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
2649 sal_uInt16 i, nTmp;
2650 sal_uInt16 nNumElemSeg = 0;
2651 sal_uInt16 nNumElemMemSeg = 0;
2652 sal_uInt16 nElemSizeSeg = 2;
2654 if ( SeekToContent( DFF_Prop_pSegmentInfo, rIn ) )
2655 rIn >> nNumElemSeg >> nNumElemMemSeg >> nElemSizeSeg;
2656 if ( nNumElemSeg )
2658 sal_Int16 nCommand;
2659 sal_Int16 nCnt;
2660 aSegments.realloc( nNumElemSeg );
2661 for ( i = 0; i < nNumElemSeg; i++ )
2663 rIn >> nTmp;
2664 nCommand = EnhancedCustomShapeSegmentCommand::UNKNOWN;
2665 nCnt = (sal_Int16)( nTmp & 0xfff );
2666 switch( nTmp >> 12 )
2668 case 0x0: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break;
2669 case 0x1: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break; // seems to the relative lineto
2670 case 0x4: nCommand = EnhancedCustomShapeSegmentCommand::MOVETO; if ( !nCnt ) nCnt = 1; break;
2671 case 0x2: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break;
2672 case 0x3: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break; // seems to be the relative curveto
2673 case 0x8: nCommand = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; nCnt = 0; break;
2674 case 0x6: nCommand = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; nCnt = 0; break;
2675 case 0xa:
2676 case 0xb:
2678 switch ( ( nTmp >> 8 ) & 0xf )
2680 case 0x0:
2682 nCommand = EnhancedCustomShapeSegmentCommand::LINETO;
2683 if ( !nCnt )
2684 nCnt = 1;
2686 break;
2687 case 0x1:
2689 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
2690 nCnt = ( nTmp & 0xff ) / 3;
2692 break;
2693 case 0x2:
2695 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
2696 nCnt = ( nTmp & 0xff ) / 3;
2698 break;
2699 case 0x3:
2701 nCommand = EnhancedCustomShapeSegmentCommand::ARCTO;
2702 nCnt = ( nTmp & 0xff ) >> 2;
2704 break;
2705 case 0x4:
2707 nCommand = EnhancedCustomShapeSegmentCommand::ARC;
2708 nCnt = ( nTmp & 0xff ) >> 2;
2710 break;
2711 case 0x5:
2713 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
2714 nCnt = ( nTmp & 0xff ) >> 2;
2716 break;
2717 case 0x6:
2719 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
2720 nCnt = ( nTmp & 0xff ) >> 2;
2722 break;
2723 case 0x7:
2725 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
2726 nCnt = nTmp & 0xff;
2728 break;
2729 case 0x8:
2731 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
2732 nCnt = nTmp & 0xff;
2734 break;
2735 case 0xa: nCommand = EnhancedCustomShapeSegmentCommand::NOFILL; nCnt = 0; break;
2736 case 0xb: nCommand = EnhancedCustomShapeSegmentCommand::NOSTROKE; nCnt = 0; break;
2739 break;
2741 // if the command is unknown, we will store all the data in nCnt, so it will be possible to export without loss
2742 if ( nCommand == EnhancedCustomShapeSegmentCommand::UNKNOWN )
2743 nCnt = (sal_Int16)nTmp;
2744 aSegments[ i ].Command = nCommand;
2745 aSegments[ i ].Count = nCnt;
2748 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
2749 aProp.Name = sSegments;
2750 aProp.Value <<= aSegments;
2751 aPathPropVec.push_back( aProp );
2753 // Path/StretchX
2754 if ( IsProperty( DFF_Prop_stretchPointX ) )
2756 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
2757 sal_Int32 nStretchX = GetPropertyValue( DFF_Prop_stretchPointX, 0 );
2758 aProp.Name = sStretchX;
2759 aProp.Value <<= nStretchX;
2760 aPathPropVec.push_back( aProp );
2762 // Path/StretchX
2763 if ( IsProperty( DFF_Prop_stretchPointY ) )
2765 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
2766 sal_Int32 nStretchY = GetPropertyValue( DFF_Prop_stretchPointY, 0 );
2767 aProp.Name = sStretchY;
2768 aProp.Value <<= nStretchY;
2769 aPathPropVec.push_back( aProp );
2771 // Path/TextFrames
2772 if ( IsProperty( DFF_Prop_textRectangles ) )
2774 sal_uInt16 i;
2775 sal_uInt16 nNumElem = 0;
2776 sal_uInt16 nNumElemMem = 0;
2777 sal_uInt16 nElemSize = 16;
2779 if ( SeekToContent( DFF_Prop_textRectangles, rIn ) )
2780 rIn >> nNumElem >> nNumElemMem >> nElemSize;
2781 if ( nElemSize == 16 )
2783 sal_Int32 nLeft, nTop, nRight, nBottom;
2784 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem );
2785 for ( i = 0; i < nNumElem; i++ )
2787 rIn >> nLeft
2788 >> nTop
2789 >> nRight
2790 >> nBottom;
2792 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.First, nLeft );
2793 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.Second, nTop );
2794 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.First, nRight );
2795 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.Second, nBottom);
2797 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
2798 aProp.Name = sTextFrames;
2799 aProp.Value <<= aTextFrames;
2800 aPathPropVec.push_back( aProp );
2803 //Path/GluePoints
2804 if ( IsProperty( DFF_Prop_connectorPoints ) )
2806 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
2808 sal_uInt16 i;
2809 sal_uInt16 nNumElemVert = 0;
2810 sal_uInt16 nNumElemMemVert = 0;
2811 sal_uInt16 nElemSizeVert = 8;
2813 if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) )
2814 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
2816 sal_Int32 nX, nY;
2817 sal_Int16 nTmpA, nTmpB;
2818 aGluePoints.realloc( nNumElemVert );
2819 for ( i = 0; i < nNumElemVert; i++ )
2821 if ( nElemSizeVert == 8 )
2823 rIn >> nX
2824 >> nY;
2826 else
2828 rIn >> nTmpA
2829 >> nTmpB;
2831 nX = nTmpA;
2832 nY = nTmpB;
2834 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First, nX );
2835 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY );
2837 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
2838 aProp.Name = sGluePoints;
2839 aProp.Value <<= aGluePoints;
2840 aPathPropVec.push_back( aProp );
2842 if ( IsProperty( DFF_Prop_connectorType ) )
2844 sal_Int16 nGluePointType = (sal_uInt16)GetPropertyValue( DFF_Prop_connectorType );
2845 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
2846 aProp.Name = sGluePointType;
2847 aProp.Value <<= nGluePointType;
2848 aPathPropVec.push_back( aProp );
2850 // pushing the whole Path element
2851 if ( aPathPropVec.size() )
2853 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
2854 PropSeq aPathPropSeq( aPathPropVec.size() );
2855 aIter = aPathPropVec.begin();
2856 aEnd = aPathPropVec.end();
2857 beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
2858 while ( aIter != aEnd )
2859 *pPathValues++ = *aIter++;
2860 aProp.Name = sPath;
2861 aProp.Value <<= aPathPropSeq;
2862 aPropVec.push_back( aProp );
2865 /////////////////////////////////////////
2866 // "TextPath" PropertySequence element //
2867 /////////////////////////////////////////
2868 sal_Bool bTextPathOn = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x4000 ) != 0;
2869 if ( bTextPathOn )
2871 PropVec aTextPathPropVec;
2873 // TextPath
2874 const rtl::OUString sTextPathOn( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
2875 aProp.Name = sTextPathOn;
2876 aProp.Value <<= bTextPathOn;
2877 aTextPathPropVec.push_back( aProp );
2879 // TextPathMode
2880 const rtl::OUString sTextPathMode( RTL_CONSTASCII_USTRINGPARAM ( "TextPathMode" ) );
2881 sal_Bool bTextPathFitPath = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x100 ) != 0;
2883 sal_Bool bTextPathFitShape;
2884 if ( IsHardAttribute( DFF_Prop_gtextFStretch ) )
2885 bTextPathFitShape = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x400 ) != 0;
2886 else
2888 bTextPathFitShape = true;
2889 switch( eShapeType )
2891 case mso_sptTextArchUpCurve :
2892 case mso_sptTextArchDownCurve :
2893 case mso_sptTextCircleCurve :
2894 case mso_sptTextButtonCurve :
2895 bTextPathFitShape = false;
2896 default : break;
2899 EnhancedCustomShapeTextPathMode eTextPathMode( EnhancedCustomShapeTextPathMode_NORMAL );
2900 if ( bTextPathFitShape )
2901 eTextPathMode = EnhancedCustomShapeTextPathMode_SHAPE;
2902 else if ( bTextPathFitPath )
2903 eTextPathMode = EnhancedCustomShapeTextPathMode_PATH;
2904 aProp.Name = sTextPathMode;
2905 aProp.Value <<= eTextPathMode;
2906 aTextPathPropVec.push_back( aProp );
2908 // ScaleX
2909 const rtl::OUString sTextPathScaleX( RTL_CONSTASCII_USTRINGPARAM ( "ScaleX" ) );
2910 sal_Bool bTextPathScaleX = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x40 ) != 0;
2911 aProp.Name = sTextPathScaleX;
2912 aProp.Value <<= bTextPathScaleX;
2913 aTextPathPropVec.push_back( aProp );
2914 // SameLetterHeights
2915 const rtl::OUString sSameLetterHeight( RTL_CONSTASCII_USTRINGPARAM ( "SameLetterHeights" ) );
2916 sal_Bool bSameLetterHeight = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x80 ) != 0;
2917 aProp.Name = sSameLetterHeight;
2918 aProp.Value <<= bSameLetterHeight;
2919 aTextPathPropVec.push_back( aProp );
2921 // pushing the whole TextPath element
2922 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
2923 PropSeq aTextPathPropSeq( aTextPathPropVec.size() );
2924 aIter = aTextPathPropVec.begin();
2925 aEnd = aTextPathPropVec.end();
2926 beans::PropertyValue* pTextPathValues = aTextPathPropSeq.getArray();
2927 while ( aIter != aEnd )
2928 *pTextPathValues++ = *aIter++;
2929 aProp.Name = sTextPath;
2930 aProp.Value <<= aTextPathPropSeq;
2931 aPropVec.push_back( aProp );
2933 ////////////////////////
2934 // "AdjustmentValues" // The AdjustmentValues are imported at last, because depending to the type of the
2935 //////////////////////// handle (POLAR) we will convert the adjustment value from a fixed float to double
2937 // checking the last used adjustment handle, so we can determine how many handles are to allocate
2938 sal_Int32 i = DFF_Prop_adjust10Value;
2939 while ( ( i >= DFF_Prop_adjustValue ) && !IsProperty( i ) )
2940 i--;
2941 sal_Int32 nAdjustmentValues = ( i - DFF_Prop_adjustValue ) + 1;
2942 if ( nAdjustmentValues )
2944 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq( nAdjustmentValues );
2945 while( --nAdjustmentValues >= 0 )
2947 sal_Int32 nValue = 0;
2948 beans::PropertyState ePropertyState = beans::PropertyState_DEFAULT_VALUE;
2949 if ( IsProperty( i ) )
2951 nValue = GetPropertyValue( i );
2952 ePropertyState = beans::PropertyState_DIRECT_VALUE;
2954 if ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << ( i - DFF_Prop_adjustValue ) ) )
2956 double fValue = nValue;
2957 fValue /= 65536;
2958 aAdjustmentSeq[ nAdjustmentValues ].Value <<= fValue;
2960 else
2961 aAdjustmentSeq[ nAdjustmentValues ].Value <<= nValue;
2962 aAdjustmentSeq[ nAdjustmentValues ].State = ePropertyState;
2963 i--;
2965 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
2966 aProp.Name = sAdjustmentValues;
2967 aProp.Value <<= aAdjustmentSeq;
2968 aPropVec.push_back( aProp );
2971 // creating the whole property set
2972 PropSeq aSeq( aPropVec.size() );
2973 beans::PropertyValue* pValues = aSeq.getArray();
2974 aIter = aPropVec.begin();
2975 aEnd = aPropVec.end();
2976 while ( aIter != aEnd )
2977 *pValues++ = *aIter++;
2978 rSet.Put( SdrCustomShapeGeometryItem( aSeq ) );
2981 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, const MSO_SPT eShapeType, const sal_uInt32 nShapeFlags ) const
2983 // MapUnit eMap( rManager.GetModel()->GetScaleUnit() );
2985 for ( void* pDummy = ((DffPropertyReader*)this)->First(); pDummy; pDummy = ((DffPropertyReader*)this)->Next() )
2987 UINT32 nRecType = GetCurKey();
2988 UINT32 nContent = mpContents[ nRecType ];
2989 switch ( nRecType )
2991 case DFF_Prop_gtextSize :
2992 rSet.Put( SvxFontHeightItem( rManager.ScalePt( nContent ), 100, EE_CHAR_FONTHEIGHT ) );
2993 break;
2994 // GeoText
2995 case DFF_Prop_gtextFStrikethrough :
2997 if ( nContent & 0x20 )
2998 rSet.Put( SvxWeightItem( nContent ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
2999 if ( nContent & 0x10 )
3000 rSet.Put( SvxPostureItem( nContent ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
3001 if ( nContent & 0x08 )
3002 rSet.Put( SvxUnderlineItem( nContent ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
3003 if ( nContent & 0x40 )
3004 rSet.Put(SvxShadowedItem( nContent != 0, EE_CHAR_SHADOW ) );
3005 // if ( nContent & 0x02 )
3006 // rSet.Put( SvxCaseMapItem( nContent ? SVX_CASEMAP_KAPITAELCHEN : SVX_CASEMAP_NOT_MAPPED ) );
3007 if ( nContent & 0x01 )
3008 rSet.Put( SvxCrossedOutItem( nContent ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) );
3010 break;
3012 case DFF_Prop_fillColor :
3013 rSet.Put( XFillColorItem( String(), rManager.MSO_CLR_ToColor( nContent, DFF_Prop_fillColor ) ) );
3014 break;
3016 // ShadowStyle
3017 case DFF_Prop_shadowType :
3019 MSO_ShadowType eShadowType = (MSO_ShadowType)nContent;
3020 if( eShadowType != mso_shadowOffset )
3022 // mso_shadowDouble
3023 // mso_shadowRich
3024 // mso_shadowEmbossOrEngrave
3025 // koennen wir nicht, kreiere Default-Schatten mit default-
3026 // Abstand
3027 rSet.Put( SdrShadowXDistItem( 35 ) ); // 0,35 mm Schattendistanz
3028 rSet.Put( SdrShadowYDistItem( 35 ) );
3031 break;
3032 case DFF_Prop_shadowColor :
3033 rSet.Put( SdrShadowColorItem( String(), rManager.MSO_CLR_ToColor( nContent, DFF_Prop_shadowColor ) ) );
3034 break;
3035 case DFF_Prop_shadowOpacity :
3036 rSet.Put( SdrShadowTransparenceItem( (sal_uInt16)( ( 0x10000 - nContent ) / 655 ) ) );
3037 break;
3038 case DFF_Prop_shadowOffsetX :
3040 INT32 nVal = (INT32)nContent;
3041 rManager.ScaleEmu( nVal );
3042 if ( nVal )
3043 rSet.Put( SdrShadowXDistItem( nVal ) );
3045 break;
3046 case DFF_Prop_shadowOffsetY :
3048 INT32 nVal = (INT32)nContent;
3049 rManager.ScaleEmu( nVal );
3050 if ( nVal )
3051 rSet.Put( SdrShadowYDistItem( nVal ) );
3053 break;
3054 case DFF_Prop_fshadowObscured :
3056 sal_Bool bHasShadow = ( nContent & 2 ) != 0;
3057 rSet.Put( SdrShadowItem( bHasShadow ) );
3058 if ( bHasShadow )
3060 if ( !IsProperty( DFF_Prop_shadowOffsetX ) )
3061 rSet.Put( SdrShadowXDistItem( 35 ) );
3062 if ( !IsProperty( DFF_Prop_shadowOffsetY ) )
3063 rSet.Put( SdrShadowYDistItem( 35 ) );
3066 break;
3070 ApplyLineAttributes( rSet, eShapeType ); // #i28269#
3071 ApplyFillAttributes( rIn, rSet, eShapeType );
3072 if ( rManager.GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_IAS )
3074 if ( eShapeType != mso_sptNil )
3076 ApplyCustomShapeGeometryAttributes( rIn, rSet, eShapeType, nShapeFlags );
3077 ApplyCustomShapeTextAttributes( rSet );
3082 //---------------------------------------------------------------------------
3083 //- Record Manager ----------------------------------------------------------
3084 //---------------------------------------------------------------------------
3086 DffRecordList::DffRecordList( DffRecordList* pList ) :
3087 nCount ( 0 ),
3088 nCurrent ( 0 ),
3089 pPrev ( pList ),
3090 pNext ( NULL )
3092 if ( pList )
3093 pList->pNext = this;
3096 DffRecordList::~DffRecordList()
3098 delete pNext;
3101 DffRecordManager::DffRecordManager() :
3102 DffRecordList ( NULL ),
3103 pCList ( (DffRecordList*)this )
3107 DffRecordManager::DffRecordManager( SvStream& rIn ) :
3108 DffRecordList ( NULL ),
3109 pCList ( (DffRecordList*)this )
3111 Consume( rIn );
3114 DffRecordManager::~DffRecordManager()
3119 void DffRecordManager::Consume( SvStream& rIn, BOOL bAppend, UINT32 nStOfs )
3121 if ( !bAppend )
3122 Clear();
3123 UINT32 nOldPos = rIn.Tell();
3124 if ( !nStOfs )
3126 DffRecordHeader aHd;
3127 rIn >> aHd;
3128 if ( aHd.nRecVer == DFF_PSFLAG_CONTAINER )
3129 nStOfs = aHd.GetRecEndFilePos();
3131 if ( nStOfs )
3133 pCList = (DffRecordList*)this;
3134 while ( pCList->pNext )
3135 pCList = pCList->pNext;
3136 while ( ( rIn.GetError() == 0 ) && ( ( rIn.Tell() + 8 ) <= nStOfs ) )
3138 if ( pCList->nCount == DFF_RECORD_MANAGER_BUF_SIZE )
3139 pCList = new DffRecordList( pCList );
3140 rIn >> pCList->mHd[ pCList->nCount ];
3141 pCList->mHd[ pCList->nCount++ ].SeekToEndOfRecord( rIn );
3143 rIn.Seek( nOldPos );
3147 void DffRecordManager::Clear()
3149 pCList = (DffRecordList*)this;
3150 delete pNext, pNext = NULL;
3151 nCurrent = 0;
3152 nCount = 0;
3155 DffRecordHeader* DffRecordManager::Current()
3157 DffRecordHeader* pRet = NULL;
3158 if ( pCList->nCurrent < pCList->nCount )
3159 pRet = &pCList->mHd[ pCList->nCurrent ];
3160 return pRet;
3163 DffRecordHeader* DffRecordManager::First()
3165 DffRecordHeader* pRet = NULL;
3166 pCList = (DffRecordList*)this;
3167 if ( pCList->nCount )
3169 pCList->nCurrent = 0;
3170 pRet = &pCList->mHd[ 0 ];
3172 return pRet;
3175 DffRecordHeader* DffRecordManager::Next()
3177 DffRecordHeader* pRet = NULL;
3178 UINT32 nC = pCList->nCurrent + 1;
3179 if ( nC < pCList->nCount )
3181 pCList->nCurrent++;
3182 pRet = &pCList->mHd[ nC ];
3184 else if ( pCList->pNext )
3186 pCList = pCList->pNext;
3187 pCList->nCurrent = 0;
3188 pRet = &pCList->mHd[ 0 ];
3190 return pRet;
3193 DffRecordHeader* DffRecordManager::Prev()
3195 DffRecordHeader* pRet = NULL;
3196 UINT32 nCur = pCList->nCurrent;
3197 if ( !nCur && pCList->pPrev )
3199 pCList = pCList->pPrev;
3200 nCur = pCList->nCount;
3202 if ( nCur-- )
3204 pCList->nCurrent = nCur;
3205 pRet = &pCList->mHd[ nCur ];
3207 return pRet;
3210 DffRecordHeader* DffRecordManager::Last()
3212 DffRecordHeader* pRet = NULL;
3213 while ( pCList->pNext )
3214 pCList = pCList->pNext;
3215 UINT32 nCnt = pCList->nCount;
3216 if ( nCnt-- )
3218 pCList->nCurrent = nCnt;
3219 pRet = &pCList->mHd[ nCnt ];
3221 return pRet;
3224 BOOL DffRecordManager::SeekToContent( SvStream& rIn, UINT16 nRecId, DffSeekToContentMode eMode )
3226 DffRecordHeader* pHd = GetRecordHeader( nRecId, eMode );
3227 if ( pHd )
3229 pHd->SeekToContent( rIn );
3230 return TRUE;
3232 else
3233 return FALSE;
3236 DffRecordHeader* DffRecordManager::GetRecordHeader( UINT16 nRecId, DffSeekToContentMode eMode )
3238 UINT32 nOldCurrent = pCList->nCurrent;
3239 DffRecordList* pOldList = pCList;
3240 DffRecordHeader* pHd;
3242 if ( eMode == SEEK_FROM_BEGINNING )
3243 pHd = First();
3244 else
3245 pHd = Next();
3247 while ( pHd )
3249 if ( pHd->nRecType == nRecId )
3250 break;
3251 pHd = Next();
3253 if ( !pHd && eMode == SEEK_FROM_CURRENT_AND_RESTART )
3255 DffRecordHeader* pBreak = &pOldList->mHd[ nOldCurrent ];
3256 pHd = First();
3257 if ( pHd )
3259 while ( pHd != pBreak )
3261 if ( pHd->nRecType == nRecId )
3262 break;
3263 pHd = Next();
3265 if ( pHd->nRecType != nRecId )
3266 pHd = NULL;
3269 if ( !pHd )
3271 pCList = pOldList;
3272 pOldList->nCurrent = nOldCurrent;
3274 return pHd;
3277 //---------------------------------------------------------------------------
3278 // private Methoden
3279 //---------------------------------------------------------------------------
3281 struct EscherBlipCacheEntry
3283 ByteString aUniqueID;
3284 sal_uInt32 nBlip;
3286 EscherBlipCacheEntry( sal_uInt32 nBlipId, const ByteString& rUniqueID ) :
3287 aUniqueID( rUniqueID ),
3288 nBlip( nBlipId ) {}
3291 void SvxMSDffManager::Scale( sal_Int32& rVal ) const
3293 if ( bNeedMap )
3294 rVal = BigMulDiv( rVal, nMapMul, nMapDiv );
3297 void SvxMSDffManager::Scale( Point& rPos ) const
3299 rPos.X() += nMapXOfs;
3300 rPos.Y() += nMapYOfs;
3301 if ( bNeedMap )
3303 rPos.X() = BigMulDiv( rPos.X(), nMapMul, nMapDiv );
3304 rPos.Y() = BigMulDiv( rPos.Y(), nMapMul, nMapDiv );
3308 void SvxMSDffManager::Scale( Size& rSiz ) const
3310 if ( bNeedMap )
3312 rSiz.Width() = BigMulDiv( rSiz.Width(), nMapMul, nMapDiv );
3313 rSiz.Height() = BigMulDiv( rSiz.Height(), nMapMul, nMapDiv );
3317 void SvxMSDffManager::Scale( Rectangle& rRect ) const
3319 rRect.Move( nMapXOfs, nMapYOfs );
3320 if ( bNeedMap )
3322 rRect.Left() =BigMulDiv( rRect.Left() , nMapMul, nMapDiv );
3323 rRect.Top() =BigMulDiv( rRect.Top() , nMapMul, nMapDiv );
3324 rRect.Right() =BigMulDiv( rRect.Right() , nMapMul, nMapDiv );
3325 rRect.Bottom()=BigMulDiv( rRect.Bottom(), nMapMul, nMapDiv );
3329 void SvxMSDffManager::Scale( Polygon& rPoly ) const
3331 if ( !bNeedMap )
3332 return;
3333 USHORT nPointAnz = rPoly.GetSize();
3334 for ( USHORT nPointNum = 0; nPointNum < nPointAnz; nPointNum++ )
3335 Scale( rPoly[ nPointNum ] );
3338 void SvxMSDffManager::Scale( PolyPolygon& rPoly ) const
3340 if ( !bNeedMap )
3341 return;
3342 USHORT nPolyAnz = rPoly.Count();
3343 for ( USHORT nPolyNum = 0; nPolyNum < nPolyAnz; nPolyNum++ )
3344 Scale( rPoly[ nPolyNum ] );
3347 void SvxMSDffManager::ScaleEmu( sal_Int32& rVal ) const
3349 rVal = BigMulDiv( rVal, nEmuMul, nEmuDiv );
3352 UINT32 SvxMSDffManager::ScalePt( UINT32 nVal ) const
3354 MapUnit eMap = pSdrModel->GetScaleUnit();
3355 Fraction aFact( GetMapFactor( MAP_POINT, eMap ).X() );
3356 long aMul = aFact.GetNumerator();
3357 long aDiv = aFact.GetDenominator() * 65536;
3358 aFact = Fraction( aMul, aDiv ); // nochmal versuchen zu kuerzen
3359 return BigMulDiv( nVal, aFact.GetNumerator(), aFact.GetDenominator() );
3362 INT32 SvxMSDffManager::ScalePoint( INT32 nVal ) const
3364 return BigMulDiv( nVal, nPntMul, nPntDiv );
3367 void SvxMSDffManager::SetModel(SdrModel* pModel, long nApplicationScale)
3369 pSdrModel = pModel;
3370 if( pModel && (0 < nApplicationScale) )
3372 // PPT arbeitet nur mit Einheiten zu 576DPI
3373 // WW hingegen verwendet twips, dh. 1440DPI.
3374 MapUnit eMap = pSdrModel->GetScaleUnit();
3375 Fraction aFact( GetMapFactor(MAP_INCH, eMap).X() );
3376 long nMul=aFact.GetNumerator();
3377 long nDiv=aFact.GetDenominator()*nApplicationScale;
3378 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3379 // Bei 100TH_MM -> 2540/576=635/144
3380 // Bei Twip -> 1440/576=5/2
3381 nMapMul = aFact.GetNumerator();
3382 nMapDiv = aFact.GetDenominator();
3383 bNeedMap = nMapMul!=nMapDiv;
3385 // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
3386 // 1mm=36000emu, 1twip=635emu
3387 aFact=GetMapFactor(MAP_100TH_MM,eMap).X();
3388 nMul=aFact.GetNumerator();
3389 nDiv=aFact.GetDenominator()*360;
3390 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3391 // Bei 100TH_MM -> 1/360
3392 // Bei Twip -> 14,40/(25,4*360)=144/91440=1/635
3393 nEmuMul=aFact.GetNumerator();
3394 nEmuDiv=aFact.GetDenominator();
3396 // Und noch was fuer typografische Points
3397 aFact=GetMapFactor(MAP_POINT,eMap).X();
3398 nPntMul=aFact.GetNumerator();
3399 nPntDiv=aFact.GetDenominator();
3401 else
3403 pModel = 0;
3404 nMapMul = nMapDiv = nMapXOfs = nMapYOfs = nEmuMul = nEmuDiv = nPntMul = nPntDiv = 0;
3405 bNeedMap = FALSE;
3409 BOOL SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, UINT32 nId ) const
3411 BOOL bRet = FALSE;
3412 if ( mpFidcls )
3414 UINT32 nMerk = rSt.Tell();
3415 UINT32 nShapeId, nSec = ( nId >> 10 ) - 1;
3416 if ( nSec < mnIdClusters )
3418 sal_IntPtr nOfs = (sal_IntPtr)maDgOffsetTable.Get( mpFidcls[ nSec ].dgid );
3419 if ( nOfs )
3421 rSt.Seek( nOfs );
3422 DffRecordHeader aEscherF002Hd;
3423 rSt >> aEscherF002Hd;
3424 ULONG nEscherF002End = aEscherF002Hd.GetRecEndFilePos();
3425 DffRecordHeader aEscherObjListHd;
3426 while ( rSt.Tell() < nEscherF002End )
3428 rSt >> aEscherObjListHd;
3429 if ( aEscherObjListHd.nRecVer != 0xf )
3430 aEscherObjListHd.SeekToEndOfRecord( rSt );
3431 else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer )
3433 DffRecordHeader aShapeHd;
3434 if ( SeekToRec( rSt, DFF_msofbtSp, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) )
3436 rSt >> nShapeId;
3437 if ( nId == nShapeId )
3439 aEscherObjListHd.SeekToBegOfRecord( rSt );
3440 bRet = TRUE;
3441 break;
3444 aEscherObjListHd.SeekToEndOfRecord( rSt );
3449 if ( !bRet )
3450 rSt.Seek( nMerk );
3452 return bRet;
3455 FASTBOOL SvxMSDffManager::SeekToRec( SvStream& rSt, USHORT nRecId, ULONG nMaxFilePos, DffRecordHeader* pRecHd, ULONG nSkipCount ) const
3457 FASTBOOL bRet = FALSE;
3458 ULONG nFPosMerk = rSt.Tell(); // FilePos merken fuer ggf. spaetere Restauration
3459 DffRecordHeader aHd;
3462 rSt >> aHd;
3463 if ( aHd.nRecType == nRecId )
3465 if ( nSkipCount )
3466 nSkipCount--;
3467 else
3469 bRet = TRUE;
3470 if ( pRecHd != NULL )
3471 *pRecHd = aHd;
3472 else
3473 aHd.SeekToBegOfRecord( rSt );
3476 if ( !bRet )
3477 aHd.SeekToEndOfRecord( rSt );
3479 while ( rSt.GetError() == 0 && rSt.Tell() < nMaxFilePos && !bRet );
3480 if ( !bRet )
3481 rSt.Seek( nFPosMerk ); // FilePos restaurieren
3482 return bRet;
3485 FASTBOOL SvxMSDffManager::SeekToRec2( USHORT nRecId1, USHORT nRecId2, ULONG nMaxFilePos, DffRecordHeader* pRecHd, ULONG nSkipCount ) const
3487 FASTBOOL bRet = FALSE;
3488 ULONG nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer ggf. spaetere Restauration
3489 DffRecordHeader aHd;
3492 rStCtrl >> aHd;
3493 if ( aHd.nRecType == nRecId1 || aHd.nRecType == nRecId2 )
3495 if ( nSkipCount )
3496 nSkipCount--;
3497 else
3499 bRet = TRUE;
3500 if ( pRecHd )
3501 *pRecHd = aHd;
3502 else
3503 aHd.SeekToBegOfRecord( rStCtrl );
3506 if ( !bRet )
3507 aHd.SeekToEndOfRecord( rStCtrl );
3509 while ( rStCtrl.GetError() == 0 && rStCtrl.Tell() < nMaxFilePos && !bRet );
3510 if ( !bRet )
3511 rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
3512 return bRet;
3516 FASTBOOL SvxMSDffManager::GetColorFromPalette( USHORT /* nNum */, Color& rColor ) const
3518 // diese Methode ist in der zum Excel-Import
3519 // abgeleiteten Klasse zu ueberschreiben...
3520 rColor.SetColor( COL_WHITE );
3521 return TRUE;
3525 Color SvxMSDffManager::MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContentProperty ) const
3527 Color aColor( mnDefaultColor );
3529 // Fuer Textfarben: Header ist 0xfeRRGGBB
3530 if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 )
3531 nColorCode &= 0x00ffffff;
3533 sal_uInt8 nUpper = (sal_uInt8)( nColorCode >> 24 );
3534 if( nUpper & 0x19 ) // if( nUpper & 0x1f )
3536 if( ( nUpper & 0x08 ) || ( ( nUpper & 0x10 ) == 0 ) )
3538 // SCHEMECOLOR
3539 if ( !GetColorFromPalette( ( nUpper & 8 ) ? (sal_uInt16)nColorCode : nUpper, aColor ) )
3541 switch( nContentProperty )
3543 case DFF_Prop_pictureTransparent :
3544 case DFF_Prop_shadowColor :
3545 case DFF_Prop_fillBackColor :
3546 case DFF_Prop_fillColor :
3547 aColor = Color( COL_WHITE );
3548 break;
3549 case DFF_Prop_lineColor :
3551 aColor = Color( COL_BLACK );
3553 break;
3557 else // SYSCOLOR
3559 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
3561 // UINT16 nParameter = (BYTE)( nColorCode >> 16); // SJ: nice compiler optimization bug on windows, though downcasting
3562 UINT16 nParameter = sal_uInt16(( nColorCode >> 16 ) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o
3563 UINT16 nFunctionBits = (UINT16)( ( nColorCode & 0x00000f00 ) >> 8 );
3564 UINT16 nAdditionalFlags = (UINT16)( ( nColorCode & 0x0000f000) >> 8 );
3565 UINT16 nColorIndex = sal_uInt16(nColorCode & 0x00ff);
3566 UINT32 nPropColor = 0;
3568 sal_uInt16 nCProp = 0;
3570 switch ( nColorIndex )
3572 case mso_syscolorButtonFace : aColor = rStyleSettings.GetFaceColor(); break;
3573 case mso_syscolorWindowText : aColor = rStyleSettings.GetWindowTextColor(); break;
3574 case mso_syscolorMenu : aColor = rStyleSettings.GetMenuColor(); break;
3575 case mso_syscolor3DLight :
3576 case mso_syscolorButtonHighlight :
3577 case mso_syscolorHighlight : aColor = rStyleSettings.GetHighlightColor(); break;
3578 case mso_syscolorHighlightText : aColor = rStyleSettings.GetHighlightTextColor(); break;
3579 case mso_syscolorCaptionText : aColor = rStyleSettings.GetMenuTextColor(); break;
3580 case mso_syscolorActiveCaption : aColor = rStyleSettings.GetHighlightColor(); break;
3581 case mso_syscolorButtonShadow : aColor = rStyleSettings.GetShadowColor(); break;
3582 case mso_syscolorButtonText : aColor = rStyleSettings.GetButtonTextColor(); break;
3583 case mso_syscolorGrayText : aColor = rStyleSettings.GetDeactiveColor(); break;
3584 case mso_syscolorInactiveCaption : aColor = rStyleSettings.GetDeactiveColor(); break;
3585 case mso_syscolorInactiveCaptionText : aColor = rStyleSettings.GetDeactiveColor(); break;
3586 case mso_syscolorInfoBackground : aColor = rStyleSettings.GetFaceColor(); break;
3587 case mso_syscolorInfoText : aColor = rStyleSettings.GetInfoTextColor(); break;
3588 case mso_syscolorMenuText : aColor = rStyleSettings.GetMenuTextColor(); break;
3589 case mso_syscolorScrollbar : aColor = rStyleSettings.GetFaceColor(); break;
3590 case mso_syscolorWindow : aColor = rStyleSettings.GetWindowColor(); break;
3591 case mso_syscolorWindowFrame : aColor = rStyleSettings.GetWindowColor(); break;
3593 case mso_colorFillColor :
3595 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3596 nCProp = DFF_Prop_fillColor;
3598 break;
3599 case mso_colorLineOrFillColor : // ( use the line color only if there is a line )
3601 if ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 )
3603 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3604 nCProp = DFF_Prop_lineColor;
3606 else
3608 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3609 nCProp = DFF_Prop_fillColor;
3612 break;
3613 case mso_colorLineColor :
3615 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3616 nCProp = DFF_Prop_lineColor;
3618 break;
3619 case mso_colorShadowColor :
3621 nPropColor = GetPropertyValue( DFF_Prop_shadowColor, 0x808080 );
3622 nCProp = DFF_Prop_shadowColor;
3624 break;
3625 case mso_colorThis : // ( use this color ... )
3627 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3628 nCProp = DFF_Prop_fillColor;
3630 break;
3631 case mso_colorFillBackColor :
3633 nPropColor = GetPropertyValue( DFF_Prop_fillBackColor, 0xffffff );
3634 nCProp = DFF_Prop_fillBackColor;
3636 break;
3637 case mso_colorLineBackColor :
3639 nPropColor = GetPropertyValue( DFF_Prop_lineBackColor, 0xffffff );
3640 nCProp = DFF_Prop_lineBackColor;
3642 break;
3643 case mso_colorFillThenLine : // ( use the fillcolor unless no fill and line )
3645 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3646 nCProp = DFF_Prop_fillColor;
3648 break;
3649 case mso_colorIndexMask : // ( extract the color index ) ?
3651 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3652 nCProp = DFF_Prop_fillColor;
3654 break;
3656 if ( nCProp && ( nPropColor & 0x10000000 ) == 0 ) // beware of looping recursive
3657 aColor = MSO_CLR_ToColor( nPropColor, nCProp );
3659 if( nAdditionalFlags & 0x80 ) // make color gray
3661 UINT8 nZwi = aColor.GetLuminance();
3662 aColor = Color( nZwi, nZwi, nZwi );
3664 switch( nFunctionBits )
3666 case 0x01 : // darken color by parameter
3668 aColor.SetRed( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetRed() ) >> 8 ) );
3669 aColor.SetGreen( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetGreen() ) >> 8 ) );
3670 aColor.SetBlue( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetBlue() ) >> 8 ) );
3672 break;
3673 case 0x02 : // lighten color by parameter
3675 UINT16 nInvParameter = ( 0x00ff - nParameter ) * 0xff;
3676 aColor.SetRed( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetRed() ) ) >> 8 ) );
3677 aColor.SetGreen( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetGreen() ) ) >> 8 ) );
3678 aColor.SetBlue( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetBlue() ) ) >> 8 ) );
3680 break;
3681 case 0x03 : // add grey level RGB(p,p,p)
3683 INT16 nR = (INT16)aColor.GetRed() + (INT16)nParameter;
3684 INT16 nG = (INT16)aColor.GetGreen() + (INT16)nParameter;
3685 INT16 nB = (INT16)aColor.GetBlue() + (INT16)nParameter;
3686 if ( nR > 0x00ff )
3687 nR = 0x00ff;
3688 if ( nG > 0x00ff )
3689 nG = 0x00ff;
3690 if ( nB > 0x00ff )
3691 nB = 0x00ff;
3692 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3694 break;
3695 case 0x04 : // substract grey level RGB(p,p,p)
3697 INT16 nR = (INT16)aColor.GetRed() - (INT16)nParameter;
3698 INT16 nG = (INT16)aColor.GetGreen() - (INT16)nParameter;
3699 INT16 nB = (INT16)aColor.GetBlue() - (INT16)nParameter;
3700 if ( nR < 0 )
3701 nR = 0;
3702 if ( nG < 0 )
3703 nG = 0;
3704 if ( nB < 0 )
3705 nB = 0;
3706 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3708 break;
3709 case 0x05 : // substract from grey level RGB(p,p,p)
3711 INT16 nR = (INT16)nParameter - (INT16)aColor.GetRed();
3712 INT16 nG = (INT16)nParameter - (INT16)aColor.GetGreen();
3713 INT16 nB = (INT16)nParameter - (INT16)aColor.GetBlue();
3714 if ( nR < 0 )
3715 nR = 0;
3716 if ( nG < 0 )
3717 nG = 0;
3718 if ( nB < 0 )
3719 nB = 0;
3720 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3722 break;
3723 case 0x06 : // per component: black if < p, white if >= p
3725 aColor.SetRed( aColor.GetRed() < nParameter ? 0x00 : 0xff );
3726 aColor.SetGreen( aColor.GetGreen() < nParameter ? 0x00 : 0xff );
3727 aColor.SetBlue( aColor.GetBlue() < nParameter ? 0x00 : 0xff );
3729 break;
3731 if ( nAdditionalFlags & 0x40 ) // top-bit invert
3732 aColor = Color( aColor.GetRed() ^ 0x80, aColor.GetGreen() ^ 0x80, aColor.GetBlue() ^ 0x80 );
3734 if ( nAdditionalFlags & 0x20 ) // invert color
3735 aColor = Color(0xff - aColor.GetRed(), 0xff - aColor.GetGreen(), 0xff - aColor.GetBlue());
3738 else if ( ( nUpper & 4 ) && ( ( nColorCode & 0xfffff8 ) == 0 ) )
3739 { // case of nUpper == 4 powerpoint takes this as agrument for a colorschemecolor
3740 GetColorFromPalette( nUpper, aColor );
3742 else // hart attributiert, eventuell mit Hinweis auf SYSTEMRGB
3743 aColor = Color( (BYTE)nColorCode, (BYTE)( nColorCode >> 8 ), (BYTE)( nColorCode >> 16 ) );
3744 return aColor;
3747 FASTBOOL SvxMSDffManager::ReadDffString(SvStream& rSt, String& rTxt) const
3749 FASTBOOL bRet=FALSE;
3750 DffRecordHeader aStrHd;
3751 if( !ReadCommonRecordHeader(aStrHd, rSt) )
3752 rSt.Seek( aStrHd.nFilePos );
3753 else if ( aStrHd.nRecType == DFF_PST_TextBytesAtom || aStrHd.nRecType == DFF_PST_TextCharsAtom )
3755 FASTBOOL bUniCode=aStrHd.nRecType==DFF_PST_TextCharsAtom;
3756 bRet=TRUE;
3757 ULONG nBytes = aStrHd.nRecLen;
3758 MSDFFReadZString( rSt, rTxt, nBytes, bUniCode );
3759 if( !bUniCode )
3761 for ( xub_StrLen n = 0; n < nBytes; n++ )
3763 if( rTxt.GetChar( n ) == 0x0B )
3764 rTxt.SetChar( n, ' ' ); // Weicher Umbruch
3765 // TODO: Zeilenumbruch im Absatz via Outliner setzen.
3768 aStrHd.SeekToEndOfRecord( rSt );
3770 else
3771 aStrHd.SeekToBegOfRecord( rSt );
3772 return bRet;
3775 // sj: I just want to set a string for a text object that may contain multiple
3776 // paragraphs. If I now take a look at the follwing code I get the impression that
3777 // our outliner is too complicate to be used properly,
3778 void SvxMSDffManager::ReadObjText( const String& rText, SdrObject* pObj ) const
3780 SdrTextObj* pText = PTR_CAST( SdrTextObj, pObj );
3781 if ( pText )
3783 SdrOutliner& rOutliner = pText->ImpGetDrawOutliner();
3784 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
3786 BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
3787 rOutliner.SetUpdateMode( FALSE );
3788 rOutliner.SetVertical( pText->IsVerticalWriting() );
3790 sal_uInt16 nParaIndex = 0;
3791 sal_uInt32 nParaSize;
3792 const sal_Unicode* pCurrent, *pBuf = rText.GetBuffer();
3793 const sal_Unicode* pEnd = rText.GetBuffer() + rText.Len();
3795 while( pBuf < pEnd )
3797 pCurrent = pBuf;
3799 for ( nParaSize = 0; pBuf < pEnd; )
3801 sal_Unicode nChar = *pBuf++;
3802 if ( nChar == 0xa )
3804 if ( ( pBuf < pEnd ) && ( *pBuf == 0xd ) )
3805 pBuf++;
3806 break;
3808 else if ( nChar == 0xd )
3810 if ( ( pBuf < pEnd ) && ( *pBuf == 0xa ) )
3811 pBuf++;
3812 break;
3814 else
3815 nParaSize++;
3817 ESelection aSelection( nParaIndex, 0, nParaIndex, 0 );
3818 String aParagraph( pCurrent, (sal_uInt16)nParaSize );
3819 if ( !nParaIndex && !aParagraph.Len() ) // SJ: we are crashing if the first paragraph is empty ?
3820 aParagraph += (sal_Unicode)' '; // otherwise these two lines can be removed.
3821 rOutliner.Insert( aParagraph, nParaIndex, 0 );
3822 rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() );
3824 SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() );
3825 if ( !aSelection.nStartPos )
3826 aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, FALSE ) );
3827 aSelection.nStartPos = 0;
3828 rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection );
3829 nParaIndex++;
3831 OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
3832 rOutliner.Clear();
3833 rOutliner.SetUpdateMode( bOldUpdateMode );
3834 pText->SetOutlinerParaObject( pNewText );
3838 FASTBOOL SvxMSDffManager::ReadObjText(SvStream& rSt, SdrObject* pObj) const
3840 FASTBOOL bRet=FALSE;
3841 SdrTextObj* pText = PTR_CAST(SdrTextObj, pObj);
3842 if( pText )
3844 DffRecordHeader aTextHd;
3845 if( !ReadCommonRecordHeader(aTextHd, rSt) )
3846 rSt.Seek( aTextHd.nFilePos );
3847 else if ( aTextHd.nRecType==DFF_msofbtClientTextbox )
3849 bRet=TRUE;
3850 ULONG nRecEnd=aTextHd.GetRecEndFilePos();
3851 DffRecordHeader aHd;
3852 String aText;
3853 // UINT32 nInvent=pText->GetObjInventor();
3854 // UINT16 nIdent=pText->GetObjIdentifier();
3856 SdrOutliner& rOutliner=pText->ImpGetDrawOutliner();
3857 // sal_Int16 nMinDepth = rOutliner.GetMinDepth();
3858 USHORT nOutlMode = rOutliner.GetMode();
3860 { // Wohl 'nen kleiner Bug der EditEngine, das die
3861 // Absastzattribute bei Clear() nicht entfernt werden.
3862 FASTBOOL bClearParaAttribs = TRUE;
3863 rOutliner.SetStyleSheet( 0, NULL );
3864 SfxItemSet aSet(rOutliner.GetEmptyItemSet());
3865 aSet.Put(SvxColorItem( COL_BLACK ));
3866 rOutliner.SetParaAttribs(0,aSet);
3867 pText->SetMergedItemSet(aSet);
3869 bClearParaAttribs = FALSE;
3870 if( bClearParaAttribs )
3872 // Wohl 'nen kleiner Bug der EditEngine, dass die
3873 // Absastzattribute bei Clear() nicht entfernt werden.
3874 rOutliner.SetParaAttribs(0,rOutliner.GetEmptyItemSet());
3877 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
3879 // ULONG nFilePosMerker=rSt.Tell();
3880 ////////////////////////////////////
3881 // TextString und MetaChars lesen //
3882 ////////////////////////////////////
3885 if( !ReadCommonRecordHeader(aHd, rSt) )
3886 rSt.Seek( aHd.nFilePos );
3887 else
3889 switch (aHd.nRecType)
3891 //case TextHeaderAtom
3892 //case TextSpecInfoAtom
3893 case DFF_PST_TextBytesAtom:
3894 case DFF_PST_TextCharsAtom:
3896 aHd.SeekToBegOfRecord(rSt);
3897 ReadDffString(rSt, aText);
3899 break;
3900 case DFF_PST_TextRulerAtom :
3902 UINT16 nLen = (UINT16)aHd.nRecLen;
3903 if(nLen)
3905 UINT16 nVal1, nVal2, nVal3;
3906 UINT16 nDefaultTab = 2540; // PPT def: 1 Inch //rOutliner.GetDefTab();
3907 UINT16 nMostrightTab = 0;
3908 SfxItemSet aSet(rOutliner.GetEmptyItemSet());
3909 SvxTabStopItem aTabItem(0, 0, SVX_TAB_ADJUST_DEFAULT, EE_PARA_TABS);
3911 rSt >> nVal1;
3912 rSt >> nVal2;
3913 nLen -= 4;
3915 // Allg. TAB verstellt auf Wert in nVal3
3916 if(nLen && (nVal1 & 0x0001))
3918 rSt >> nVal3;
3919 nLen -= 2;
3920 nDefaultTab = (UINT16)(((UINT32)nVal3 * 1000) / 240);
3923 // Weitere, frei gesetzte TABs
3924 if(nLen && (nVal1 & 0x0004))
3926 rSt >> nVal1;
3927 nLen -= 2;
3929 // fest gesetzte TABs importieren
3930 while(nLen && nVal1--)
3932 rSt >> nVal2;
3933 rSt >> nVal3;
3934 nLen -= 4;
3936 UINT16 nNewTabPos = (UINT16)(((UINT32)nVal2 * 1000) / 240);
3937 if(nNewTabPos > nMostrightTab)
3938 nMostrightTab = nNewTabPos;
3940 SvxTabStop aTabStop(nNewTabPos);
3941 aTabItem.Insert(aTabStop);
3945 // evtl. noch default-TABs ergaenzen (immer)
3946 UINT16 nObjWidth = sal_uInt16(pObj->GetSnapRect().GetWidth() + 1);
3947 UINT16 nDefaultTabPos = nDefaultTab;
3949 while(nDefaultTabPos <= nObjWidth && nDefaultTabPos <= nMostrightTab)
3950 nDefaultTabPos =
3951 nDefaultTabPos + nDefaultTab;
3953 while(nDefaultTabPos <= nObjWidth)
3955 SvxTabStop aTabStop(nDefaultTabPos);
3956 aTabItem.Insert(aTabStop);
3957 nDefaultTabPos =
3958 nDefaultTabPos + nDefaultTab;
3961 // Falls TABs angelegt wurden, setze diese
3962 if(aTabItem.Count())
3964 aSet.Put(aTabItem);
3965 rOutliner.SetParaAttribs(0, aSet);
3969 break;
3971 aHd.SeekToEndOfRecord( rSt );
3974 while ( rSt.GetError() == 0 && rSt.Tell() < nRecEnd );
3976 ////////////////////////
3977 // SHIFT-Ret ersetzen //
3978 ////////////////////////
3979 if ( aText.Len() )
3981 aText += ' ';
3982 aText.SetChar( aText.Len()-1, 0x0D );
3983 rOutliner.SetText( aText, rOutliner.GetParagraph( 0 ) );
3985 // SHIFT-Ret ersetzen im Outliner
3986 if(aText.GetTokenCount(0x0B) > 1)
3988 UINT32 nParaCount = rOutliner.GetParagraphCount();
3989 for(UINT16 a=0;a<nParaCount;a++)
3991 Paragraph* pActPara = rOutliner.GetParagraph(a);
3992 String aParaText = rOutliner.GetText(pActPara);
3993 for(UINT16 b=0;b<aParaText.Len();b++)
3995 if( aParaText.GetChar( b ) == 0x0B)
3997 ESelection aSelection(a, b, a, b+1);
3998 rOutliner.QuickInsertLineBreak(aSelection);
4004 OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
4005 rOutliner.Init( nOutlMode );
4006 pText->NbcSetOutlinerParaObject(pNewText);
4008 else
4009 aTextHd.SeekToBegOfRecord(rSt);
4012 return bRet;
4015 //static
4016 void SvxMSDffManager::MSDFFReadZString( SvStream& rIn, String& rStr,
4017 ULONG nRecLen, FASTBOOL bUniCode )
4019 sal_uInt16 nLen = (sal_uInt16)nRecLen;
4020 if( nLen )
4022 if ( bUniCode )
4023 nLen >>= 1;
4025 String sBuf;
4026 sal_Unicode* pBuf = sBuf.AllocBuffer( nLen );
4028 if( bUniCode )
4030 rIn.Read( (sal_Char*)pBuf, nLen << 1 );
4032 #ifdef OSL_BIGENDIAN
4033 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf )
4034 *pBuf = SWAPSHORT( *pBuf );
4035 #endif // ifdef OSL_BIGENDIAN
4037 else
4039 // use the String-Data as buffer for the 8bit characters and
4040 // change then all to unicode
4041 sal_Char* pReadPos = ((sal_Char*)pBuf) + nLen;
4042 rIn.Read( (sal_Char*)pReadPos, nLen );
4043 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf, ++pReadPos )
4044 *pBuf = ByteString::ConvertToUnicode( *pReadPos, RTL_TEXTENCODING_MS_1252 );
4047 rStr = sBuf.EraseTrailingChars( 0 );
4049 else
4050 rStr.Erase();
4053 SdrObject* SvxMSDffManager::ImportFontWork( SvStream& rStCt, SfxItemSet& rSet, Rectangle& rBoundRect ) const
4055 SdrObject* pRet = NULL;
4056 String aObjectText;
4057 String aFontName;
4058 BOOL bTextRotate = FALSE;
4060 ((SvxMSDffManager*)this)->mnFix16Angle = 0; // we don't want to use this property in future
4061 if ( SeekToContent( DFF_Prop_gtextUNICODE, rStCt ) )
4062 MSDFFReadZString( rStCt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), TRUE );
4063 if ( SeekToContent( DFF_Prop_gtextFont, rStCt ) )
4064 MSDFFReadZString( rStCt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), TRUE );
4065 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 )
4067 // Text ist senkrecht formatiert, Box Kippen
4068 INT32 nHalfWidth = ( rBoundRect.GetWidth() + 1) >> 1;
4069 INT32 nHalfHeight = ( rBoundRect.GetHeight() + 1) >> 1;
4070 Point aTopLeft( rBoundRect.Left() + nHalfWidth - nHalfHeight,
4071 rBoundRect.Top() + nHalfHeight - nHalfWidth);
4072 Size aNewSize( rBoundRect.GetHeight(), rBoundRect.GetWidth() );
4073 Rectangle aNewRect( aTopLeft, aNewSize );
4074 rBoundRect = aNewRect;
4076 String aSrcText( aObjectText );
4077 aObjectText.Erase();
4078 for( UINT16 a = 0; a < aSrcText.Len(); a++ )
4080 aObjectText += aSrcText.GetChar( a );
4081 aObjectText += '\n';
4083 rSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) );
4084 bTextRotate = TRUE;
4086 if ( aObjectText.Len() )
4087 { // FontWork-Objekt Mit dem Text in aObjectText erzeugen
4088 SdrObject* pNewObj = new SdrRectObj( OBJ_TEXT, rBoundRect );
4089 if( pNewObj )
4091 pNewObj->SetModel( pSdrModel );
4092 ((SdrRectObj*)pNewObj)->SetText( aObjectText );
4093 SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
4094 rSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
4095 rSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
4096 rSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
4097 rSet.Put( SvxFontItem( FAMILY_DONTKNOW, aFontName, String(),
4098 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
4100 pNewObj->SetMergedItemSet(rSet);
4102 pRet = pNewObj->ConvertToPolyObj( FALSE, FALSE );
4103 if( !pRet )
4104 pRet = pNewObj;
4105 else
4107 pRet->NbcSetSnapRect( rBoundRect );
4108 SdrObject::Free( pNewObj );
4110 if( bTextRotate )
4112 double a = 9000 * nPi180;
4113 pRet->NbcRotate( rBoundRect.Center(), 9000, sin( a ), cos( a ) );
4117 return pRet;
4120 static Size lcl_GetPrefSize(const Graphic& rGraf, MapMode aWanted)
4122 MapMode aPrefMapMode(rGraf.GetPrefMapMode());
4123 if (aPrefMapMode == aWanted)
4124 return rGraf.GetPrefSize();
4125 Size aRetSize;
4126 if (aPrefMapMode == MAP_PIXEL)
4128 aRetSize = Application::GetDefaultDevice()->PixelToLogic(
4129 rGraf.GetPrefSize(), aWanted);
4131 else
4133 aRetSize = Application::GetDefaultDevice()->LogicToLogic(
4134 rGraf.GetPrefSize(), rGraf.GetPrefMapMode(), aWanted);
4136 return aRetSize;
4139 // sj: if the parameter pSet is null, then the resulting crop bitmap will be stored in rGraf,
4140 // otherwise rGraf is untouched and pSet is used to store the corresponding SdrGrafCropItem
4141 static void lcl_ApplyCropping( const DffPropSet& rPropSet, SfxItemSet* pSet, Graphic& rGraf )
4143 sal_Int32 nCropTop = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromTop, 0 );
4144 sal_Int32 nCropBottom = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromBottom, 0 );
4145 sal_Int32 nCropLeft = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromLeft, 0 );
4146 sal_Int32 nCropRight = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromRight, 0 );
4148 if( nCropTop || nCropBottom || nCropLeft || nCropRight )
4150 double fFactor;
4151 Size aCropSize;
4152 BitmapEx aCropBitmap;
4153 sal_uInt32 nTop( 0 ), nBottom( 0 ), nLeft( 0 ), nRight( 0 );
4155 if ( pSet ) // use crop attributes ?
4156 aCropSize = lcl_GetPrefSize( rGraf, MAP_100TH_MM );
4157 else
4159 aCropBitmap = rGraf.GetBitmapEx();
4160 aCropSize = aCropBitmap.GetSizePixel();
4162 if ( nCropTop )
4164 fFactor = (double)nCropTop / 65536.0;
4165 nTop = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
4167 if ( nCropBottom )
4169 fFactor = (double)nCropBottom / 65536.0;
4170 nBottom = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
4172 if ( nCropLeft )
4174 fFactor = (double)nCropLeft / 65536.0;
4175 nLeft = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
4177 if ( nCropRight )
4179 fFactor = (double)nCropRight / 65536.0;
4180 nRight = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
4182 if ( pSet ) // use crop attributes ?
4183 pSet->Put( SdrGrafCropItem( nLeft, nTop, nRight, nBottom ) );
4184 else
4186 Rectangle aCropRect( nLeft, nTop, aCropSize.Width() - nRight, aCropSize.Height() - nBottom );
4187 aCropBitmap.Crop( aCropRect );
4188 rGraf = aCropBitmap;
4193 SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, Rectangle& aBoundRect, const DffObjData& rObjData ) const
4195 SdrObject* pRet = NULL;
4196 String aFilename;
4197 String aLinkFileName, aLinkFilterName;
4198 Rectangle aVisArea;
4200 MSO_BlipFlags eFlags = (MSO_BlipFlags)GetPropertyValue( DFF_Prop_pibFlags, mso_blipflagDefault );
4201 sal_uInt32 nBlipId = GetPropertyValue( DFF_Prop_pib, 0 );
4202 sal_Bool bGrfRead = sal_False,
4204 // Grafik verlinkt
4205 bLinkGrf = 0 != ( eFlags & mso_blipflagLinkToFile );
4207 Graphic aGraf; // be sure this graphic is deleted before swapping out
4208 if( SeekToContent( DFF_Prop_pibName, rSt ) )
4209 MSDFFReadZString( rSt, aFilename, GetPropertyValue( DFF_Prop_pibName ), TRUE );
4211 // UND, ODER folgendes:
4212 if( !( eFlags & mso_blipflagDoNotSave ) ) // Grafik embedded
4214 bGrfRead = GetBLIP( nBlipId, aGraf, &aVisArea );
4215 if ( !bGrfRead )
4218 Still no luck, lets look at the end of this record for a FBSE pool,
4219 this fallback is a specific case for how word does it sometimes
4221 rObjData.rSpHd.SeekToEndOfRecord( rSt );
4222 DffRecordHeader aHd;
4223 rSt >> aHd;
4224 if( DFF_msofbtBSE == aHd.nRecType )
4226 const ULONG nSkipBLIPLen = 20;
4227 const ULONG nSkipShapePos = 4;
4228 const ULONG nSkipBLIP = 4;
4229 const ULONG nSkip =
4230 nSkipBLIPLen + 4 + nSkipShapePos + 4 + nSkipBLIP;
4232 if (nSkip <= aHd.nRecLen)
4234 rSt.SeekRel(nSkip);
4235 if (0 == rSt.GetError())
4236 bGrfRead = GetBLIPDirect( rSt, aGraf, &aVisArea );
4241 if ( bGrfRead )
4243 // the writer is doing it's own cropping, so this part affects only impress and calc
4244 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_CROP_BITMAPS )
4245 lcl_ApplyCropping( *this, ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ? &rSet : NULL, aGraf );
4247 if ( IsProperty( DFF_Prop_pictureTransparent ) )
4249 UINT32 nTransColor = GetPropertyValue( DFF_Prop_pictureTransparent, 0 );
4251 if ( aGraf.GetType() == GRAPHIC_BITMAP )
4253 BitmapEx aBitmapEx( aGraf.GetBitmapEx() );
4254 Bitmap aBitmap( aBitmapEx.GetBitmap() );
4255 Bitmap aMask( aBitmap.CreateMask( MSO_CLR_ToColor( nTransColor, DFF_Prop_pictureTransparent ), 9 ) );
4256 if ( aBitmapEx.IsTransparent() )
4257 aMask.CombineSimple( aBitmapEx.GetMask(), BMP_COMBINE_OR );
4258 aGraf = BitmapEx( aBitmap, aMask );
4262 sal_Int32 nContrast = GetPropertyValue( DFF_Prop_pictureContrast, 0x10000 );
4264 0x10000 is msoffice 50%
4265 < 0x10000 is in units of 1/50th of 0x10000 per 1%
4266 > 0x10000 is in units where
4267 a msoffice x% is stored as 50/(100-x) * 0x10000
4269 plus, a (ui) microsoft % ranges from 0 to 100, OOO
4270 from -100 to 100, so also normalize into that range
4272 if ( nContrast > 0x10000 )
4274 double fX = nContrast;
4275 fX /= 0x10000;
4276 fX /= 51; // 50 + 1 to round
4277 fX = 1/fX;
4278 nContrast = static_cast<sal_Int32>(fX);
4279 nContrast -= 100;
4280 nContrast = -nContrast;
4281 nContrast = (nContrast-50)*2;
4283 else if ( nContrast == 0x10000 )
4284 nContrast = 0;
4285 else
4287 nContrast *= 101; //100 + 1 to round
4288 nContrast /= 0x10000;
4289 nContrast -= 100;
4291 sal_Int16 nBrightness = (sal_Int16)( (sal_Int32)GetPropertyValue( DFF_Prop_pictureBrightness, 0 ) / 327 );
4292 sal_Int32 nGamma = GetPropertyValue( DFF_Prop_pictureGamma, 0x10000 );
4293 GraphicDrawMode eDrawMode = GRAPHICDRAWMODE_STANDARD;
4294 switch ( GetPropertyValue( DFF_Prop_pictureActive ) & 6 )
4296 case 4 : eDrawMode = GRAPHICDRAWMODE_GREYS; break;
4297 case 6 : eDrawMode = GRAPHICDRAWMODE_MONO; break;
4298 case 0 :
4300 //office considers the converted values of (in OOo) 70 to be the
4301 //"watermark" values, which can vary slightly due to rounding from the
4302 //above values
4303 if (( nContrast == -70 ) && ( nBrightness == 70 ))
4305 nContrast = 0;
4306 nBrightness = 0;
4307 eDrawMode = GRAPHICDRAWMODE_WATERMARK;
4310 break;
4313 if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) )
4315 if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 )
4317 if ( nBrightness )
4318 rSet.Put( SdrGrafLuminanceItem( nBrightness ) );
4319 if ( nContrast )
4320 rSet.Put( SdrGrafContrastItem( (sal_Int16)nContrast ) );
4321 if ( nGamma != 0x10000 )
4322 rSet.Put( SdrGrafGamma100Item( nGamma / 655 ) );
4323 if ( eDrawMode != GRAPHICDRAWMODE_STANDARD )
4324 rSet.Put( SdrGrafModeItem( eDrawMode ) );
4326 else
4328 if ( eDrawMode == GRAPHICDRAWMODE_WATERMARK )
4330 nContrast = 60;
4331 nBrightness = 70;
4332 eDrawMode = GRAPHICDRAWMODE_STANDARD;
4334 switch ( aGraf.GetType() )
4336 case GRAPHIC_BITMAP :
4338 BitmapEx aBitmapEx( aGraf.GetBitmapEx() );
4339 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
4340 aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, FALSE );
4341 if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
4342 aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
4343 else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
4344 aBitmapEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
4345 aGraf = aBitmapEx;
4348 break;
4350 case GRAPHIC_GDIMETAFILE :
4352 GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() );
4353 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
4354 aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, FALSE );
4355 if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
4356 aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS );
4357 else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
4358 aGdiMetaFile.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
4359 aGraf = aGdiMetaFile;
4361 break;
4362 default: break;
4368 // sollte es ein OLE-Object sein?
4369 if( bGrfRead && !bLinkGrf && IsProperty( DFF_Prop_pictureId ) )
4371 // TODO/LATER: in future probably the correct aspect should be provided here
4372 sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
4373 // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method
4374 pRet = ImportOLE( GetPropertyValue( DFF_Prop_pictureId ), aGraf, aBoundRect, aVisArea, rObjData.nCalledByGroup, nAspect );
4375 // <--
4377 if( !pRet )
4379 pRet = new SdrGrafObj;
4380 if( bGrfRead )
4381 ((SdrGrafObj*)pRet)->SetGraphic( aGraf );
4383 if( bLinkGrf && !bGrfRead ) // sj: #i55484# if the graphic was embedded ( bGrfRead == true ) then
4384 { // we do not need to set a link. TODO: not to lose the information where the graphic is linked from
4385 UniString aName( ::URIHelper::SmartRel2Abs( INetURLObject(maBaseURL), aFilename, URIHelper::GetMaybeFileHdl(), true, false,
4386 INetURLObject::WAS_ENCODED,
4387 INetURLObject::DECODE_UNAMBIGUOUS ) );
4389 String aFilterName;
4390 INetURLObject aURLObj( aName );
4392 if( aURLObj.GetProtocol() == INET_PROT_NOT_VALID )
4394 String aValidURL;
4396 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aValidURL ) )
4397 aURLObj = INetURLObject( aValidURL );
4400 if( aURLObj.GetProtocol() != INET_PROT_NOT_VALID )
4402 GraphicFilter* pGrfFilter = GetGrfFilter();
4403 aFilterName = pGrfFilter->GetImportFormatName(
4404 pGrfFilter->GetImportFormatNumberForShortName( aURLObj.getExtension() ) );
4407 aLinkFileName = aName;
4408 aLinkFilterName = aFilterName;
4412 // set the size from BLIP if there is one
4413 if ( pRet && bGrfRead && !aVisArea.IsEmpty() )
4414 pRet->SetBLIPSizeRectangle( aVisArea );
4416 if ( !pRet->GetName().Len() ) // SJ 22.02.00 : PPT OLE IMPORT:
4417 { // name is already set in ImportOLE !!
4418 // JP 01.12.99: SetName before SetModel - because in the other order the Bug 70098 is active
4419 if ( ( eFlags & mso_blipflagType ) != mso_blipflagComment )
4421 INetURLObject aURL;
4422 aURL.SetSmartURL( aFilename );
4423 pRet->SetName( aURL.getBase() );
4425 else
4426 pRet->SetName( aFilename );
4429 pRet->SetModel( pSdrModel ); // fuer GraphicLink erforderlich
4430 pRet->SetLogicRect( aBoundRect );
4432 if ( pRet->ISA( SdrGrafObj ) )
4434 if( aLinkFileName.Len() )
4435 ((SdrGrafObj*)pRet)->SetGraphicLink( aLinkFileName, aLinkFilterName );
4437 if ( bLinkGrf && !bGrfRead )
4439 ((SdrGrafObj*)pRet)->ForceSwapIn();
4440 Graphic aGraf(((SdrGrafObj*)pRet)->GetGraphic());
4441 lcl_ApplyCropping( *this, &rSet, aGraf );
4443 ((SdrGrafObj*)pRet)->ForceSwapOut();
4446 return pRet;
4449 // PptSlidePersistEntry& rPersistEntry, SdPage* pPage
4450 SdrObject* SvxMSDffManager::ImportObj( SvStream& rSt, void* pClientData,
4451 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup, sal_Int32* pShapeId )
4453 SdrObject* pRet = NULL;
4454 DffRecordHeader aObjHd;
4455 rSt >> aObjHd;
4456 if ( aObjHd.nRecType == DFF_msofbtSpgrContainer )
4458 pRet = ImportGroup( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4460 else if ( aObjHd.nRecType == DFF_msofbtSpContainer )
4462 pRet = ImportShape( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4464 aObjHd.SeekToBegOfRecord( rSt ); // FilePos restaurieren
4465 return pRet;
4468 SdrObject* SvxMSDffManager::ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4469 Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4470 int nCalledByGroup, sal_Int32* pShapeId )
4472 SdrObject* pRet = NULL;
4474 if( pShapeId )
4475 *pShapeId = 0;
4477 rHd.SeekToContent( rSt );
4478 DffRecordHeader aRecHd; // the first atom has to be the SpContainer for the GroupObject
4479 rSt >> aRecHd;
4480 if ( aRecHd.nRecType == DFF_msofbtSpContainer )
4482 INT32 nGroupRotateAngle = 0;
4483 INT32 nSpFlags = 0;
4484 mnFix16Angle = 0;
4485 aRecHd.SeekToBegOfRecord( rSt );
4486 pRet = ImportObj( rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup + 1, pShapeId );
4487 if ( pRet )
4489 nSpFlags = nGroupShapeFlags;
4490 nGroupRotateAngle = mnFix16Angle;
4492 Rectangle aClientRect( rClientRect );
4494 Rectangle aGlobalChildRect;
4495 if ( !nCalledByGroup || rGlobalChildRect.IsEmpty() )
4496 aGlobalChildRect = GetGlobalChildAnchor( rHd, rSt, aClientRect );
4497 else
4498 aGlobalChildRect = rGlobalChildRect;
4500 if ( ( nGroupRotateAngle > 4500 && nGroupRotateAngle <= 13500 )
4501 || ( nGroupRotateAngle > 22500 && nGroupRotateAngle <= 31500 ) )
4503 sal_Int32 nHalfWidth = ( aClientRect.GetWidth() + 1 ) >> 1;
4504 sal_Int32 nHalfHeight = ( aClientRect.GetHeight() + 1 ) >> 1;
4505 Point aTopLeft( aClientRect.Left() + nHalfWidth - nHalfHeight,
4506 aClientRect.Top() + nHalfHeight - nHalfWidth );
4507 Size aNewSize( aClientRect.GetHeight(), aClientRect.GetWidth() );
4508 Rectangle aNewRect( aTopLeft, aNewSize );
4509 aClientRect = aNewRect;
4512 // now importing the inner objects of the group
4513 aRecHd.SeekToEndOfRecord( rSt );
4514 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4516 DffRecordHeader aRecHd2;
4517 rSt >> aRecHd2;
4518 if ( aRecHd2.nRecType == DFF_msofbtSpgrContainer )
4520 Rectangle aGroupClientAnchor, aGroupChildAnchor;
4521 GetGroupAnchors( aRecHd2, rSt, aGroupClientAnchor, aGroupChildAnchor, aClientRect, aGlobalChildRect );
4522 aRecHd2.SeekToBegOfRecord( rSt );
4523 sal_Int32 nShapeId;
4524 SdrObject* pTmp = ImportGroup( aRecHd2, rSt, pClientData, aGroupClientAnchor, aGroupChildAnchor, nCalledByGroup + 1, &nShapeId );
4525 if ( pTmp )
4527 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4528 if( nShapeId )
4529 insertShapeId( nShapeId, pTmp );
4532 else if ( aRecHd2.nRecType == DFF_msofbtSpContainer )
4534 aRecHd2.SeekToBegOfRecord( rSt );
4535 sal_Int32 nShapeId;
4536 SdrObject* pTmp = ImportShape( aRecHd2, rSt, pClientData, aClientRect, aGlobalChildRect, nCalledByGroup + 1, &nShapeId );
4537 if ( pTmp )
4539 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4540 if( nShapeId )
4541 insertShapeId( nShapeId, pTmp );
4544 aRecHd2.SeekToEndOfRecord( rSt );
4547 // pRet->NbcSetSnapRect( aGroupBound );
4548 if ( nGroupRotateAngle )
4550 double a = nGroupRotateAngle * nPi180;
4551 pRet->NbcRotate( aClientRect.Center(), nGroupRotateAngle, sin( a ), cos( a ) );
4553 if ( nSpFlags & SP_FFLIPV ) // Vertikal gespiegelt?
4554 { // BoundRect in aBoundRect
4555 Point aLeft( aClientRect.Left(), ( aClientRect.Top() + aClientRect.Bottom() ) >> 1 );
4556 Point aRight( aLeft.X() + 1000, aLeft.Y() );
4557 pRet->NbcMirror( aLeft, aRight );
4559 if ( nSpFlags & SP_FFLIPH ) // Horizontal gespiegelt?
4560 { // BoundRect in aBoundRect
4561 Point aTop( ( aClientRect.Left() + aClientRect.Right() ) >> 1, aClientRect.Top() );
4562 Point aBottom( aTop.X(), aTop.Y() + 1000 );
4563 pRet->NbcMirror( aTop, aBottom );
4567 return pRet;
4570 SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4571 Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4572 int nCalledByGroup, sal_Int32* pShapeId )
4574 SdrObject* pRet = NULL;
4576 if( pShapeId )
4577 *pShapeId = 0;
4579 rHd.SeekToBegOfRecord( rSt );
4580 Rectangle aBoundRect( rClientRect );
4581 DffObjData aObjData( rHd, aBoundRect, nCalledByGroup );
4582 maShapeRecords.Consume( rSt, FALSE );
4583 aObjData.bShapeType = maShapeRecords.SeekToContent( rSt, DFF_msofbtSp, SEEK_FROM_BEGINNING );
4584 if ( aObjData.bShapeType )
4586 rSt >> aObjData.nShapeId
4587 >> aObjData.nSpFlags;
4588 aObjData.eShapeType = (MSO_SPT)maShapeRecords.Current()->nRecInstance;
4590 else
4592 aObjData.nShapeId = 0;
4593 aObjData.nSpFlags = 0;
4594 aObjData.eShapeType = mso_sptNil;
4597 if( pShapeId )
4598 *pShapeId = aObjData.nShapeId;
4600 if ( mbTracing )
4601 mpTracer->AddAttribute( aObjData.nSpFlags & SP_FGROUP
4602 ? rtl::OUString::createFromAscii( "GroupShape" )
4603 : rtl::OUString::createFromAscii( "Shape" ),
4604 rtl::OUString::valueOf( (sal_Int32)aObjData.nShapeId ) );
4605 aObjData.bOpt = maShapeRecords.SeekToContent( rSt, DFF_msofbtOPT, SEEK_FROM_CURRENT_AND_RESTART );
4606 if ( aObjData.bOpt )
4608 maShapeRecords.Current()->SeekToBegOfRecord( rSt );
4609 #ifdef DBG_AUTOSHAPE
4610 ReadPropSet( rSt, pClientData, (UINT32)aObjData.eShapeType );
4611 #else
4612 ReadPropSet( rSt, pClientData );
4613 #endif
4615 else
4617 InitializePropSet(); // get the default PropSet
4618 ( (DffPropertyReader*) this )->mnFix16Angle = 0;
4621 aObjData.bChildAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtChildAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4622 if ( aObjData.bChildAnchor )
4624 INT32 l, o, r, u;
4625 rSt >> l >> o >> r >> u;
4626 Scale( l );
4627 Scale( o );
4628 Scale( r );
4629 Scale( u );
4630 aObjData.aChildAnchor = Rectangle( l, o, r, u );
4631 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
4633 double fl = l;
4634 double fo = o;
4635 double fWidth = r - l;
4636 double fHeight= u - o;
4637 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
4638 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
4639 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
4640 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top();
4641 fWidth *= fXScale;
4642 fHeight *= fYScale;
4643 aObjData.aChildAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
4647 aObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtClientAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4648 if ( aObjData.bClientAnchor )
4649 ProcessClientAnchor2( rSt, *maShapeRecords.Current(), pClientData, aObjData );
4651 if ( aObjData.bChildAnchor )
4652 aBoundRect = aObjData.aChildAnchor;
4654 if ( aObjData.nSpFlags & SP_FBACKGROUND )
4655 aBoundRect = Rectangle( Point(), Size( 1, 1 ) );
4657 Rectangle aTextRect;
4658 if ( !aBoundRect.IsEmpty() )
4659 { // Rotation auf BoundingBox anwenden, BEVOR ien Objekt generiert wurde
4660 if( mnFix16Angle )
4662 long nAngle = mnFix16Angle;
4663 if ( ( nAngle > 4500 && nAngle <= 13500 ) || ( nAngle > 22500 && nAngle <= 31500 ) )
4665 INT32 nHalfWidth = ( aBoundRect.GetWidth() + 1 ) >> 1;
4666 INT32 nHalfHeight = ( aBoundRect.GetHeight() + 1 ) >> 1;
4667 Point aTopLeft( aBoundRect.Left() + nHalfWidth - nHalfHeight,
4668 aBoundRect.Top() + nHalfHeight - nHalfWidth );
4669 Size aNewSize( aBoundRect.GetHeight(), aBoundRect.GetWidth() );
4670 Rectangle aNewRect( aTopLeft, aNewSize );
4671 aBoundRect = aNewRect;
4674 aTextRect = aBoundRect;
4675 FASTBOOL bGraphic = IsProperty( DFF_Prop_pib ) ||
4676 IsProperty( DFF_Prop_pibName ) ||
4677 IsProperty( DFF_Prop_pibFlags );
4679 if ( aObjData.nSpFlags & SP_FGROUP )
4681 pRet = new SdrObjGroup;
4682 /* After CWS aw033 has been integrated, an empty group object
4683 cannot store its resulting bounding rectangle anymore. We have
4684 to return this rectangle via rClientRect now, but only, if
4685 caller has not passed an own bounding ractangle. */
4686 if ( rClientRect.IsEmpty() )
4687 rClientRect = aBoundRect;
4688 nGroupShapeFlags = aObjData.nSpFlags; // #73013#
4690 else if ( ( aObjData.eShapeType != mso_sptNil ) || IsProperty( DFF_Prop_pVertices ) || bGraphic )
4692 SfxItemSet aSet( pSdrModel->GetItemPool() );
4694 sal_Bool bIsConnector = ( ( aObjData.eShapeType >= mso_sptStraightConnector1 ) && ( aObjData.eShapeType <= mso_sptCurvedConnector5 ) );
4695 sal_Bool bIsCustomShape = sal_False;
4696 sal_Int32 nObjectRotation = mnFix16Angle;
4697 sal_uInt32 nSpFlags = aObjData.nSpFlags;
4699 if ( bGraphic )
4700 pRet = ImportGraphic( rSt, aSet, aBoundRect, aObjData ); // SJ: #68396# is no longer true (fixed in ppt2000)
4701 else
4703 // Check if we are using our new as shape type. This is done by
4704 // the PowerPoint import now. As result nearly each escher object
4705 // will be imported as customshape, this is also done in the case for
4706 // simple text objects.
4707 // The new shape is having the advantage to fully support wordwrapping
4708 // and autogrow size attributes.
4710 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_IAS )
4712 if ( GetCustomShapeContent( aObjData.eShapeType ) || IsProperty( DFF_Prop_pVertices ) )
4715 ApplyAttributes( rSt, aSet, aObjData.eShapeType, aObjData.nSpFlags );
4717 // the com.sun.star.drawing.EnhancedCustomShapeEngine is default, so we do not need to set a hard attribute
4718 // aSet.Put( SdrCustomShapeEngineItem( String::CreateFromAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) );
4719 pRet = new SdrObjCustomShape();
4720 pRet->SetModel( pSdrModel );
4722 sal_Bool bIsFontwork = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) != 0;
4724 // in case of a FontWork, the text is set by the escher import
4725 if ( bIsFontwork )
4727 String aObjectText;
4728 String aFontName;
4729 MSO_GeoTextAlign eGeoTextAlign;
4731 if ( SeekToContent( DFF_Prop_gtextFont, rSt ) )
4733 SvxFontItem aLatin(EE_CHAR_FONTINFO), aAsian(EE_CHAR_FONTINFO_CJK), aComplex(EE_CHAR_FONTINFO_CTL);
4734 GetDefaultFonts( aLatin, aAsian, aComplex );
4736 MSDFFReadZString( rSt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), TRUE );
4737 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4738 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
4739 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4740 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CJK ) );
4741 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4742 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CTL ) );
4745 // SJ: applying fontattributes for Fontwork :
4746 if ( IsHardAttribute( DFF_Prop_gtextFItalic ) )
4747 aSet.Put( SvxPostureItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0010 ) != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
4749 if ( IsHardAttribute( DFF_Prop_gtextFBold ) )
4750 aSet.Put( SvxWeightItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0020 ) != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
4752 // SJ TODO: Vertical Writing is not correct, instead this should be
4753 // replaced through "CharacterRotation" by 90°, therefore a new Item has to be
4754 // supported by svx core, api and xml file format
4755 ((SdrObjCustomShape*)pRet)->SetVerticalWriting( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) != 0 );
4757 if ( SeekToContent( DFF_Prop_gtextUNICODE, rSt ) )
4759 MSDFFReadZString( rSt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), TRUE );
4760 ReadObjText( aObjectText, pRet );
4763 eGeoTextAlign = ( (MSO_GeoTextAlign)GetPropertyValue( DFF_Prop_gtextAlign, mso_alignTextCenter ) );
4765 SdrTextHorzAdjust eHorzAdjust;
4766 switch( eGeoTextAlign )
4768 case mso_alignTextLetterJust :
4769 case mso_alignTextWordJust :
4770 case mso_alignTextStretch : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break;
4771 default:
4772 case mso_alignTextInvalid :
4773 case mso_alignTextCenter : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break;
4774 case mso_alignTextLeft : eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break;
4775 case mso_alignTextRight : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break;
4777 aSet.Put( SdrTextHorzAdjustItem( eHorzAdjust ) );
4779 SdrFitToSizeType eFTS = SDRTEXTFIT_NONE;
4780 if ( eGeoTextAlign == mso_alignTextStretch )
4781 eFTS = SDRTEXTFIT_ALLLINES;
4782 aSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
4784 if ( IsProperty( DFF_Prop_gtextSpacing ) )
4786 sal_Int32 nTextWidth = GetPropertyValue( DFF_Prop_gtextSpacing, 100 < 16 ) / 655;
4787 if ( nTextWidth != 100 )
4788 aSet.Put( SvxCharScaleWidthItem( (sal_uInt16)nTextWidth, EE_CHAR_FONTWIDTH ) );
4790 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x1000 ) // SJ: Font Kerning On ?
4791 aSet.Put( SvxKerningItem( 1, EE_CHAR_KERNING ) );
4793 pRet->SetMergedItemSet( aSet );
4795 // sj: taking care of rtl, ltr. In case of fontwork mso. seems not to be able to set
4796 // proper text directions, instead the text default is depending to the string.
4797 // so we have to calculate the a text direction from string:
4798 if ( bIsFontwork )
4800 OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pRet)->GetOutlinerParaObject();
4801 if ( pParaObj )
4803 SdrOutliner& rOutliner = ((SdrObjCustomShape*)pRet)->ImpGetDrawOutliner();
4804 BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
4805 SdrModel* pModel = pRet->GetModel();
4806 if ( pModel )
4807 rOutliner.SetStyleSheetPool( (SfxStyleSheetPool*)pModel->GetStyleSheetPool() );
4808 rOutliner.SetUpdateMode( FALSE );
4809 rOutliner.SetText( *pParaObj );
4810 VirtualDevice aVirDev( 1 );
4811 aVirDev.SetMapMode( MAP_100TH_MM );
4812 sal_uInt32 i, nParagraphs = rOutliner.GetParagraphCount();
4813 if ( nParagraphs )
4815 sal_Bool bCreateNewParaObject = sal_False;
4816 for ( i = 0; i < nParagraphs; i++ )
4818 BOOL bIsRTL = aVirDev.GetTextIsRTL( rOutliner.GetText( rOutliner.GetParagraph( i ) ), 0, STRING_LEN );
4819 if ( bIsRTL )
4821 SfxItemSet aSet2( rOutliner.GetParaAttribs( (USHORT)i ) );
4822 aSet2.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
4823 rOutliner.SetParaAttribs( (USHORT)i, aSet2 );
4824 bCreateNewParaObject = sal_True;
4827 if ( bCreateNewParaObject )
4829 OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
4830 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
4831 ((SdrObjCustomShape*)pRet)->NbcSetOutlinerParaObject( pNewText );
4834 rOutliner.Clear();
4835 rOutliner.SetUpdateMode( bOldUpdateMode );
4839 // mso_sptArc special treating:
4840 // sj: since we actually can't render the arc because of its weird SnapRect settings,
4841 // we will create a new CustomShape, that can be saved/loaded without problems.
4842 // We will change the shape type, so this code applys only if importing arcs from msoffice.
4843 if ( aObjData.eShapeType == mso_sptArc )
4845 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
4846 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
4847 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
4848 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
4849 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
4850 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
4851 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
4852 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
4853 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
4854 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
4856 // before clearing the GeometryItem we have to store the current Coordinates
4857 const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
4858 Rectangle aPolyBoundRect;
4859 if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) )
4861 sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength();
4862 XPolygon aXP( (sal_uInt16)nNumElemVert );
4863 // const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
4864 for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ )
4866 Point aP;
4867 sal_Int32 nX = 0, nY = 0;
4868 seqCoordinates[ nPtNum ].First.Value >>= nX;
4869 seqCoordinates[ nPtNum ].Second.Value >>= nY;
4870 aP.X() = nX;
4871 aP.Y() = nY;
4872 aXP[ (sal_uInt16)nPtNum ] = aP;
4874 aPolyBoundRect = Rectangle( aXP.GetBoundRect() );
4876 else
4877 aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 ); // defaulting
4879 // clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry
4880 aGeometryItem.ClearPropertyValue( sHandles );
4881 aGeometryItem.ClearPropertyValue( sEquations );
4882 aGeometryItem.ClearPropertyValue( sViewBox );
4883 aGeometryItem.ClearPropertyValue( sPath );
4885 sal_Int32 nEndAngle = 9000;
4886 sal_Int32 nStartAngle = 0;
4887 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
4888 if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 )
4890 double fNumber;
4891 if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
4893 seqAdjustmentValues[ 0 ].Value >>= fNumber;
4894 nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4896 else
4898 fNumber = 270.0;
4899 seqAdjustmentValues[ 0 ].Value <<= fNumber;
4900 seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // so this value will properly be stored
4903 if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
4905 seqAdjustmentValues[ 1 ].Value >>= fNumber;
4906 nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
4908 else
4910 fNumber = 0.0;
4911 seqAdjustmentValues[ 0 ].Value <<= fNumber;
4912 seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
4915 PropertyValue aPropVal;
4916 aPropVal.Name = sAdjustmentValues;
4917 aPropVal.Value <<= seqAdjustmentValues;
4918 aGeometryItem.SetPropertyValue( aPropVal ); // storing the angle attribute
4920 if ( nStartAngle != nEndAngle )
4922 XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2,
4923 (USHORT)nStartAngle / 10, (USHORT)nEndAngle / 10, TRUE );
4924 Rectangle aPolyPieRect( aXPoly.GetBoundRect() );
4926 double fYScale, fXScale;
4927 double fYOfs, fXOfs;
4929 Point aP( aBoundRect.Center() );
4930 Size aS( aBoundRect.GetSize() );
4931 aP.X() -= aS.Width() / 2;
4932 aP.Y() -= aS.Height() / 2;
4933 Rectangle aLogicRect( aP, aS );
4935 fYOfs = fXOfs = 0.0;
4937 if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() )
4939 fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth();
4940 if ( nSpFlags & SP_FFLIPH )
4941 fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale;
4942 else
4943 fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale;
4945 if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() )
4947 fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight();
4948 if ( nSpFlags & SP_FFLIPV )
4949 fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale;
4950 else
4951 fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale;
4954 fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth();
4955 fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight();
4957 Rectangle aOldBoundRect( aBoundRect );
4958 aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ),
4959 Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) );
4961 // creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system
4962 double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth();
4963 double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight();
4964 sal_Int32 nLeft = (sal_Int32)(( aPolyPieRect.Left() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
4965 sal_Int32 nTop = (sal_Int32)(( aPolyPieRect.Top() - aPolyBoundRect.Top() ) * fTextFrameScaleY );
4966 sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
4967 sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() ) * fTextFrameScaleY );
4968 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 );
4969 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First, nLeft );
4970 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second, nTop );
4971 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight );
4972 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom );
4973 PropertyValue aProp;
4974 aProp.Name = sTextFrames;
4975 aProp.Value <<= aTextFrame;
4976 aGeometryItem.SetPropertyValue( sPath, aProp );
4978 // sj: taking care of the different rotation points, since the new arc is having a bigger snaprect
4979 if ( mnFix16Angle )
4981 sal_Int32 nAngle = mnFix16Angle;
4982 if ( nSpFlags & SP_FFLIPH )
4983 nAngle = 36000 - nAngle;
4984 if ( nSpFlags & SP_FFLIPV )
4985 nAngle = -nAngle;
4986 double a = nAngle * F_PI18000;
4987 double ss = sin( a );
4988 double cc = cos( a );
4989 Point aP1( aOldBoundRect.TopLeft() );
4990 Point aC1( aBoundRect.Center() );
4991 Point aP2( aOldBoundRect.TopLeft() );
4992 Point aC2( aOldBoundRect.Center() );
4993 RotatePoint( aP1, aC1, ss, cc );
4994 RotatePoint( aP2, aC2, ss, cc );
4995 aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() );
4998 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem );
4999 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
5001 // now setting a new name, so the above correction is only done once when importing from ms
5002 SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
5003 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
5004 const rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) );
5005 PropertyValue aPropVal;
5006 aPropVal.Name = sType;
5007 aPropVal.Value <<= sName;
5008 aGeoName.SetPropertyValue( aPropVal );
5009 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName );
5011 else
5012 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
5014 pRet->SetSnapRect( aBoundRect );
5015 EnhancedCustomShape2d aCustomShape2d( pRet );
5016 aTextRect = aCustomShape2d.GetTextRect();
5018 bIsCustomShape = TRUE;
5020 if( bIsConnector )
5022 if( nObjectRotation )
5024 double a = nObjectRotation * nPi180;
5025 pRet->NbcRotate( aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
5027 // Horizontal gespiegelt?
5028 if ( nSpFlags & SP_FFLIPH )
5030 Rectangle aBndRect( pRet->GetSnapRect() );
5031 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
5032 Point aBottom( aTop.X(), aTop.Y() + 1000 );
5033 pRet->NbcMirror( aTop, aBottom );
5035 // Vertikal gespiegelt?
5036 if ( nSpFlags & SP_FFLIPV )
5038 Rectangle aBndRect( pRet->GetSnapRect() );
5039 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
5040 Point aRight( aLeft.X() + 1000, aLeft.Y() );
5041 pRet->NbcMirror( aLeft, aRight );
5043 basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) );
5044 SdrObject::Free( pRet );
5046 pRet = new SdrEdgeObj();
5047 pRet->SetLogicRect(aBoundRect);
5049 // Konnektoren
5050 MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight );
5052 ((SdrEdgeObj*)pRet)->ConnectToNode(TRUE, NULL);
5053 ((SdrEdgeObj*)pRet)->ConnectToNode(FALSE, NULL);
5055 Point aPoint1( aBoundRect.TopLeft() );
5056 Point aPoint2( aBoundRect.BottomRight() );
5058 // Rotationen beachten
5059 if ( nObjectRotation )
5061 double a = nObjectRotation * nPi180;
5062 Point aCenter( aBoundRect.Center() );
5063 double ss = sin(a);
5064 double cc = cos(a);
5066 RotatePoint(aPoint1, aCenter, ss, cc);
5067 RotatePoint(aPoint2, aCenter, ss, cc);
5070 // Linie innerhalb des Bereiches zurechtdrehen/spiegeln
5071 if ( nSpFlags & SP_FFLIPH )
5073 INT32 n = aPoint1.X();
5074 aPoint1.X() = aPoint2.X();
5075 aPoint2.X() = n;
5077 if ( nSpFlags & SP_FFLIPV )
5079 INT32 n = aPoint1.Y();
5080 aPoint1.Y() = aPoint2.Y();
5081 aPoint2.Y() = n;
5083 nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH );
5085 pRet->NbcSetPoint(aPoint1, 0L); // Startpunkt
5086 pRet->NbcSetPoint(aPoint2, 1L); // Endpunkt
5088 sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist;
5089 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0;
5090 switch( eConnectorStyle )
5092 case mso_cxstyleBent:
5094 aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) );
5095 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630;
5097 break;
5098 case mso_cxstyleCurved:
5099 aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) );
5100 break;
5101 default: // mso_cxstyleStraight || mso_cxstyleNone
5102 aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) );
5103 break;
5105 aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) );
5106 aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) );
5107 aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) );
5108 aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) );
5110 ((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly );
5114 else
5116 SvxMSDffCustomShape aCustomShape( *this, rSt, aObjData, aBoundRect, nObjectRotation, mpTracer );
5117 if ( !aCustomShape.IsEmpty() )
5119 ApplyAttributes( rSt, aSet, aObjData.eShapeType, aObjData.nSpFlags );
5120 pRet = aCustomShape.GetObject( pSdrModel, aSet, TRUE );
5121 aTextRect = aCustomShape.GetTextRect();
5122 bIsCustomShape = TRUE;
5125 if ( !bIsCustomShape )
5127 if ( aObjData.eShapeType == mso_sptTextBox )
5129 if ( ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 )
5130 || ( GetPropertyValue( DFF_Prop_fNoFillHitTest ) & 0x10 ) )
5132 pRet = new SdrRectObj( aBoundRect ); // SJ: changed the type from OBJ_TEXT to OBJ_RECT (#88277#)
5135 else if ( ( ( aObjData.eShapeType >= mso_sptCallout1 ) && ( aObjData.eShapeType <= mso_sptAccentBorderCallout3 ) )
5136 || ( aObjData.eShapeType == mso_sptCallout90 )
5137 || ( aObjData.eShapeType == mso_sptAccentCallout90 )
5138 || ( aObjData.eShapeType == mso_sptBorderCallout90 )
5139 || ( aObjData.eShapeType == mso_sptAccentBorderCallout90 ) )
5141 pRet = new SdrCaptionObj( aBoundRect );
5142 INT32 nAdjust0 = GetPropertyValue( DFF_Prop_adjustValue, 0 );
5143 INT32 nAdjust1 = GetPropertyValue( DFF_Prop_adjust2Value, 0 );
5144 if( nAdjust0 | nAdjust1 )
5145 { // AdjustValues anwenden, nur welche ?!?
5146 nAdjust0 = ( nAdjust0 * 100 ) / 850;
5147 nAdjust1 = ( nAdjust1 * 100 ) / 1275;
5148 Point aTailPos( nAdjust0 + aBoundRect.Left(), nAdjust1 + aBoundRect.Top() );
5149 ((SdrCaptionObj*)pRet)->NbcSetTailPos( aTailPos );
5152 else if( ( aObjData.eShapeType >= mso_sptTextPlainText ) && ( aObjData.eShapeType <= mso_sptTextCanDown ) ) // FontWork
5154 aObjData.bIsAutoText = TRUE;
5155 if ( mbTracing )
5156 mpTracer->Trace( rtl::OUString::createFromAscii( "escher1000" ), rtl::OUString::valueOf( (sal_Int32)aObjData.eShapeType ) );
5157 pRet = ImportFontWork( rSt, aSet, aBoundRect );
5159 else if ( aObjData.eShapeType == mso_sptLine )
5161 basegfx::B2DPolygon aPoly;
5162 aPoly.append(basegfx::B2DPoint(aBoundRect.Left(), aBoundRect.Top()));
5163 aPoly.append(basegfx::B2DPoint(aBoundRect.Right(), aBoundRect.Bottom()));
5164 pRet = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly));
5166 else if ( ( (int)aObjData.eShapeType > (int)mso_sptRectangle ) && ( (int)aObjData.eShapeType < (int)mso_sptHostControl ) )
5168 pRet = GetAutoForm( aObjData.eShapeType );
5169 if ( pRet )
5171 mpTracer->Trace( rtl::OUString::createFromAscii( "escher1001" ), rtl::OUString::valueOf( (sal_Int32)aObjData.eShapeType ) );
5172 pRet->NbcSetSnapRect( aBoundRect ); // Groesse setzen
5177 if ( pRet )
5179 if ( bIsConnector || !bIsCustomShape )
5181 ApplyAttributes( rSt, aSet, aObjData.eShapeType, aObjData.nSpFlags );
5182 if ( !GetPropertyValue( DFF_Prop_gtextSize, 0 ) )
5183 aSet.Put( SvxFontHeightItem( ScalePt( 24 << 16 ), 100, EE_CHAR_FONTHEIGHT ) );
5184 if ( aObjData.eShapeType == mso_sptTextBox )
5185 aSet.Put( SdrTextMinFrameHeightItem( aBoundRect.GetHeight() ) );
5186 pRet->SetModel( pSdrModel );
5187 pRet->SetMergedItemSet(aSet);
5188 // Rotieren
5189 if ( pRet->ISA( SdrCaptionObj ) ) // sj: #96758# SetModel is changing
5190 pRet->SetSnapRect( aBoundRect ); // the original snaprect
5192 // FillStyle != XFILL_NONE und nicht geschlossenes Polygon-Objekt?
5193 if( pRet->ISA( SdrPathObj ) )
5195 XFillStyle eFillStyle = ITEMVALUE( aSet, XATTR_FILLSTYLE, XFillStyleItem );
5196 if( eFillStyle != XFILL_NONE )
5198 // Das Polygon des Objektes muss geschlossen werden
5199 if(!((SdrPathObj*)pRet)->IsClosed())
5200 ((SdrPathObj*)pRet)->ToggleClosed(); //0);
5203 // Handelt es sich um 3D?
5204 if( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 8 )
5206 // #81981# not all objects are effected by 3d effects
5207 if ( !bGraphic )
5209 SdrObject* p3d = SvxMSDffCustomShape3D::Create3DObject( pRet, *this, aSet, aBoundRect, nSpFlags );
5210 if ( p3d )
5212 nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH );
5213 nObjectRotation = 0;
5214 SdrObject::Free( pRet );
5215 pRet = p3d;
5220 if ( pRet )
5222 if( nObjectRotation /* && !bIsConnector */ )
5224 double a = nObjectRotation * nPi180;
5225 pRet->NbcRotate( aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
5227 // Horizontal gespiegelt?
5228 if ( nSpFlags & SP_FFLIPH )
5230 Rectangle aBndRect( pRet->GetSnapRect() );
5231 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
5232 Point aBottom( aTop.X(), aTop.Y() + 1000 );
5233 pRet->NbcMirror( aTop, aBottom );
5235 // Vertikal gespiegelt?
5236 if ( nSpFlags & SP_FFLIPV )
5238 Rectangle aBndRect( pRet->GetSnapRect() );
5239 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
5240 Point aRight( aLeft.X() + 1000, aLeft.Y() );
5241 pRet->NbcMirror( aLeft, aRight );
5247 // #i51348# #118052# name of the shape
5248 if( pRet )
5250 ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt );
5251 if( aObjName.getLength() > 0 )
5252 pRet->SetName( aObjName );
5255 pRet =
5256 ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet);
5258 if ( mbTracing )
5259 mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP
5260 ? rtl::OUString::createFromAscii( "GroupShape" )
5261 : rtl::OUString::createFromAscii( "Shape" ) );
5262 return pRet;
5265 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect )
5267 Rectangle aChildAnchor;
5268 rHd.SeekToContent( rSt );
5269 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
5271 DffRecordHeader aShapeHd;
5272 rSt >> aShapeHd;
5273 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
5274 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
5276 DffRecordHeader aShapeHd2( aShapeHd );
5277 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
5278 rSt >> aShapeHd2;
5279 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
5281 DffRecordHeader aShapeAtom;
5282 rSt >> aShapeAtom;
5284 if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor )
5286 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT )
5288 sal_Int32 l, t, r, b;
5289 if ( aShapeAtom.nRecLen == 16 )
5291 rSt >> l >> t >> r >> b;
5293 else
5295 INT16 ls, ts, rs, bs;
5296 rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ...
5297 l = ls, t = ts, r = rs, b = bs;
5299 Scale( l );
5300 Scale( t );
5301 Scale( r );
5302 Scale( b );
5303 aClientRect = Rectangle( l, t, r, b );
5305 break;
5307 else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
5309 sal_Int32 l, o, r, u;
5310 rSt >> l >> o >> r >> u;
5311 Scale( l );
5312 Scale( o );
5313 Scale( r );
5314 Scale( u );
5315 Rectangle aChild( l, o, r, u );
5316 aChildAnchor.Union( aChild );
5317 break;
5319 aShapeAtom.SeekToEndOfRecord( rSt );
5322 aShapeHd.SeekToEndOfRecord( rSt );
5324 return aChildAnchor;
5327 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt,
5328 Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor,
5329 const Rectangle& rClientRect, const Rectangle& rGlobalChildRect )
5331 sal_Bool bFirst = sal_True;
5332 rHd.SeekToContent( rSt );
5333 DffRecordHeader aShapeHd;
5334 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
5336 rSt >> aShapeHd;
5337 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
5338 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
5340 DffRecordHeader aShapeHd2( aShapeHd );
5341 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
5342 rSt >> aShapeHd2;
5343 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
5345 DffRecordHeader aShapeAtom;
5346 rSt >> aShapeAtom;
5347 if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
5349 sal_Int32 l, o, r, u;
5350 rSt >> l >> o >> r >> u;
5351 Scale( l );
5352 Scale( o );
5353 Scale( r );
5354 Scale( u );
5355 Rectangle aChild( l, o, r, u );
5357 if ( bFirst )
5359 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
5361 double fl = l;
5362 double fo = o;
5363 double fWidth = r - l;
5364 double fHeight= u - o;
5365 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
5366 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
5367 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
5368 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top();
5369 fWidth *= fXScale;
5370 fHeight *= fYScale;
5371 rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
5373 bFirst = sal_False;
5375 else
5376 rGroupChildAnchor.Union( aChild );
5377 break;
5379 aShapeAtom.SeekToEndOfRecord( rSt );
5382 aShapeHd.SeekToEndOfRecord( rSt );
5386 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt,
5387 DffObjData& rObjData,
5388 void* pData,
5389 Rectangle& rTextRect,
5390 SdrObject* pObj
5393 if( !rTextRect.IsEmpty() )
5395 SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
5396 SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
5397 SvxMSDffImportRec* pTextImpRec = pImpRec;
5399 // fill Import Record with data
5400 pImpRec->nShapeId = rObjData.nShapeId;
5401 pImpRec->eShapeType = rObjData.eShapeType;
5403 MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue(
5404 DFF_Prop_WrapText,
5405 mso_wrapSquare ) );
5406 rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
5407 DFF_msofbtClientAnchor,
5408 SEEK_FROM_CURRENT_AND_RESTART );
5409 if( rObjData.bClientAnchor )
5410 ProcessClientAnchor( rSt,
5411 maShapeRecords.Current()->nRecLen,
5412 pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
5414 rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
5415 DFF_msofbtClientData,
5416 SEEK_FROM_CURRENT_AND_RESTART );
5417 if( rObjData.bClientData )
5418 ProcessClientData( rSt,
5419 maShapeRecords.Current()->nRecLen,
5420 pImpRec->pClientDataBuffer, pImpRec->nClientDataLen );
5423 // process user (== Winword) defined parameters in 0xF122 record
5424 if( maShapeRecords.SeekToContent( rSt,
5425 DFF_msofbtUDefProp,
5426 SEEK_FROM_CURRENT_AND_RESTART )
5427 && maShapeRecords.Current()->nRecLen )
5429 UINT32 nBytesLeft = maShapeRecords.Current()->nRecLen;
5430 UINT32 nUDData;
5431 UINT16 nPID;
5432 while( 5 < nBytesLeft )
5434 rSt >> nPID;
5435 if ( rSt.GetError() != 0 )
5436 break;
5437 rSt >> nUDData;
5438 switch( nPID )
5440 case 0x038F: pImpRec->nXAlign = nUDData; break;
5441 case 0x0390: pImpRec->nXRelTo = nUDData; break;
5442 case 0x0391: pImpRec->nYAlign = nUDData; break;
5443 case 0x0392: pImpRec->nYRelTo = nUDData; break;
5444 case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break;
5446 if ( rSt.GetError() != 0 )
5447 break;
5448 pImpRec->bHasUDefProp = TRUE;
5449 nBytesLeft -= 6;
5453 // Textrahmen, auch Title oder Outline
5454 SdrObject* pOrgObj = pObj;
5455 SdrRectObj* pTextObj = 0;
5456 UINT32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
5457 if( nTextId )
5459 SfxItemSet aSet( pSdrModel->GetItemPool() );
5461 //Originally anything that as a mso_sptTextBox was created as a
5462 //textbox, this was changed for #88277# to be created as a simple
5463 //rect to keep impress happy. For the rest of us we'd like to turn
5464 //it back into a textbox again.
5465 FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox);
5466 if (!bTextFrame)
5468 //Either
5469 //a) its a simple text object or
5470 //b) its a rectangle with text and square wrapping.
5471 bTextFrame =
5473 (pImpRec->eShapeType == mso_sptTextSimple) ||
5475 (pImpRec->eShapeType == mso_sptRectangle)
5476 && (eWrapMode == mso_wrapSquare)
5477 && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
5482 if (bTextFrame)
5484 SdrObject::Free( pObj );
5485 pObj = pOrgObj = 0;
5488 // Distance of Textbox to it's surrounding Customshape
5489 INT32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
5490 INT32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
5491 INT32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L );
5492 INT32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
5494 ScaleEmu( nTextLeft );
5495 ScaleEmu( nTextRight );
5496 ScaleEmu( nTextTop );
5497 ScaleEmu( nTextBottom );
5499 INT32 nTextRotationAngle=0;
5500 bool bVerticalText = false;
5501 if ( IsProperty( DFF_Prop_txflTextFlow ) )
5503 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue(
5504 DFF_Prop_txflTextFlow) & 0xFFFF);
5505 switch( eTextFlow )
5507 case mso_txflBtoT:
5508 nTextRotationAngle = 9000;
5509 break;
5510 case mso_txflVertN:
5511 case mso_txflTtoBN:
5512 nTextRotationAngle = 27000;
5513 break;
5514 case mso_txflTtoBA:
5515 bVerticalText = true;
5516 break;
5517 case mso_txflHorzA:
5518 bVerticalText = true;
5519 nTextRotationAngle = 9000;
5520 case mso_txflHorzN:
5521 default :
5522 break;
5526 if (nTextRotationAngle)
5528 while (nTextRotationAngle > 360000)
5529 nTextRotationAngle-=9000;
5530 switch (nTextRotationAngle)
5532 case 9000:
5534 long nWidth = rTextRect.GetWidth();
5535 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5536 rTextRect.Bottom() = rTextRect.Top() + nWidth;
5538 INT32 nOldTextLeft = nTextLeft;
5539 INT32 nOldTextRight = nTextRight;
5540 INT32 nOldTextTop = nTextTop;
5541 INT32 nOldTextBottom = nTextBottom;
5543 nTextLeft = nOldTextBottom;
5544 nTextRight = nOldTextTop;
5545 nTextTop = nOldTextLeft;
5546 nTextBottom = nOldTextRight;
5548 break;
5549 case 27000:
5551 long nWidth = rTextRect.GetWidth();
5552 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5553 rTextRect.Bottom() = rTextRect.Top() + nWidth;
5555 INT32 nOldTextLeft = nTextLeft;
5556 INT32 nOldTextRight = nTextRight;
5557 INT32 nOldTextTop = nTextTop;
5558 INT32 nOldTextBottom = nTextBottom;
5560 nTextLeft = nOldTextTop;
5561 nTextRight = nOldTextBottom;
5562 nTextTop = nOldTextRight;
5563 nTextBottom = nOldTextLeft;
5565 break;
5566 default:
5567 break;
5571 pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect);
5572 pTextImpRec = new SvxMSDffImportRec(*pImpRec);
5574 // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
5575 // hier rausrechnen
5576 Rectangle aNewRect(rTextRect);
5577 aNewRect.Bottom() -= nTextTop + nTextBottom;
5578 aNewRect.Right() -= nTextLeft + nTextRight;
5580 // Nur falls es eine einfache Textbox ist, darf der Writer
5581 // das Objekt durch einen Rahmen ersetzen, ansonsten
5582 if( bTextFrame )
5584 SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId );
5585 aTmpRec.bSortByShapeId = TRUE;
5587 USHORT nFound;
5588 if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) )
5590 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound);
5591 pTextImpRec->bReplaceByFly = rInfo.bReplaceByFly;
5592 pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain;
5596 if( !pObj )
5597 ApplyAttributes( rSt, aSet, rObjData.eShapeType, rObjData.nSpFlags );
5599 bool bFitText = false;
5600 if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2)
5602 aSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
5603 aSet.Put( SdrTextMinFrameHeightItem(
5604 aNewRect.Bottom() - aNewRect.Top() ) );
5605 aSet.Put( SdrTextMinFrameWidthItem(
5606 aNewRect.Right() - aNewRect.Left() ) );
5607 bFitText = true;
5609 else
5611 aSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
5612 aSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
5615 switch ( (MSO_WrapMode)
5616 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) )
5618 case mso_wrapNone :
5619 aSet.Put( SdrTextAutoGrowWidthItem( TRUE ) );
5620 if (bFitText)
5622 //can't do autowidth in flys #i107184#
5623 pTextImpRec->bReplaceByFly = false;
5625 break;
5626 case mso_wrapByPoints :
5627 aSet.Put( SdrTextContourFrameItem( TRUE ) );
5628 break;
5629 default: break;
5632 // Abstaende an den Raendern der Textbox setzen
5633 aSet.Put( SdrTextLeftDistItem( nTextLeft ) );
5634 aSet.Put( SdrTextRightDistItem( nTextRight ) );
5635 aSet.Put( SdrTextUpperDistItem( nTextTop ) );
5636 aSet.Put( SdrTextLowerDistItem( nTextBottom ) );
5637 pTextImpRec->nDxTextLeft = nTextLeft;
5638 pTextImpRec->nDyTextTop = nTextTop;
5639 pTextImpRec->nDxTextRight = nTextRight;
5640 pTextImpRec->nDyTextBottom = nTextBottom;
5642 // Textverankerung lesen
5643 if ( IsProperty( DFF_Prop_anchorText ) )
5645 MSO_Anchor eTextAnchor =
5646 (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText );
5648 SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER;
5649 BOOL bTVASet(FALSE);
5650 SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER;
5651 BOOL bTHASet(FALSE);
5653 switch( eTextAnchor )
5655 case mso_anchorTop:
5657 eTVA = SDRTEXTVERTADJUST_TOP;
5658 bTVASet = TRUE;
5660 break;
5661 case mso_anchorTopCentered:
5663 eTVA = SDRTEXTVERTADJUST_TOP;
5664 bTVASet = TRUE;
5665 bTHASet = TRUE;
5667 break;
5669 case mso_anchorMiddle:
5670 bTVASet = TRUE;
5671 break;
5672 case mso_anchorMiddleCentered:
5674 bTVASet = TRUE;
5675 bTHASet = TRUE;
5677 break;
5678 case mso_anchorBottom:
5680 eTVA = SDRTEXTVERTADJUST_BOTTOM;
5681 bTVASet = TRUE;
5683 break;
5684 case mso_anchorBottomCentered:
5686 eTVA = SDRTEXTVERTADJUST_BOTTOM;
5687 bTVASet = TRUE;
5688 bTHASet = TRUE;
5690 break;
5692 case mso_anchorTopBaseline:
5693 case mso_anchorBottomBaseline:
5694 case mso_anchorTopCenteredBaseline:
5695 case mso_anchorBottomCenteredBaseline:
5696 break;
5698 default : break;
5700 // Einsetzen
5701 if ( bTVASet )
5702 aSet.Put( SdrTextVertAdjustItem( eTVA ) );
5703 if ( bTHASet )
5704 aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
5707 pTextObj->SetMergedItemSet(aSet);
5708 pTextObj->SetModel(pSdrModel);
5710 if (bVerticalText)
5711 pTextObj->SetVerticalWriting(sal_True);
5713 if (nTextRotationAngle)
5715 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ?
5716 rTextRect.GetWidth() : rTextRect.GetHeight();
5717 nMinWH /= 2;
5718 Point aPivot(rTextRect.TopLeft());
5719 aPivot.X() += nMinWH;
5720 aPivot.Y() += nMinWH;
5721 double a = nTextRotationAngle * nPi180;
5722 pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a));
5725 // rotate text with shape ?
5726 if ( mnFix16Angle )
5728 double a = mnFix16Angle * nPi180;
5729 pTextObj->NbcRotate( rObjData.rBoundRect.Center(), mnFix16Angle,
5730 sin( a ), cos( a ) );
5733 if( !pObj )
5735 pObj = pTextObj;
5737 else
5739 if( pTextObj != pObj )
5741 SdrObject* pGroup = new SdrObjGroup;
5742 pGroup->GetSubList()->NbcInsertObject( pObj );
5743 pGroup->GetSubList()->NbcInsertObject( pTextObj );
5744 if (pOrgObj == pObj)
5745 pOrgObj = pGroup;
5746 else
5747 pOrgObj = pObj;
5748 pObj = pGroup;
5752 else if( !pObj )
5754 // simple rectangular objects are ignored by ImportObj() :-(
5755 // this is OK for Draw but not for Calc and Writer
5756 // cause here these objects have a default border
5757 pObj = new SdrRectObj(rTextRect);
5758 pOrgObj = pObj;
5759 pObj->SetModel( pSdrModel );
5760 SfxItemSet aSet( pSdrModel->GetItemPool() );
5761 ApplyAttributes( rSt, aSet, rObjData.eShapeType, rObjData.nSpFlags );
5763 const SfxPoolItem* pPoolItem=NULL;
5764 SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
5765 FALSE, &pPoolItem );
5766 if( SFX_ITEM_DEFAULT == eState )
5767 aSet.Put( XFillColorItem( String(),
5768 Color( mnDefaultColor ) ) );
5769 pObj->SetMergedItemSet(aSet);
5772 //Means that fBehindDocument is set
5773 if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
5774 pImpRec->bDrawHell = TRUE;
5775 else
5776 pImpRec->bDrawHell = FALSE;
5777 if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
5778 pImpRec->bHidden = TRUE;
5779 pTextImpRec->bDrawHell = pImpRec->bDrawHell;
5780 pTextImpRec->bHidden = pImpRec->bHidden;
5781 pImpRec->nNextShapeId = GetPropertyValue( DFF_Prop_hspNext, 0 );
5782 pTextImpRec->nNextShapeId=pImpRec->nNextShapeId;
5784 if ( nTextId )
5786 pTextImpRec->aTextId.nTxBxS = (UINT16)( nTextId >> 16 );
5787 pTextImpRec->aTextId.nSequence = (UINT16)nTextId;
5790 pTextImpRec->nDxWrapDistLeft = GetPropertyValue(
5791 DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
5792 pTextImpRec->nDyWrapDistTop = GetPropertyValue(
5793 DFF_Prop_dyWrapDistTop, 0 ) / 635L;
5794 pTextImpRec->nDxWrapDistRight = GetPropertyValue(
5795 DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
5796 pTextImpRec->nDyWrapDistBottom = GetPropertyValue(
5797 DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
5798 // 16.16 fraction times total image width or height, as appropriate.
5800 if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt))
5802 delete pTextImpRec->pWrapPolygon;
5803 sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
5804 rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
5805 if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
5807 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert);
5808 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
5810 sal_Int32 nX, nY;
5811 if (nElemSizeVert == 8)
5812 rSt >> nX >> nY;
5813 else
5815 sal_Int16 nSmallX, nSmallY;
5816 rSt >> nSmallX >> nSmallY;
5817 nX = nSmallX;
5818 nY = nSmallY;
5820 (*(pTextImpRec->pWrapPolygon))[i].X() = nX;
5821 (*(pTextImpRec->pWrapPolygon))[i].Y() = nY;
5826 pImpRec->nCropFromTop = GetPropertyValue(
5827 DFF_Prop_cropFromTop, 0 );
5828 pImpRec->nCropFromBottom = GetPropertyValue(
5829 DFF_Prop_cropFromBottom, 0 );
5830 pImpRec->nCropFromLeft = GetPropertyValue(
5831 DFF_Prop_cropFromLeft, 0 );
5832 pImpRec->nCropFromRight = GetPropertyValue(
5833 DFF_Prop_cropFromRight, 0 );
5835 pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false;
5836 pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false;
5838 UINT32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
5839 pImpRec->eLineStyle = (nLineFlags & 8)
5840 ? (MSO_LineStyle)GetPropertyValue(
5841 DFF_Prop_lineStyle,
5842 mso_lineSimple )
5843 : (MSO_LineStyle)USHRT_MAX;
5844 pTextImpRec->eLineStyle = pImpRec->eLineStyle;
5846 if( pImpRec->nShapeId )
5848 // Import-Record-Liste ergaenzen
5849 if( pOrgObj )
5851 pImpRec->pObj = pOrgObj;
5852 rImportData.aRecords.Insert( pImpRec );
5855 if( pTextObj && (pOrgObj != pTextObj) )
5857 // Modify ShapeId (must be unique)
5858 pImpRec->nShapeId |= 0x8000000;
5859 pTextImpRec->pObj = pTextObj;
5860 rImportData.aRecords.Insert( pTextImpRec );
5863 // Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen
5864 /*Only store objects which are not deep inside the tree*/
5865 if( ( rObjData.nCalledByGroup == 0 )
5867 ( (rObjData.nSpFlags & SP_FGROUP)
5868 && (rObjData.nCalledByGroup < 2) )
5870 StoreShapeOrder( pImpRec->nShapeId,
5871 ( ( (ULONG)pImpRec->aTextId.nTxBxS ) << 16 )
5872 + pImpRec->aTextId.nSequence, pObj );
5874 else
5875 delete pImpRec;
5878 return pObj;
5881 void SvxMSDffManager::StoreShapeOrder(ULONG nId,
5882 ULONG nTxBx,
5883 SdrObject* pObject,
5884 SwFlyFrmFmt* pFly,
5885 short nHdFtSection) const
5887 USHORT nShpCnt = pShapeOrders->Count();
5888 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5890 SvxMSDffShapeOrder& rOrder
5891 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5893 if( rOrder.nShapeId == nId )
5895 rOrder.nTxBxComp = nTxBx;
5896 rOrder.pObj = pObject;
5897 rOrder.pFly = pFly;
5898 rOrder.nHdFtSection = nHdFtSection;
5904 void SvxMSDffManager::ExchangeInShapeOrder( SdrObject* pOldObject,
5905 ULONG nTxBx,
5906 SwFlyFrmFmt* pFly,
5907 SdrObject* pObject) const
5909 USHORT nShpCnt = pShapeOrders->Count();
5910 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5912 SvxMSDffShapeOrder& rOrder
5913 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5915 if( rOrder.pObj == pOldObject )
5917 rOrder.pFly = pFly;
5918 rOrder.pObj = pObject;
5919 rOrder.nTxBxComp = nTxBx;
5925 void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const
5927 USHORT nShpCnt = pShapeOrders->Count();
5928 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
5930 SvxMSDffShapeOrder& rOrder
5931 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
5933 if( rOrder.pObj == pObject )
5935 rOrder.pObj = 0;
5936 rOrder.pFly = 0;
5937 rOrder.nTxBxComp = 0;
5945 //---------------------------------------------------------------------------
5946 // Hilfs Deklarationen
5947 //---------------------------------------------------------------------------
5949 /*struct SvxMSDffBLIPInfo -> in's Header-File
5951 USHORT nBLIPType; // Art des BLIP: z.B. 6 fuer PNG
5952 ULONG nFilePos; // Offset des BLIP im Daten-Stream
5953 ULONG nBLIPSize; // Anzahl Bytes, die der BLIP im Stream einnimmt
5954 SvxMSDffBLIPInfo(USHORT nBType, ULONG nFPos, ULONG nBSize):
5955 nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){}
5959 SV_IMPL_PTRARR( SvxMSDffBLIPInfos, SvxMSDffBLIPInfo_Ptr );
5961 SV_IMPL_PTRARR( SvxMSDffShapeOrders, SvxMSDffShapeOrder_Ptr );
5963 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeInfos, SvxMSDffShapeInfo_Ptr );
5965 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeTxBxSort, SvxMSDffShapeOrder_Ptr );
5968 // Liste aller SvxMSDffImportRec fuer eine Gruppe
5969 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr)
5971 //---------------------------------------------------------------------------
5972 // exportierte Klasse: oeffentliche Methoden
5973 //---------------------------------------------------------------------------
5975 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_,
5976 const String& rBaseURL,
5977 long nOffsDgg_,
5978 SvStream* pStData_,
5979 SdrModel* pSdrModel_,// s. unten: SetModel()
5980 long nApplicationScale,
5981 ColorData mnDefaultColor_,
5982 ULONG nDefaultFontHeight_,
5983 SvStream* pStData2_,
5984 MSFilterTracer* pTracer )
5985 :DffPropertyReader( *this ),
5986 pFormModel( NULL ),
5987 pBLIPInfos( new SvxMSDffBLIPInfos ),
5988 pShapeInfos( new SvxMSDffShapeInfos ),
5989 pShapeOrders( new SvxMSDffShapeOrders ),
5990 nDefaultFontHeight( nDefaultFontHeight_),
5991 nOffsDgg( nOffsDgg_ ),
5992 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen,
5993 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt
5994 maBaseURL( rBaseURL ),
5995 mpFidcls( NULL ),
5996 rStCtrl( rStCtrl_ ),
5997 pStData( pStData_ ),
5998 pStData2( pStData2_ ),
5999 nSvxMSDffSettings( 0 ),
6000 nSvxMSDffOLEConvFlags( 0 ),
6001 pEscherBlipCache( NULL ),
6002 mnDefaultColor( mnDefaultColor_),
6003 mpTracer( pTracer ),
6004 mbTracing( sal_False )
6006 if ( mpTracer )
6008 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
6009 aAny >>= mbTracing;
6011 SetModel( pSdrModel_, nApplicationScale );
6013 // FilePos des/der Stream(s) merken
6014 ULONG nOldPosCtrl = rStCtrl.Tell();
6015 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6017 // Falls kein Datenstream angegeben, gehen wir davon aus,
6018 // dass die BLIPs im Steuerstream stehen.
6019 if( !pStData )
6020 pStData = &rStCtrl;
6022 SetDefaultPropSet( rStCtrl, nOffsDgg );
6024 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
6025 GetCtrlData( nOffsDgg );
6027 // Text-Box-Story-Ketten-Infos ueberpruefen
6028 CheckTxBxStoryChain();
6030 // alte FilePos des/der Stream(s) restaurieren
6031 rStCtrl.Seek( nOldPosCtrl );
6032 if( &rStCtrl != pStData )
6033 pStData->Seek( nOldPosData );
6036 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer )
6037 :DffPropertyReader( *this ),
6038 pFormModel( NULL ),
6039 pBLIPInfos( new SvxMSDffBLIPInfos ),
6040 pShapeInfos( new SvxMSDffShapeInfos ),
6041 pShapeOrders( new SvxMSDffShapeOrders ),
6042 nDefaultFontHeight( 24 ),
6043 nOffsDgg( 0 ),
6044 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen,
6045 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt
6046 maBaseURL( rBaseURL ),
6047 mpFidcls( NULL ),
6048 rStCtrl( rStCtrl_ ),
6049 pStData( 0 ),
6050 pStData2( 0 ),
6051 nSvxMSDffSettings( 0 ),
6052 nSvxMSDffOLEConvFlags( 0 ),
6053 pEscherBlipCache( NULL ),
6054 mnDefaultColor( COL_DEFAULT ),
6055 mpTracer( pTracer ),
6056 mbTracing( sal_False )
6058 if ( mpTracer )
6060 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
6061 aAny >>= mbTracing;
6063 SetModel( NULL, 0 );
6066 SvxMSDffManager::~SvxMSDffManager()
6068 if ( pEscherBlipCache )
6070 void* pPtr;
6071 for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() )
6072 delete (EscherBlipCacheEntry*)pPtr;
6073 delete pEscherBlipCache;
6075 delete pBLIPInfos;
6076 delete pShapeInfos;
6077 delete pShapeOrders;
6078 delete pFormModel;
6079 delete[] mpFidcls;
6082 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags )
6084 nOffsDgg = nOffsDgg_;
6085 pStData = pStData_;
6086 nSvxMSDffOLEConvFlags = nOleConvFlags;
6088 // FilePos des/der Stream(s) merken
6089 ULONG nOldPosCtrl = rStCtrl.Tell();
6091 SetDefaultPropSet( rStCtrl, nOffsDgg );
6093 // insert fidcl cluster table
6094 GetFidclData( nOffsDgg );
6096 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
6097 GetCtrlData( nOffsDgg );
6099 // Text-Box-Story-Ketten-Infos ueberpruefen
6100 CheckTxBxStoryChain();
6102 // alte FilePos des/der Stream(s) restaurieren
6103 rStCtrl.Seek( nOldPosCtrl );
6106 void SvxMSDffManager::SetDgContainer( SvStream& rSt )
6108 UINT32 nFilePos = rSt.Tell();
6109 DffRecordHeader aDgContHd;
6110 rSt >> aDgContHd;
6111 // insert this container only if there is also a DgAtom
6112 if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) )
6114 DffRecordHeader aRecHd;
6115 rSt >> aRecHd;
6116 UINT32 nDrawingId = aRecHd.nRecInstance;
6117 maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos );
6118 rSt.Seek( nFilePos );
6122 void SvxMSDffManager::GetFidclData( long nOffsDggL )
6124 if ( nOffsDggL )
6126 UINT32 nDummy, nMerk = rStCtrl.Tell();
6127 rStCtrl.Seek( nOffsDggL );
6129 DffRecordHeader aRecHd;
6130 rStCtrl >> aRecHd;
6132 DffRecordHeader aDggAtomHd;
6133 if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) )
6135 aDggAtomHd.SeekToContent( rStCtrl );
6136 rStCtrl >> mnCurMaxShapeId
6137 >> mnIdClusters
6138 >> nDummy
6139 >> mnDrawingsSaved;
6141 if ( mnIdClusters-- > 2 )
6143 if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) )
6145 mpFidcls = new FIDCL[ mnIdClusters ];
6146 for ( UINT32 i = 0; i < mnIdClusters; i++ )
6148 rStCtrl >> mpFidcls[ i ].dgid
6149 >> mpFidcls[ i ].cspidCur;
6154 rStCtrl.Seek( nMerk );
6158 void SvxMSDffManager::CheckTxBxStoryChain()
6160 SvxMSDffShapeInfos* pOld = pShapeInfos;
6161 USHORT nCnt = pOld->Count();
6162 pShapeInfos = new SvxMSDffShapeInfos( (nCnt < 255)
6163 ? nCnt
6164 : 255 );
6165 // altes Info-Array ueberarbeiten
6166 // (ist sortiert nach nTxBxComp)
6167 ULONG nChain = ULONG_MAX;
6168 USHORT nObjMark = 0;
6169 BOOL bSetReplaceFALSE = FALSE;
6170 USHORT nObj;
6171 for( nObj = 0; nObj < nCnt; ++nObj )
6173 SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj );
6174 if( pObj->nTxBxComp )
6176 pObj->bLastBoxInChain = FALSE;
6177 // Gruppenwechsel ?
6178 // --> OD 2008-07-28 #156763#
6179 // the text id also contains an internal drawing container id
6180 // to distinguish between text id of drawing objects in different
6181 // drawing containers.
6182 // if( nChain != (pObj->nTxBxComp & 0xFFFF0000) )
6183 if( nChain != pObj->nTxBxComp )
6184 // <--
6186 // voriger war letzter seiner Gruppe
6187 if( nObj )
6188 pOld->GetObject( nObj-1 )->bLastBoxInChain = TRUE;
6189 // Merker und Hilfs-Flag zuruecksetzen
6190 nObjMark = nObj;
6191 // --> OD 2008-07-28 #156763#
6192 // nChain = pObj->nTxBxComp & 0xFFFF0000;
6193 nChain = pObj->nTxBxComp;
6194 // <--
6195 bSetReplaceFALSE = !pObj->bReplaceByFly;
6197 else
6198 if( !pObj->bReplaceByFly )
6200 // Objekt, das NICHT durch Rahmen ersetzt werden darf ?
6201 // Hilfs-Flag setzen
6202 bSetReplaceFALSE = TRUE;
6203 // ggfs Flag in Anfang der Gruppe austragen
6204 for( USHORT nObj2 = nObjMark; nObj2 < nObj; ++nObj2 )
6205 pOld->GetObject( nObj2 )->bReplaceByFly = FALSE;
6208 if( bSetReplaceFALSE )
6210 pObj->bReplaceByFly = FALSE;
6213 // alle Shape-Info-Objekte in pShapeInfos umkopieren
6214 // (aber nach nShapeId sortieren)
6215 pObj->bSortByShapeId = TRUE;
6216 // --> OD 2008-07-28 #156763#
6217 pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000;
6218 // <--
6219 pShapeInfos->Insert( pObj );
6221 // voriger war letzter seiner Gruppe
6222 if( nObj )
6223 pOld->GetObject( nObj-1 )->bLastBoxInChain = TRUE;
6224 // urspruengliches Array freigeben, ohne Objekte zu zerstoeren
6225 pOld->Remove((USHORT)0, nCnt);
6226 delete pOld;
6230 /*****************************************************************************
6232 Einlesen der Shape-Infos im Ctor:
6233 ---------------------------------
6234 merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos
6235 ========= ============ =============
6236 und merken des File-Offsets fuer jedes Blip
6237 ============
6238 ******************************************************************************/
6239 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ )
6241 // Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen
6242 long nOffsDggL = nOffsDgg_;
6244 // Kontroll Stream positionieren
6245 rStCtrl.Seek( nOffsDggL );
6247 BYTE nVer;
6248 USHORT nInst;
6249 USHORT nFbt;
6250 UINT32 nLength;
6251 if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return;
6253 BOOL bOk;
6254 ULONG nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE;
6256 // Fall A: erst Drawing Group Container, dann n Mal Drawing Container
6257 if( DFF_msofbtDggContainer == nFbt )
6259 GetDrawingGroupContainerData( rStCtrl, nLength );
6261 rStCtrl.Seek( STREAM_SEEK_TO_END );
6262 UINT32 nMaxStrPos = rStCtrl.Tell();
6264 nPos += nLength;
6265 // --> OD 2008-07-28 #156763#
6266 unsigned long nDrawingContainerId = 1;
6267 // <--
6270 rStCtrl.Seek( nPos );
6272 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt );
6274 if( !bOk )
6276 nPos++;
6277 rStCtrl.Seek( nPos );
6278 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength )
6279 && ( DFF_msofbtDgContainer == nFbt );
6281 if( bOk )
6283 // --> OD 2008-07-28 #156763#
6284 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId );
6285 // <--
6287 nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6288 // --> OD 2008-07-28 #156763#
6289 ++nDrawingContainerId;
6290 // <--
6292 while( nPos < nMaxStrPos && bOk );
6297 // ab hier: Drawing Group Container d.h. Dokument - weit gueltige Daten
6298 // ======================= ========
6300 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, ULONG nLenDgg )
6302 BYTE nVer;
6303 USHORT nInst;
6304 USHORT nFbt;
6305 UINT32 nLength;
6307 ULONG nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0;
6309 // Nach einem BStore Container suchen
6312 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6313 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6314 if( DFF_msofbtBstoreContainer == nFbt )
6316 nLenBStoreCont = nLength; break;
6318 rSt.SeekRel( nLength );
6320 while( nRead < nLenDgg );
6322 if( !nLenBStoreCont ) return;
6324 // Im BStore Container alle Header der Container und Atome auslesen und die
6325 // relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen.
6326 // Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit.
6328 const ULONG nSkipBLIPLen = 20; // bis zu nBLIPLen zu ueberspringende Bytes
6329 const ULONG nSkipBLIPPos = 4; // dahinter bis zu nBLIPPos zu skippen
6331 sal_uInt32 nBLIPLen = 0, nBLIPPos = 0;
6333 nRead = 0;
6336 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6337 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6338 if( DFF_msofbtBSE == nFbt )
6340 nLenFBSE = nLength;
6341 // ist FBSE gross genug fuer unsere Daten
6342 BOOL bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE );
6344 if( bOk )
6346 rSt.SeekRel( nSkipBLIPLen );
6347 rSt >> nBLIPLen;
6348 rSt.SeekRel( nSkipBLIPPos );
6349 rSt >> nBLIPPos;
6350 bOk = rSt.GetError() == 0;
6352 nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4;
6355 if( bOk )
6357 // Besonderheit:
6358 // Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist,
6359 // nehmen wir an, dass das Bild IM FBSE drin steht!
6360 if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) )
6361 nBLIPPos = rSt.Tell() + 4;
6363 // Das hat ja fein geklappt!
6364 // Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben.
6365 nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell());
6367 if( USHRT_MAX == nBLIPCount )
6368 nBLIPCount = 1;
6369 else
6370 nBLIPCount++;
6372 // Jetzt die Infos fuer spaetere Zugriffe speichern
6373 pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ),
6374 pBLIPInfos->Count() );
6377 rSt.SeekRel( nLength );
6379 while( nRead < nLenBStoreCont );
6383 // ab hier: Drawing Container d.h. Seiten (Blatt, Dia) - weit gueltige Daten
6384 // ================= ======
6386 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, ULONG nLenDg,
6387 const unsigned long nDrawingContainerId )
6389 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6391 ULONG nReadDg = 0;
6393 // Wir stehen in einem Drawing Container (je einer pro Seite)
6394 // und muessen nun
6395 // alle enthaltenen Shape Group Container abklappern
6398 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6399 nReadDg += DFF_COMMON_RECORD_HEADER_SIZE;
6400 // Patriarch gefunden (der oberste Shape Group Container) ?
6401 if( DFF_msofbtSpgrContainer == nFbt )
6403 if(!this->GetShapeGroupContainerData( rSt, nLength, TRUE, nDrawingContainerId )) return;
6405 else
6406 // blanker Shape Container ? (ausserhalb vom Shape Group Container)
6407 if( DFF_msofbtSpContainer == nFbt )
6409 if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return;
6411 else
6412 rSt.SeekRel( nLength );
6413 nReadDg += nLength;
6415 while( nReadDg < nLenDg );
6418 BOOL SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt,
6419 ULONG nLenShapeGroupCont,
6420 BOOL bPatriarch,
6421 const unsigned long nDrawingContainerId )
6423 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6424 long nStartShapeGroupCont = rSt.Tell();
6425 // Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite)
6426 // und muessen nun
6427 // alle enthaltenen Shape Container abklappern
6428 BOOL bFirst = !bPatriarch;
6429 ULONG nReadSpGrCont = 0;
6432 if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) )
6433 return FALSE;
6434 nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE;
6435 // Shape Container ?
6436 if( DFF_msofbtSpContainer == nFbt )
6438 ULONG nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX;
6439 if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) )
6440 return FALSE;
6441 bFirst = FALSE;
6443 else
6444 // eingeschachtelter Shape Group Container ?
6445 if( DFF_msofbtSpgrContainer == nFbt )
6447 if ( !this->GetShapeGroupContainerData( rSt, nLength, FALSE, nDrawingContainerId ) )
6448 return FALSE;
6450 else
6451 rSt.SeekRel( nLength );
6452 nReadSpGrCont += nLength;
6454 while( nReadSpGrCont < nLenShapeGroupCont );
6455 // den Stream wieder korrekt positionieren
6456 rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont );
6457 return TRUE;
6460 BOOL SvxMSDffManager::GetShapeContainerData( SvStream& rSt,
6461 ULONG nLenShapeCont,
6462 ULONG nPosGroup,
6463 const unsigned long nDrawingContainerId )
6465 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6466 long nStartShapeCont = rSt.Tell();
6467 // Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group)
6468 // und muessen nun
6469 // die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe)
6470 // und den ersten BStore Verweis (falls vorhanden) entnehmen
6471 ULONG nLenShapePropTbl = 0;
6472 ULONG nReadSpCont = 0;
6474 // File Offset des Shape-Containers bzw. der Gruppe(!) vermerken
6476 ULONG nStartOffs = (ULONG_MAX > nPosGroup) ?
6477 nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE;
6478 SvxMSDffShapeInfo aInfo( nStartOffs );
6480 // duerfte das Shape durch einen Rahmen ersetzt werden ?
6481 // (vorausgesetzt, es zeigt sich, dass es eine TextBox ist,
6482 // und der Text nicht gedreht ist)
6483 BOOL bCanBeReplaced = (ULONG_MAX > nPosGroup) ? FALSE : TRUE;
6485 // wir wissen noch nicht, ob es eine TextBox ist
6486 MSO_SPT eShapeType = mso_sptNil;
6487 MSO_WrapMode eWrapMode = mso_wrapSquare;
6488 // BOOL bIsTextBox = FALSE;
6490 // Shape analysieren
6494 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return FALSE;
6495 nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE;
6496 // FSP ?
6497 if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) )
6499 // Wir haben den FSP gefunden: Shape Typ und Id vermerken!
6500 eShapeType = (MSO_SPT)nInst;
6501 rSt >> aInfo.nShapeId;
6502 rSt.SeekRel( nLength - 4 );
6503 nReadSpCont += nLength;
6505 else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ?
6507 // Wir haben die Property Table gefunden:
6508 // nach der Blip Property suchen!
6509 ULONG nPropRead = 0;
6510 USHORT nPropId;
6511 sal_uInt32 nPropVal;
6512 nLenShapePropTbl = nLength;
6513 // UINT32 nPropCount = nInst;
6514 long nStartShapePropTbl = rSt.Tell();
6515 // UINT32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6);
6518 rSt >> nPropId
6519 >> nPropVal;
6520 nPropRead += 6;
6522 switch( nPropId )
6524 case DFF_Prop_txflTextFlow :
6525 //Writer can now handle vertical textflows in its
6526 //native frames, to only need to do this for the
6527 //other two formats
6529 //Writer will handle all textflow except BtoT
6530 if (GetSvxMSDffSettings() &
6531 (SVXMSDFF_SETTINGS_IMPORT_PPT |
6532 SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6534 if( 0 != nPropVal )
6535 bCanBeReplaced = false;
6537 else if (
6538 (nPropVal != mso_txflHorzN) &&
6539 (nPropVal != mso_txflTtoBA)
6542 bCanBeReplaced = false;
6544 break;
6545 case DFF_Prop_cdirFont :
6546 //Writer can now handle right to left and left
6547 //to right in its native frames, so only do
6548 //this for the other two formats.
6549 if (GetSvxMSDffSettings() &
6550 (SVXMSDFF_SETTINGS_IMPORT_PPT |
6551 SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6553 if( 0 != nPropVal )
6554 bCanBeReplaced = FALSE;
6556 break;
6557 case DFF_Prop_Rotation :
6558 if( 0 != nPropVal )
6559 bCanBeReplaced = FALSE;
6560 break;
6562 case DFF_Prop_gtextFStrikethrough :
6563 if( ( 0x20002000 & nPropVal ) == 0x20002000 )
6564 bCanBeReplaced = FALSE;
6565 break;
6567 case DFF_Prop_fc3DLightFace :
6568 if( ( 0x00080008 & nPropVal ) == 0x00080008 )
6569 bCanBeReplaced = FALSE;
6570 break;
6572 case DFF_Prop_WrapText :
6573 eWrapMode = (MSO_WrapMode)nPropVal;
6574 break;
6576 default:
6578 // Bit gesetzt und gueltig?
6579 if( 0x4000 == ( nPropId & 0xC000 ) )
6581 // Blip Property gefunden: BStore Idx vermerken!
6582 nPropRead = nLenShapePropTbl;
6584 else if( 0x8000 & nPropId )
6586 // komplexe Prop gefunden:
6587 // Laenge ist immer 6, nur die Laenge der nach der
6588 // eigentlichen Prop-Table anhaengenden Extra-Daten
6589 // ist unterschiedlich
6590 nPropVal = 6;
6593 break;
6597 //JP 21.04.99: Bug 64510
6598 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge
6599 // Performance einbussen hat.
6601 if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig?
6603 // Blip Property gefunden: BStore Idx vermerken!
6604 aInfo.nBStoreIdx = nPropVal; // Index im BStore Container
6605 break;
6607 else
6608 if( ( ( (DFF_Prop_txflTextFlow == nPropId)
6609 || (DFF_Prop_Rotation == nPropId)
6610 || (DFF_Prop_cdirFont == nPropId) )
6611 && (0 != nPropVal) )
6613 || ( (DFF_Prop_gtextFStrikethrough == nPropId)
6614 && ( (0x20002000 & nPropVal) == 0x20002000) ) // also DFF_Prop_gtextFVertical
6615 || ( (DFF_Prop_fc3DLightFace == nPropId)
6616 && ( (0x00080008 & nPropVal) == 0x00080008) ) // also DFF_Prop_f3D
6619 bCanBeReplaced = FALSE; // Mist: gedrehter Text oder 3D-Objekt!
6621 else
6622 if( DFF_Prop_WrapText == nPropId )
6624 eWrapMode = (MSO_WrapMode)nPropVal;
6626 ////////////////////////////////////////////////////////////////
6627 ////////////////////////////////////////////////////////////////
6628 // keine weitere Property-Auswertung: folge beim Shape-Import //
6629 ////////////////////////////////////////////////////////////////
6630 ////////////////////////////////////////////////////////////////
6631 else
6632 if( 0x8000 & nPropId )
6634 // komplexe Prop gefunden: Laenge lesen und ueberspringen
6635 if(!SkipBytes( rSt, nPropVal )) return FALSE;
6636 nPropRead += nPropVal;
6640 while( nPropRead < nLenShapePropTbl );
6641 rSt.Seek( nStartShapePropTbl + nLenShapePropTbl );
6642 nReadSpCont += nLenShapePropTbl;
6644 else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) ) // Text-Box-Story-Eintrag gefunden
6646 rSt >> aInfo.nTxBxComp;
6647 // --> OD 2008-07-28 #156763#
6648 // Add internal drawing container id to text id.
6649 // Note: The text id uses the first two bytes, while the internal
6650 // drawing container id used the second two bytes.
6651 aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) +
6652 nDrawingContainerId;
6653 DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId,
6654 "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." );
6655 // <--
6657 else
6659 rSt.SeekRel( nLength );
6660 nReadSpCont += nLength;
6663 while( nReadSpCont < nLenShapeCont );
6666 // Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern
6668 if( aInfo.nShapeId )
6670 // fuer Textboxen ggfs. ersetzen durch Rahmen erlauben
6671 if( bCanBeReplaced
6672 && aInfo.nTxBxComp
6673 && (
6674 ( eShapeType == mso_sptTextSimple )
6675 || ( eShapeType == mso_sptTextBox )
6676 || ( ( ( eShapeType == mso_sptRectangle )
6677 || ( eShapeType == mso_sptRoundRectangle )
6679 ) ) )
6681 aInfo.bReplaceByFly = TRUE;
6683 pShapeInfos->Insert( new SvxMSDffShapeInfo( aInfo ) );
6684 pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ),
6685 pShapeOrders->Count() );
6688 // und den Stream wieder korrekt positionieren
6689 rSt.Seek( nStartShapeCont + nLenShapeCont );
6690 return TRUE;
6695 /*****************************************************************************
6697 Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id)
6698 ----------------------------------
6699 ******************************************************************************/
6700 BOOL SvxMSDffManager::GetShape(ULONG nId, SdrObject*& rpShape,
6701 SvxMSDffImportData& rData)
6703 SvxMSDffShapeInfo aTmpRec(0, nId);
6704 aTmpRec.bSortByShapeId = TRUE;
6706 USHORT nFound;
6707 if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) )
6709 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound );
6711 // eventuell altes Errorflag loeschen
6712 if( rStCtrl.GetError() )
6713 rStCtrl.ResetError();
6714 // FilePos des/der Stream(s) merken
6715 ULONG nOldPosCtrl = rStCtrl.Tell();
6716 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6717 // das Shape im Steuer Stream anspringen
6718 rStCtrl.Seek( rInfo.nFilePos );
6720 // Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt!
6721 if( rStCtrl.GetError() )
6722 rStCtrl.ResetError();
6723 else
6724 rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect );
6726 // alte FilePos des/der Stream(s) restaurieren
6727 rStCtrl.Seek( nOldPosCtrl );
6728 if( &rStCtrl != pStData )
6729 pStData->Seek( nOldPosData );
6730 return ( 0 != rpShape );
6732 return FALSE;
6737 /* Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr)
6738 ---------------------------------
6739 ******************************************************************************/
6740 BOOL SvxMSDffManager::GetBLIP( ULONG nIdx_, Graphic& rData, Rectangle* pVisArea ) const
6742 BOOL bOk = FALSE; // Ergebnisvariable initialisieren
6743 if ( pStData )
6745 // check if a graphic for this blipId is already imported
6746 if ( nIdx_ && pEscherBlipCache )
6748 EscherBlipCacheEntry* pEntry;
6749 for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry;
6750 pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() )
6752 if ( pEntry->nBlip == nIdx_ )
6753 { /* if this entry is available, then it should be possible
6754 to get the Graphic via GraphicObject */
6755 GraphicObject aGraphicObject( pEntry->aUniqueID );
6756 rData = aGraphicObject.GetGraphic();
6757 if ( rData.GetType() != GRAPHIC_NONE )
6758 bOk = sal_True;
6759 else
6760 delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove();
6761 break;
6765 if ( !bOk )
6767 USHORT nIdx = USHORT( nIdx_ );
6768 if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return FALSE;
6770 // eventuell alte(s) Errorflag(s) loeschen
6771 if( rStCtrl.GetError() )
6772 rStCtrl.ResetError();
6773 if( ( &rStCtrl != pStData )
6774 && pStData->GetError() )
6775 pStData->ResetError();
6777 // FilePos des/der Stream(s) merken
6778 ULONG nOldPosCtrl = rStCtrl.Tell();
6779 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6781 // passende Info-Struct aus unserem Pointer Array nehmen
6782 SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ];
6784 // das BLIP Atom im Daten Stream anspringen
6785 pStData->Seek( rInfo.nFilePos );
6786 // ggfs. Fehlerstatus zuruecksetzen
6787 if( pStData->GetError() )
6788 pStData->ResetError();
6789 else
6790 bOk = GetBLIPDirect( *pStData, rData, pVisArea );
6791 if( pStData2 && !bOk )
6793 // Fehler, aber zweite Chance: es gibt noch einen zweiten
6794 // Datenstream, in dem die Grafik liegen koennte!
6795 if( pStData2->GetError() )
6796 pStData2->ResetError();
6797 ULONG nOldPosData2 = pStData2->Tell();
6798 // das BLIP Atom im zweiten Daten Stream anspringen
6799 pStData2->Seek( rInfo.nFilePos );
6800 // ggfs. Fehlerstatus zuruecksetzen
6801 if( pStData2->GetError() )
6802 pStData2->ResetError();
6803 else
6804 bOk = GetBLIPDirect( *pStData2, rData, pVisArea );
6805 // alte FilePos des zweiten Daten-Stream restaurieren
6806 pStData2->Seek( nOldPosData2 );
6808 // alte FilePos des/der Stream(s) restaurieren
6809 rStCtrl.Seek( nOldPosCtrl );
6810 if( &rStCtrl != pStData )
6811 pStData->Seek( nOldPosData );
6813 if ( bOk )
6815 // create new BlipCacheEntry for this graphic
6816 GraphicObject aGraphicObject( rData );
6817 if ( !pEscherBlipCache )
6818 const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List();
6819 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() );
6820 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND );
6824 return bOk;
6827 /* Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream)
6828 ---------------------------------
6829 ******************************************************************************/
6830 BOOL SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const
6832 ULONG nOldPos = rBLIPStream.Tell();
6834 int nRes = GRFILTER_OPENERROR; // Fehlervariable initialisieren
6836 // nachschauen, ob es sich auch wirklich um ein BLIP handelt
6837 UINT32 nLength;
6838 USHORT nInst, nFbt( 0 );
6839 BYTE nVer;
6840 if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) )
6842 Size aMtfSize100;
6843 BOOL bMtfBLIP = FALSE;
6844 BOOL bZCodecCompression = FALSE;
6845 // Nun exakt auf den Beginn der eingebetteten Grafik positionieren
6846 ULONG nSkip = ( nInst & 0x0001 ) ? 32 : 16;
6848 switch( nInst & 0xFFFE )
6850 case 0x216 : // Metafile header then compressed WMF
6851 case 0x3D4 : // Metafile header then compressed EMF
6852 case 0x542 : // Metafile hd. then compressed PICT
6854 rBLIPStream.SeekRel( nSkip + 20 );
6856 // read in size of metafile in EMUS
6857 rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height();
6859 // scale to 1/100mm
6860 aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360;
6862 if ( pVisArea ) // seem that we currently are skipping the visarea position
6863 *pVisArea = Rectangle( Point(), aMtfSize100 );
6865 // skip rest of header
6866 nSkip = 6;
6867 bMtfBLIP = bZCodecCompression = TRUE;
6869 break;
6870 case 0x46A : // One byte tag then JPEG (= JFIF) data
6871 case 0x6E0 : // One byte tag then PNG data
6872 case 0x7A8 :
6873 nSkip += 1; // One byte tag then DIB data
6874 break;
6876 rBLIPStream.SeekRel( nSkip );
6878 SvStream* pGrStream = &rBLIPStream;
6879 SvMemoryStream* pOut = NULL;
6880 if( bZCodecCompression )
6882 pOut = new SvMemoryStream( 0x8000, 0x4000 );
6883 ZCodec aZCodec( 0x8000, 0x8000 );
6884 aZCodec.BeginCompression();
6885 aZCodec.Decompress( rBLIPStream, *pOut );
6886 aZCodec.EndCompression();
6887 pOut->Seek( STREAM_SEEK_TO_BEGIN );
6888 pGrStream = pOut;
6891 //#define DBG_EXTRACTGRAPHICS
6892 #ifdef DBG_EXTRACTGRAPHICS
6894 static sal_Int32 nCount;
6896 String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) );
6897 aFileName.Append( String::CreateFromInt32( nCount++ ) );
6898 switch( nInst &~ 1 )
6900 case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break;
6901 case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break;
6902 case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break;
6903 case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
6904 case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break;
6905 case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break;
6908 String aURLStr;
6910 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
6912 INetURLObject aURL( aURLStr );
6914 aURL.removeSegment();
6915 aURL.removeFinalSlash();
6916 aURL.Append( aFileName );
6918 SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE );
6920 if( pDbgOut )
6922 if ( bZCodecCompression )
6924 pOut->Seek( STREAM_SEEK_TO_END );
6925 pDbgOut->Write( pOut->GetData(), pOut->Tell() );
6926 pOut->Seek( STREAM_SEEK_TO_BEGIN );
6928 else
6930 sal_Int32 nDbgLen = nLength - nSkip;
6931 if ( nDbgLen )
6933 sal_Char* pDat = new sal_Char[ nDbgLen ];
6934 pGrStream->Read( pDat, nDbgLen );
6935 pDbgOut->Write( pDat, nDbgLen );
6936 pGrStream->SeekRel( -nDbgLen );
6937 delete[] pDat;
6941 delete pDbgOut;
6944 #endif
6946 if( ( nInst & 0xFFFE ) == 0x7A8 )
6947 { // DIBs direkt holen
6948 Bitmap aNew;
6949 if( aNew.Read( *pGrStream, FALSE ) )
6951 rData = Graphic( aNew );
6952 nRes = GRFILTER_OK;
6955 else
6956 { // und unsere feinen Filter darauf loslassen
6957 GraphicFilter* pGF = GetGrfFilter();
6958 String aEmptyStr;
6959 nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW );
6961 // SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems,
6962 // then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the
6963 // scaling has been implemented does not happen anymore.
6965 // For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the
6966 // dxarray is empty (this has been solved in wmf/emf but not for pict)
6967 if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) )
6969 if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) )
6970 { // #75956#, scaling does not work properly, if the graphic is less than 1cm
6971 GDIMetaFile aMtf( rData.GetGDIMetaFile() );
6972 const Size aOldSize( aMtf.GetPrefSize() );
6974 if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) &&
6975 aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) )
6977 aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(),
6978 (double) aMtfSize100.Height() / aOldSize.Height() );
6979 aMtf.SetPrefSize( aMtfSize100 );
6980 aMtf.SetPrefMapMode( MAP_100TH_MM );
6981 rData = aMtf;
6986 // ggfs. Fehlerstatus zuruecksetzen
6987 if ( ERRCODE_IO_PENDING == pGrStream->GetError() )
6988 pGrStream->ResetError();
6989 delete pOut;
6991 rBLIPStream.Seek( nOldPos ); // alte FilePos des Streams restaurieren
6993 return ( GRFILTER_OK == nRes ); // Ergebniss melden
6996 /* static */
6997 BOOL SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn)
6999 rRec.nFilePos = rIn.Tell();
7000 return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer,
7001 rRec.nRecInstance,
7002 rRec.nRecType,
7003 rRec.nRecLen );
7007 /* auch static */
7008 BOOL SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt,
7009 BYTE& rVer,
7010 USHORT& rInst,
7011 USHORT& rFbt,
7012 UINT32& rLength )
7014 sal_uInt16 nTmp;
7015 rSt >> nTmp >> rFbt >> rLength;
7016 rVer = sal::static_int_cast< BYTE >(nTmp & 15);
7017 rInst = nTmp >> 4;
7018 return rSt.GetError() == 0;
7024 BOOL SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, ULONG nDatLen,
7025 char*& rpBuff, UINT32& rBuffLen ) const
7027 if( nDatLen )
7029 rpBuff = new char[ nDatLen ];
7030 rBuffLen = nDatLen;
7031 rStData.Read( rpBuff, nDatLen );
7033 return TRUE;
7036 BOOL SvxMSDffManager::ProcessClientData(SvStream& rStData, ULONG nDatLen,
7037 char*& rpBuff, UINT32& rBuffLen ) const
7039 if( nDatLen )
7041 rpBuff = new char[ nDatLen ];
7042 rBuffLen = nDatLen;
7043 rStData.Read( rpBuff, nDatLen );
7045 return TRUE;
7049 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ )
7051 return; // wird von SJ im Draw ueberladen
7054 ULONG SvxMSDffManager::Calc_nBLIPPos( ULONG nOrgVal, ULONG /* nStreamPos */ ) const
7056 return nOrgVal;
7059 BOOL SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const
7061 return FALSE;
7064 BOOL SvxMSDffManager::ShapeHasText( ULONG /* nShapeId */, ULONG /* nFilePos */ ) const
7066 return TRUE;
7069 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup>
7070 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId,
7071 const Graphic& rGrf,
7072 const Rectangle& rBoundRect,
7073 const Rectangle& rVisArea,
7074 const int /* _nCalledByGroup */,
7075 sal_Int64 nAspect ) const
7076 // <--
7078 SdrObject* pRet = 0;
7079 String sStorageName;
7080 SvStorageRef xSrcStg;
7081 ErrCode nError = ERRCODE_NONE;
7082 uno::Reference < embed::XStorage > xDstStg;
7083 if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
7084 pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg,
7085 rGrf, rBoundRect, rVisArea, pStData, nError,
7086 nSvxMSDffOLEConvFlags, nAspect );
7087 return pRet;
7090 const GDIMetaFile* SvxMSDffManager::lcl_GetMetaFileFromGrf_Impl( const Graphic& rGrf,
7091 GDIMetaFile& rMtf )
7093 const GDIMetaFile* pMtf;
7094 if( GRAPHIC_BITMAP == rGrf.GetType() )
7096 Point aPt;
7097 const Size aSz(lcl_GetPrefSize(rGrf, MAP_100TH_MM));
7099 VirtualDevice aVirtDev;
7100 aVirtDev.EnableOutput( FALSE );
7101 MapMode aMM(MAP_100TH_MM);
7102 aVirtDev.SetMapMode( aMM );
7104 rMtf.Record( &aVirtDev );
7105 rGrf.Draw( &aVirtDev, aPt, aSz );
7106 rMtf.Stop();
7107 rMtf.SetPrefMapMode(aMM);
7108 rMtf.SetPrefSize( aSz );
7110 pMtf = &rMtf;
7112 else
7113 pMtf = &rGrf.GetGDIMetaFile();
7114 return pMtf;
7117 BOOL SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf )
7119 String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) );
7120 SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream );
7121 xStm->SetVersion( pStor->GetVersion() );
7122 xStm->SetBufferSize( 8192 );
7124 USHORT nAspect = ASPECT_CONTENT;
7125 ULONG nAdviseModes = 2;
7127 Impl_OlePres aEle( FORMAT_GDIMETAFILE );
7128 // Die Groesse in 1/100 mm umrechnen
7129 // Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird,
7130 // versucht SV einen BestMatchden richtigen Wert zu raten.
7131 Size aSize = rMtf.GetPrefSize();
7132 MapMode aMMSrc = rMtf.GetPrefMapMode();
7133 MapMode aMMDst( MAP_100TH_MM );
7134 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
7135 aEle.SetSize( aSize );
7136 aEle.SetAspect( nAspect );
7137 aEle.SetAdviseFlags( nAdviseModes );
7138 aEle.SetMtf( rMtf );
7139 aEle.Write( *xStm );
7141 xStm->SetBufferSize( 0 );
7142 return xStm->GetError() == SVSTREAM_OK;
7145 struct ClsIDs {
7146 UINT32 nId;
7147 const sal_Char* pSvrName;
7148 const sal_Char* pDspName;
7150 static ClsIDs aClsIDs[] = {
7152 { 0x000212F0, "MSWordArt", "Microsoft Word Art" },
7153 { 0x000212F0, "MSWordArt.2", "Microsoft Word Art 2.0" },
7155 // MS Apps
7156 { 0x00030000, "ExcelWorksheet", "Microsoft Excel Worksheet" },
7157 { 0x00030001, "ExcelChart", "Microsoft Excel Chart" },
7158 { 0x00030002, "ExcelMacrosheet", "Microsoft Excel Macro" },
7159 { 0x00030003, "WordDocument", "Microsoft Word Document" },
7160 { 0x00030004, "MSPowerPoint", "Microsoft PowerPoint" },
7161 { 0x00030005, "MSPowerPointSho", "Microsoft PowerPoint Slide Show"},
7162 { 0x00030006, "MSGraph", "Microsoft Graph" },
7163 { 0x00030007, "MSDraw", "Microsoft Draw" },
7164 { 0x00030008, "Note-It", "Microsoft Note-It" },
7165 { 0x00030009, "WordArt", "Microsoft Word Art" },
7166 { 0x0003000a, "PBrush", "Microsoft PaintBrush Picture" },
7167 { 0x0003000b, "Equation", "Microsoft Equation Editor" },
7168 { 0x0003000c, "Package", "Package" },
7169 { 0x0003000d, "SoundRec", "Sound" },
7170 { 0x0003000e, "MPlayer", "Media Player" },
7171 // MS Demos
7172 { 0x0003000f, "ServerDemo", "OLE 1.0 Server Demo" },
7173 { 0x00030010, "Srtest", "OLE 1.0 Test Demo" },
7174 { 0x00030011, "SrtInv", "OLE 1.0 Inv Demo" },
7175 { 0x00030012, "OleDemo", "OLE 1.0 Demo" },
7177 // Coromandel / Dorai Swamy / 718-793-7963
7178 { 0x00030013, "CoromandelIntegra", "Coromandel Integra" },
7179 { 0x00030014, "CoromandelObjServer","Coromandel Object Server" },
7181 // 3-d Visions Corp / Peter Hirsch / 310-325-1339
7182 { 0x00030015, "StanfordGraphics", "Stanford Graphics" },
7184 // Deltapoint / Nigel Hearne / 408-648-4000
7185 { 0x00030016, "DGraphCHART", "DeltaPoint Graph Chart" },
7186 { 0x00030017, "DGraphDATA", "DeltaPoint Graph Data" },
7188 // Corel / Richard V. Woodend / 613-728-8200 x1153
7189 { 0x00030018, "PhotoPaint", "Corel PhotoPaint" },
7190 { 0x00030019, "CShow", "Corel Show" },
7191 { 0x0003001a, "CorelChart", "Corel Chart" },
7192 { 0x0003001b, "CDraw", "Corel Draw" },
7194 // Inset Systems / Mark Skiba / 203-740-2400
7195 { 0x0003001c, "HJWIN1.0", "Inset Systems" },
7197 // Mark V Systems / Mark McGraw / 818-995-7671
7198 { 0x0003001d, "ObjMakerOLE", "MarkV Systems Object Maker" },
7200 // IdentiTech / Mike Gilger / 407-951-9503
7201 { 0x0003001e, "FYI", "IdentiTech FYI" },
7202 { 0x0003001f, "FYIView", "IdentiTech FYI Viewer" },
7204 // Inventa Corporation / Balaji Varadarajan / 408-987-0220
7205 { 0x00030020, "Stickynote", "Inventa Sticky Note" },
7207 // ShapeWare Corp. / Lori Pearce / 206-467-6723
7208 { 0x00030021, "ShapewareVISIO10", "Shapeware Visio 1.0" },
7209 { 0x00030022, "ImportServer", "Spaheware Import Server" },
7211 // test app SrTest
7212 { 0x00030023, "SrvrTest", "OLE 1.0 Server Test" },
7214 // test app ClTest. Doesn't really work as a server but is in reg db
7215 { 0x00030025, "Cltest", "OLE 1.0 Client Test" },
7217 // Microsoft ClipArt Gallery Sherry Larsen-Holmes
7218 { 0x00030026, "MS_ClipArt_Gallery", "Microsoft ClipArt Gallery" },
7219 // Microsoft Project Cory Reina
7220 { 0x00030027, "MSProject", "Microsoft Project" },
7222 // Microsoft Works Chart
7223 { 0x00030028, "MSWorksChart", "Microsoft Works Chart" },
7225 // Microsoft Works Spreadsheet
7226 { 0x00030029, "MSWorksSpreadsheet", "Microsoft Works Spreadsheet" },
7228 // AFX apps - Dean McCrory
7229 { 0x0003002A, "MinSvr", "AFX Mini Server" },
7230 { 0x0003002B, "HierarchyList", "AFX Hierarchy List" },
7231 { 0x0003002C, "BibRef", "AFX BibRef" },
7232 { 0x0003002D, "MinSvrMI", "AFX Mini Server MI" },
7233 { 0x0003002E, "TestServ", "AFX Test Server" },
7235 // Ami Pro
7236 { 0x0003002F, "AmiProDocument", "Ami Pro Document" },
7238 // WordPerfect Presentations For Windows
7239 { 0x00030030, "WPGraphics", "WordPerfect Presentation" },
7240 { 0x00030031, "WPCharts", "WordPerfect Chart" },
7242 // MicroGrafx Charisma
7243 { 0x00030032, "Charisma", "MicroGrafx Charisma" },
7244 { 0x00030033, "Charisma_30", "MicroGrafx Charisma 3.0" },
7245 { 0x00030034, "CharPres_30", "MicroGrafx Charisma 3.0 Pres" },
7246 // MicroGrafx Draw
7247 { 0x00030035, "Draw", "MicroGrafx Draw" },
7248 // MicroGrafx Designer
7249 { 0x00030036, "Designer_40", "MicroGrafx Designer 4.0" },
7251 // STAR DIVISION
7252 // { 0x000424CA, "StarMath", "StarMath 1.0" },
7253 { 0x00043AD2, "FontWork", "Star FontWork" },
7254 // { 0x000456EE, "StarMath2", "StarMath 2.0" },
7256 { 0, "", "" } };
7259 BOOL SvxMSDffManager::ConvertToOle2( SvStream& rStm, UINT32 nReadLen,
7260 const GDIMetaFile * pMtf, const SotStorageRef& rDest )
7262 BOOL bMtfRead = FALSE;
7263 SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ),
7264 STREAM_WRITE| STREAM_SHARE_DENYALL );
7265 if( xOle10Stm->GetError() )
7266 return FALSE;
7268 UINT32 nType;
7269 UINT32 nRecType;
7270 UINT32 nStrLen;
7271 String aSvrName;
7272 UINT32 nDummy0;
7273 UINT32 nDummy1;
7274 UINT32 nDataLen;
7275 BYTE * pData;
7276 UINT32 nBytesRead = 0;
7279 rStm >> nType;
7280 rStm >> nRecType;
7281 rStm >> nStrLen;
7282 if( nStrLen )
7284 if( 0x10000L > nStrLen )
7286 sal_Char * pBuf = new sal_Char[ nStrLen ];
7287 rStm.Read( pBuf, nStrLen );
7288 aSvrName.Assign( String( pBuf, (USHORT) nStrLen-1, gsl_getSystemTextEncoding() ) );
7289 delete[] pBuf;
7291 else
7292 break;
7294 rStm >> nDummy0;
7295 rStm >> nDummy1;
7296 rStm >> nDataLen;
7298 nBytesRead += 6 * sizeof( UINT32 ) + nStrLen + nDataLen;
7300 if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen )
7302 if( xOle10Stm.Is() )
7304 pData = new BYTE[ nDataLen ];
7305 if( !pData )
7306 return FALSE;
7308 rStm.Read( pData, nDataLen );
7310 // write to ole10 stream
7311 *xOle10Stm << nDataLen;
7312 xOle10Stm->Write( pData, nDataLen );
7313 xOle10Stm = SotStorageStreamRef();
7315 // set the compobj stream
7316 ClsIDs* pIds;
7317 for( pIds = aClsIDs; pIds->nId; pIds++ )
7319 if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) )
7320 break;
7322 // SvGlobalName* pClsId = NULL;
7323 String aShort, aFull;
7324 if( pIds->nId )
7326 // gefunden!
7327 ULONG nCbFmt = SotExchange::RegisterFormatName( aSvrName );
7328 rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt,
7329 String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) );
7331 else
7333 ULONG nCbFmt = SotExchange::RegisterFormatName( aSvrName );
7334 rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName );
7337 delete[] pData;
7339 else if( nRecType == 5 && !pMtf )
7341 ULONG nPos = rStm.Tell();
7342 UINT16 sz[4];
7343 rStm.Read( sz, 8 );
7344 //rStm.SeekRel( 8 );
7345 Graphic aGraphic;
7346 if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() )
7348 const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
7349 MakeContentStream( rDest, rMtf );
7350 bMtfRead = TRUE;
7352 // set behind the data
7353 rStm.Seek( nPos + nDataLen );
7355 else
7356 rStm.SeekRel( nDataLen );
7358 } while( !rStm.IsEof() && nReadLen >= nBytesRead );
7360 if( !bMtfRead && pMtf )
7362 MakeContentStream( rDest, *pMtf );
7363 return TRUE;
7366 return FALSE;
7369 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName )
7371 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 )
7372 || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
7373 return "swriter";
7374 else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 )
7375 || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
7376 return "scalc";
7377 else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 )
7378 || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
7379 return "simpress";
7380 else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 )
7381 || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
7382 return "sdraw";
7383 else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 )
7384 || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
7385 return "smath";
7386 else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 )
7387 || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
7388 return "schart";
7389 return 0;
7392 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
7394 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) )
7395 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) );
7397 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
7398 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) );
7400 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) )
7401 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) );
7403 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
7404 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) );
7406 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
7407 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) );
7409 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
7410 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) );
7412 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
7413 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) );
7415 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
7416 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) );
7418 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) )
7419 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) );
7421 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
7422 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) );
7424 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
7425 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) );
7427 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
7428 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) );
7430 return ::rtl::OUString();
7433 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > SvxMSDffManager::CheckForConvertToSOObj( UINT32 nConvertFlags,
7434 SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage,
7435 const Graphic& rGrf,
7436 const Rectangle& rVisArea )
7438 uno::Reference < embed::XEmbeddedObject > xObj;
7439 SvGlobalName aStgNm = rSrcStg.GetClassName();
7440 const char* pName = GetInternalServerName_Impl( aStgNm );
7441 String sStarName;
7442 if ( pName )
7443 sStarName = String::CreateFromAscii( pName );
7444 else if ( nConvertFlags )
7446 static struct _ObjImpType
7448 UINT32 nFlag;
7449 const char* pFactoryNm;
7450 // GlobalNameId
7451 UINT32 n1;
7452 USHORT n2, n3;
7453 BYTE b8, b9, b10, b11, b12, b13, b14, b15;
7454 } aArr[] = {
7455 { OLE_MATHTYPE_2_STARMATH, "smath",
7456 0x0002ce02L, 0x0000, 0x0000,
7457 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7458 { OLE_MATHTYPE_2_STARMATH, "smath",
7459 0x00021700L, 0x0000, 0x0000,
7460 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7461 { OLE_WINWORD_2_STARWRITER, "swriter",
7462 0x00020906L, 0x0000, 0x0000,
7463 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7464 { OLE_EXCEL_2_STARCALC, "scalc", // Excel table
7465 0x00020810L, 0x0000, 0x0000,
7466 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7467 { OLE_EXCEL_2_STARCALC, "scalc", // Excel chart
7468 0x00020820L, 0x0000, 0x0000,
7469 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7470 // 114465: additional Excel OLE chart classId to above.
7471 { OLE_EXCEL_2_STARCALC, "scalc",
7472 0x00020821L, 0x0000, 0x0000,
7473 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7474 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint presentation
7475 0x64818d10L, 0x4f9b, 0x11cf,
7476 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7477 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint slide
7478 0x64818d11L, 0x4f9b, 0x11cf,
7479 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7480 { 0, 0,
7481 0, 0, 0,
7482 0, 0, 0, 0, 0, 0, 0, 0 }
7485 for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr )
7487 if( nConvertFlags & pArr->nFlag )
7489 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3,
7490 pArr->b8, pArr->b9, pArr->b10, pArr->b11,
7491 pArr->b12, pArr->b13, pArr->b14, pArr->b15 );
7493 if ( aStgNm == aTypeName )
7495 sStarName = String::CreateFromAscii( pArr->pFactoryNm );
7496 break;
7502 if ( sStarName.Len() )
7504 //TODO/MBA: check if (and when) storage and stream will be destroyed!
7505 const SfxFilter* pFilter = 0;
7506 SvMemoryStream* pStream = new SvMemoryStream;
7507 if ( pName )
7509 // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also
7510 SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ );
7511 *xStr >> *pStream;
7513 else
7515 SfxFilterMatcher aMatch( sStarName );
7516 SotStorageRef xStorage = new SotStorage( FALSE, *pStream );
7517 rSrcStg.CopyTo( xStorage );
7518 xStorage->Commit();
7519 xStorage.Clear();
7520 String aType = SfxFilter::GetTypeFromStorage( rSrcStg );
7521 if ( aType.Len() )
7522 pFilter = aMatch.GetFilter4EA( aType );
7525 //#define DBG_EXTRACTOLESTREAMS
7526 #ifdef DBG_EXTRACTOLESTREAMS
7527 static sal_Int32 nCount(0);
7528 String aTmpName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("/tmp/embedded_stream_")));
7529 aTmpName += String::CreateFromInt32(nCount++);
7530 aTmpName += String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(".bin"));
7531 SvFileStream aTmpStream(aTmpName,STREAM_READ|STREAM_WRITE|STREAM_TRUNC);
7532 pStream->Seek(0);
7533 *pStream >> aTmpStream;
7534 aTmpStream.Close();
7535 #endif
7537 if ( pName || pFilter )
7539 //Reuse current ole name
7540 String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7541 aDstStgName += String::CreateFromInt32(nMSOleObjCntr);
7543 ::rtl::OUString aFilterName;
7544 if ( pFilter )
7545 aFilterName = pFilter->GetName();
7546 else
7547 aFilterName = GetFilterNameFromClassID_Impl( aStgNm );
7549 uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2);
7550 aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
7551 uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream );
7552 aMedium[0].Value <<= xStream;
7553 aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
7554 aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
7556 if ( aFilterName.getLength() )
7558 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
7559 aMedium[2].Value <<= aFilterName;
7562 ::rtl::OUString aName( aDstStgName );
7563 comphelper::EmbeddedObjectContainer aCnt( rDestStorage );
7564 xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7566 if ( !xObj.is() )
7568 if( aFilterName.getLength() )
7570 // throw the filter parameter away as workaround
7571 aMedium.realloc( 2 );
7572 xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7575 if ( !xObj.is() )
7576 return xObj;
7579 // TODO/LATER: ViewAspect must be passed from outside!
7580 sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT;
7582 // JP 26.10.2001: Bug 93374 / 91928 the writer
7583 // objects need the correct visarea needs the
7584 // correct visarea, but this is not true for
7585 // PowerPoint (see bugdoc 94908b)
7586 // SJ: 19.11.2001 bug 94908, also chart objects
7587 // needs the correct visarea
7589 // If pName is set this is an own embedded object, it should have the correct size internally
7590 // TODO/LATER: it might make sence in future to set the size stored in internal object
7591 if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) )
7593 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) );
7594 Size aSz;
7595 if ( rVisArea.IsEmpty() )
7596 aSz = lcl_GetPrefSize(rGrf, aMapMode );
7597 else
7599 aSz = rVisArea.GetSize();
7600 aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode );
7603 // don't modify the object
7604 //TODO/LATER: remove those hacks, that needs to be done differently!
7605 //xIPObj->EnableSetModified( FALSE );
7606 awt::Size aSize;
7607 aSize.Width = aSz.Width();
7608 aSize.Height = aSz.Height();
7609 xObj->setVisualAreaSize( nViewAspect, aSize );
7610 //xIPObj->EnableSetModified( TRUE );
7612 else if ( sStarName.EqualsAscii( "smath" ) )
7613 { // SJ: force the object to recalc its visarea
7614 //TODO/LATER: wait for PrinterChangeNotification
7615 //xIPObj->OnDocumentPrinterChanged( NULL );
7620 return xObj;
7623 // TODO/MBA: code review and testing!
7624 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage(
7625 const String& rStorageName,
7626 SotStorageRef& rSrcStorage,
7627 const uno::Reference < embed::XStorage >& xDestStorage,
7628 const Graphic& rGrf,
7629 const Rectangle& rBoundRect,
7630 const Rectangle& rVisArea,
7631 SvStream* pDataStrm,
7632 ErrCode& rError,
7633 UINT32 nConvertFlags,
7634 sal_Int64 nReccomendedAspect )
7636 sal_Int64 nAspect = nReccomendedAspect;
7637 SdrOle2Obj* pRet = 0;
7638 if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() )
7640 comphelper::EmbeddedObjectContainer aCnt( xDestStorage );
7641 // Ist der 01Ole-Stream ueberhaupt vorhanden ?
7642 // ( ist er z.B. bei FontWork nicht )
7643 // Wenn nicht -> Einbindung als Grafik
7644 BOOL bValidStorage = FALSE;
7645 String aDstStgName( String::CreateFromAscii(
7646 RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7648 aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr );
7651 SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName,
7652 STREAM_READWRITE| STREAM_SHARE_DENYALL );
7653 if( xObjStg.Is() )
7656 BYTE aTestA[10]; // exist the \1CompObj-Stream ?
7657 SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream(
7658 String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"),
7659 RTL_TEXTENCODING_MS_1252 ));
7660 bValidStorage = xSrcTst.Is() && sizeof( aTestA ) ==
7661 xSrcTst->Read( aTestA, sizeof( aTestA ) );
7662 if( !bValidStorage )
7664 // or the \1Ole-Stream ?
7665 xSrcTst = xObjStg->OpenSotStream(
7666 String(RTL_CONSTASCII_STRINGPARAM("\1Ole"),
7667 RTL_TEXTENCODING_MS_1252 ));
7668 bValidStorage = xSrcTst.Is() && sizeof(aTestA) ==
7669 xSrcTst->Read(aTestA, sizeof(aTestA));
7673 if( bValidStorage )
7675 if ( nAspect != embed::Aspects::MSOLE_ICON )
7677 // check whether the object is iconified one
7678 // usually this information is already known, the only exception
7679 // is a kind of embedded objects in Word documents
7680 // TODO/LATER: should the caller be notified if the aspect changes in future?
7682 SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream(
7683 String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ),
7684 STREAM_STD_READ | STREAM_NOCREATE );
7685 if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
7687 BYTE nByte = 0;
7688 *xObjInfoSrc >> nByte;
7689 if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
7690 nAspect = embed::Aspects::MSOLE_ICON;
7694 uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj(
7695 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea ));
7696 if ( xObj.is() )
7698 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7700 // TODO/LATER: need MediaType
7701 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7703 // TODO/MBA: check setting of PersistName
7704 pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false);
7705 // we have the Object, don't create another
7706 bValidStorage = false;
7712 if( bValidStorage )
7714 // object is not an own object
7715 SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE );
7717 if ( xObjStor.Is() )
7719 SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ );
7720 xSrcStor->CopyTo( xObjStor );
7722 if( !xObjStor->GetError() )
7723 xObjStor->Commit();
7725 if( xObjStor->GetError() )
7727 rError = xObjStor->GetError();
7728 bValidStorage = FALSE;
7730 else if( !xObjStor.Is() )
7731 bValidStorage = FALSE;
7734 else if( pDataStrm )
7736 UINT32 nLen, nDummy;
7737 *pDataStrm >> nLen >> nDummy;
7738 if( SVSTREAM_OK != pDataStrm->GetError() ||
7739 // Id in BugDoc - exist there other Ids?
7740 // The ConvertToOle2 - does not check for consistent
7741 0x30008 != nDummy )
7742 bValidStorage = FALSE;
7743 else
7745 // or is it an OLE-1 Stream in the DataStream?
7746 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName );
7747 //TODO/MBA: remove metafile conversion from ConvertToOle2
7748 //when is this code used?!
7749 GDIMetaFile aMtf;
7750 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor );
7751 xObjStor->Commit();
7755 if( bValidStorage )
7757 uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName );
7758 if( xObj.is() )
7760 // the visual area must be retrieved from the metafile (object doesn't know it so far)
7762 if ( nAspect != embed::Aspects::MSOLE_ICON )
7764 // working with visual area can switch the object to running state
7765 awt::Size aAwtSz;
7768 // the provided visual area should be used, if there is any
7769 if ( rVisArea.IsEmpty() )
7771 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
7772 Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit)));
7773 aAwtSz.Width = aSz.Width();
7774 aAwtSz.Height = aSz.Height();
7776 else
7778 aAwtSz.Width = rVisArea.GetWidth();
7779 aAwtSz.Height = rVisArea.GetHeight();
7781 //xInplaceObj->EnableSetModified( FALSE );
7782 xObj->setVisualAreaSize( nAspect, aAwtSz );
7783 //xInplaceObj->EnableSetModified( TRUE );*/
7785 catch( uno::Exception& )
7787 OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" );
7791 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7793 // TODO/LATER: need MediaType
7794 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7796 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false);
7801 return pRet;
7804 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const
7806 SdrObject* pRet = NULL;
7808 if(120 >= UINT16(eTyp))
7810 pRet = new SdrRectObj();
7813 DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM");
7815 return pRet;
7818 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
7819 const String& rPropName, sal_Bool bTestPropertyAvailability )
7821 sal_Bool bRetValue = sal_True;
7822 if ( bTestPropertyAvailability )
7824 bRetValue = sal_False;
7827 uno::Reference< beans::XPropertySetInfo >
7828 aXPropSetInfo( rXPropSet->getPropertySetInfo() );
7829 if ( aXPropSetInfo.is() )
7830 bRetValue = aXPropSetInfo->hasPropertyByName( rPropName );
7832 catch( uno::Exception& )
7834 bRetValue = sal_False;
7837 if ( bRetValue )
7841 rXPropSet->setPropertyValue( rPropName, rAny );
7842 bRetValue = sal_True;
7844 catch( uno::Exception& )
7846 bRetValue = sal_False;
7849 return bRetValue;
7852 SvxMSDffImportRec::SvxMSDffImportRec()
7853 : pObj( 0 ),
7854 pWrapPolygon(0),
7855 pClientAnchorBuffer( 0 ),
7856 nClientAnchorLen( 0 ),
7857 pClientDataBuffer( 0 ),
7858 nClientDataLen( 0 ),
7859 nXAlign( 0 ), // position n cm from left
7860 nXRelTo( 2 ), // relative to column
7861 nYAlign( 0 ), // position n cm below
7862 nYRelTo( 2 ), // relative to paragraph
7863 nLayoutInTableCell( 0 ), // element is laid out in table cell
7864 nTextRotationAngle( 0 ),
7865 nDxTextLeft( 144 ),
7866 nDyTextTop( 72 ),
7867 nDxTextRight( 144 ),
7868 nDyTextBottom( 72 ),
7869 nDxWrapDistLeft( 0 ),
7870 nDyWrapDistTop( 0 ),
7871 nDxWrapDistRight( 0 ),
7872 nDyWrapDistBottom(0 ),
7873 nCropFromTop( 0 ),
7874 nCropFromBottom( 0 ),
7875 nCropFromLeft( 0 ),
7876 nCropFromRight( 0 ),
7877 aTextId( 0, 0 ),
7878 nNextShapeId( 0 ),
7879 nShapeId( 0 ),
7880 eShapeType( mso_sptNil )
7882 eLineStyle = mso_lineSimple; // GPF-Bug #66227#
7883 bDrawHell = FALSE;
7884 bHidden = FALSE;
7885 // bInGroup = FALSE;
7886 bReplaceByFly = FALSE;
7887 bLastBoxInChain = TRUE;
7888 bHasUDefProp = FALSE; // was the DFF_msofbtUDefProp record set?
7889 bVFlip = FALSE;
7890 bHFlip = FALSE;
7891 bAutoWidth = FALSE;
7894 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy)
7895 : pObj( rCopy.pObj ),
7896 nXAlign( rCopy.nXAlign ),
7897 nXRelTo( rCopy.nXRelTo ),
7898 nYAlign( rCopy.nYAlign ),
7899 nYRelTo( rCopy.nYRelTo ),
7900 nLayoutInTableCell( rCopy.nLayoutInTableCell ),
7901 nTextRotationAngle( rCopy.nTextRotationAngle ),
7902 nDxTextLeft( rCopy.nDxTextLeft ),
7903 nDyTextTop( rCopy.nDyTextTop ),
7904 nDxTextRight( rCopy.nDxTextRight ),
7905 nDyTextBottom( rCopy.nDyTextBottom ),
7906 nDxWrapDistLeft( rCopy.nDxWrapDistLeft ),
7907 nDyWrapDistTop( rCopy.nDyWrapDistTop ),
7908 nDxWrapDistRight( rCopy.nDxWrapDistRight ),
7909 nDyWrapDistBottom(rCopy.nDyWrapDistBottom ),
7910 nCropFromTop( rCopy.nCropFromTop ),
7911 nCropFromBottom( rCopy.nCropFromBottom ),
7912 nCropFromLeft( rCopy.nCropFromLeft ),
7913 nCropFromRight( rCopy.nCropFromRight ),
7914 aTextId( rCopy.aTextId ),
7915 nNextShapeId( rCopy.nNextShapeId ),
7916 nShapeId( rCopy.nShapeId ),
7917 eShapeType( rCopy.eShapeType )
7919 eLineStyle = rCopy.eLineStyle; // GPF-Bug #66227#
7920 bDrawHell = rCopy.bDrawHell;
7921 bHidden = rCopy.bHidden;
7922 // bInGroup = rCopy.bInGroup;
7923 bReplaceByFly = rCopy.bReplaceByFly;
7924 bAutoWidth = rCopy.bAutoWidth;
7925 bLastBoxInChain = rCopy.bLastBoxInChain;
7926 bHasUDefProp = rCopy.bHasUDefProp;
7927 bVFlip = rCopy.bVFlip;
7928 bHFlip = rCopy.bHFlip;
7929 nClientAnchorLen = rCopy.nClientAnchorLen;
7930 if( rCopy.nClientAnchorLen )
7932 pClientAnchorBuffer = new char[ nClientAnchorLen ];
7933 memcpy( pClientAnchorBuffer,
7934 rCopy.pClientAnchorBuffer,
7935 nClientAnchorLen );
7937 else
7938 pClientAnchorBuffer = 0;
7940 nClientDataLen = rCopy.nClientDataLen;
7941 if( rCopy.nClientDataLen )
7943 pClientDataBuffer = new char[ nClientDataLen ];
7944 memcpy( pClientDataBuffer,
7945 rCopy.pClientDataBuffer,
7946 nClientDataLen );
7948 else
7949 pClientDataBuffer = 0;
7951 if (rCopy.pWrapPolygon)
7952 pWrapPolygon = new Polygon(*rCopy.pWrapPolygon);
7953 else
7954 pWrapPolygon = 0;
7957 SvxMSDffImportRec::~SvxMSDffImportRec()
7959 if (pClientAnchorBuffer)
7960 delete[] pClientAnchorBuffer;
7961 if (pClientDataBuffer)
7962 delete[] pClientDataBuffer;
7963 if (pWrapPolygon)
7964 delete pWrapPolygon;
7967 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
7969 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape )
7971 maShapeIdContainer[nShapeId] = pShape;
7974 void SvxMSDffManager::removeShapeId( SdrObject* pShape )
7976 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() );
7977 const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() );
7978 while( aIter != aEnd )
7980 if( (*aIter).second == pShape )
7982 maShapeIdContainer.erase( aIter );
7983 break;
7988 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId )
7990 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) );
7991 return aIter != maShapeIdContainer.end() ? (*aIter).second : 0;