update dev300-m58
[ooovba.git] / svx / source / msfilter / msdffimp.cxx
blob42e7464751e740b0d7056765a6be78107c74474e
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 "gallery.hxx"
172 #include <com/sun/star/drawing/ShadeMode.hpp>
173 #include <svtools/itempool.hxx>
174 #include <vcl/svapp.hxx>
175 #include <svx/svx3ditems.hxx>
176 #include <svx/svdoashp.hxx>
177 #include <svx/sdasaitm.hxx>
178 #ifndef _UCBHELPER_CONTENT_HXX_
179 #include <ucbhelper/content.hxx>
180 #endif
181 #ifndef _UCBHELPER_CONTENTBROKER_HXX_
182 #include <ucbhelper/contentbroker.hxx>
183 #endif
184 #include <vos/xception.hxx>
185 #ifndef _VOS_NO_NAMESPACE
186 using namespace vos;
187 #endif
188 #include "../customshapes/EnhancedCustomShapeTypeNames.hxx"
189 #include "../customshapes/EnhancedCustomShapeGeometry.hxx"
190 #include <com/sun/star/drawing/EnhancedCustomShapeParameterPair.hpp>
191 #include <com/sun/star/drawing/EnhancedCustomShapeParameterType.hpp>
192 #include <com/sun/star/drawing/EnhancedCustomShapeSegment.hpp>
193 #include <com/sun/star/drawing/EnhancedCustomShapeGluePointType.hpp>
194 #include <com/sun/star/drawing/EnhancedCustomShapeSegmentCommand.hpp>
195 #include <com/sun/star/drawing/EnhancedCustomShapeTextFrame.hpp>
196 #include <com/sun/star/drawing/EnhancedCustomShapeAdjustmentValue.hpp>
197 #include <com/sun/star/drawing/EnhancedCustomShapeTextPathMode.hpp>
198 #ifndef __com_sun_star_beans_PropertyValues_hpp__
199 #include <com/sun/star/beans/PropertyValues.hpp>
200 #endif
201 #include <com/sun/star/drawing/ProjectionMode.hpp>
202 #include "../customshapes/EnhancedCustomShape2d.hxx"
204 using namespace ::com::sun::star ;
205 using namespace ::com::sun::star::drawing;
206 using namespace uno ;
207 using namespace beans ;
208 using namespace drawing ;
209 using namespace container ;
211 #define ITEMVALUE(ItemSet,Id,Cast) ((const Cast&)(ItemSet).Get(Id)).GetValue()
213 // static counter for OLE-Objects
214 static sal_uInt32 nMSOleObjCntr = 0;
215 #define MSO_OLE_Obj "MSO_OLE_Obj"
218 /*************************************************************************/
219 BOOL Impl_OlePres::Read( SvStream & rStm )
221 ULONG nBeginPos = rStm.Tell();
222 INT32 n;
223 rStm >> n;
224 if( n != -1 )
226 pBmp = new Bitmap;
227 rStm >> *pBmp;
228 if( rStm.GetError() == SVSTREAM_OK )
230 nFormat = FORMAT_BITMAP;
231 aSize = pBmp->GetPrefSize();
232 MapMode aMMSrc;
233 if( !aSize.Width() || !aSize.Height() )
235 // letzte Chance
236 aSize = pBmp->GetSizePixel();
237 aMMSrc = MAP_PIXEL;
239 else
240 aMMSrc = pBmp->GetPrefMapMode();
241 MapMode aMMDst( MAP_100TH_MM );
242 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
243 return TRUE;
245 else
247 delete pBmp;
248 pBmp = NULL;
250 pMtf = new GDIMetaFile();
251 rStm.ResetError();
252 rStm >> *pMtf;
253 if( rStm.GetError() == SVSTREAM_OK )
255 nFormat = FORMAT_GDIMETAFILE;
256 aSize = pMtf->GetPrefSize();
257 MapMode aMMSrc = pMtf->GetPrefMapMode();
258 MapMode aMMDst( MAP_100TH_MM );
259 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
260 return TRUE;
262 else
264 delete pMtf;
265 pMtf = NULL;
271 rStm.ResetError();
272 rStm.Seek( nBeginPos );
273 nFormat = ReadClipboardFormat( rStm );
274 // JobSetup, bzw. TargetDevice ueberlesen
275 // Information aufnehmen, um sie beim Schreiben nicht zu verlieren
276 nJobLen = 0;
277 rStm >> nJobLen;
278 if( nJobLen >= 4 )
280 nJobLen -= 4;
281 if( nJobLen )
283 pJob = new BYTE[ nJobLen ];
284 rStm.Read( pJob, nJobLen );
287 else
289 rStm.SetError( SVSTREAM_GENERALERROR );
290 return FALSE;
292 UINT32 nAsp;
293 rStm >> nAsp;
294 USHORT nSvAsp = USHORT( nAsp );
295 SetAspect( nSvAsp );
296 rStm.SeekRel( 4 ); //L-Index ueberlesen
297 rStm >> nAdvFlags;
298 rStm.SeekRel( 4 ); //Compression
299 UINT32 nWidth = 0;
300 UINT32 nHeight = 0;
301 UINT32 nSize = 0;
302 rStm >> nWidth >> nHeight >> nSize;
303 aSize.Width() = nWidth;
304 aSize.Height() = nHeight;
306 if( nFormat == FORMAT_GDIMETAFILE )
308 pMtf = new GDIMetaFile();
309 ReadWindowMetafile( rStm, *pMtf, NULL );
311 else if( nFormat == FORMAT_BITMAP )
313 pBmp = new Bitmap();
314 rStm >> *pBmp;
316 else
318 BYTE * p = new BYTE[ nSize ];
319 rStm.Read( p, nSize );
320 delete p;
321 return FALSE;
323 return TRUE;
326 /************************************************************************/
327 void Impl_OlePres::Write( SvStream & rStm )
329 WriteClipboardFormat( rStm, FORMAT_GDIMETAFILE );
330 rStm << (INT32)(nJobLen +4); // immer leeres TargetDevice
331 if( nJobLen )
332 rStm.Write( pJob, nJobLen );
333 rStm << (UINT32)nAspect;
334 rStm << (INT32)-1; //L-Index immer -1
335 rStm << (INT32)nAdvFlags;
336 rStm << (INT32)0; //Compression
337 rStm << (INT32)aSize.Width();
338 rStm << (INT32)aSize.Height();
339 ULONG nPos = rStm.Tell();
340 rStm << (INT32)0;
342 if( GetFormat() == FORMAT_GDIMETAFILE && pMtf )
344 // Immer auf 1/100 mm, bis Mtf-Loesung gefunden
345 // Annahme (keine Skalierung, keine Org-Verschiebung)
346 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleX() == Fraction( 1, 1 ),
347 "X-Skalierung im Mtf" );
348 DBG_ASSERT( pMtf->GetPrefMapMode().GetScaleY() == Fraction( 1, 1 ),
349 "Y-Skalierung im Mtf" );
350 DBG_ASSERT( pMtf->GetPrefMapMode().GetOrigin() == Point(),
351 "Origin-Verschiebung im Mtf" );
352 MapUnit nMU = pMtf->GetPrefMapMode().GetMapUnit();
353 if( MAP_100TH_MM != nMU )
355 Size aPrefS( pMtf->GetPrefSize() );
356 Size aS( aPrefS );
357 aS = OutputDevice::LogicToLogic( aS, nMU, MAP_100TH_MM );
359 pMtf->Scale( Fraction( aS.Width(), aPrefS.Width() ),
360 Fraction( aS.Height(), aPrefS.Height() ) );
361 pMtf->SetPrefMapMode( MAP_100TH_MM );
362 pMtf->SetPrefSize( aS );
364 WriteWindowMetafileBits( rStm, *pMtf );
366 else
368 DBG_ERROR( "unknown format" );
370 ULONG nEndPos = rStm.Tell();
371 rStm.Seek( nPos );
372 rStm << (UINT32)(nEndPos - nPos - 4);
373 rStm.Seek( nEndPos );
376 Impl_OlePres * CreateCache_Impl( SotStorage * pStor )
378 SotStorageStreamRef xOleObjStm =pStor->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "Ole-Object" ) ),
379 STREAM_READ | STREAM_NOCREATE );
380 if( xOleObjStm->GetError() )
381 return NULL;
382 SotStorageRef xOleObjStor = new SotStorage( *xOleObjStm );
383 if( xOleObjStor->GetError() )
384 return NULL;
386 String aStreamName;
387 if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) ) ) )
388 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres000" ) );
389 else if( xOleObjStor->IsContained( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ) ) )
390 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) );
392 if( aStreamName.Len() == 0 )
393 return NULL;
396 for( USHORT i = 1; i < 10; i++ )
398 SotStorageStreamRef xStm = xOleObjStor->OpenSotStream( aStreamName,
399 STREAM_READ | STREAM_NOCREATE );
400 if( xStm->GetError() )
401 break;
403 xStm->SetBufferSize( 8192 );
404 Impl_OlePres * pEle = new Impl_OlePres( 0 );
405 if( pEle->Read( *xStm ) && !xStm->GetError() )
407 if( pEle->GetFormat() == FORMAT_GDIMETAFILE || pEle->GetFormat() == FORMAT_BITMAP )
408 return pEle;
410 delete pEle;
411 aStreamName = String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\002OlePres00" ) );
412 aStreamName += String( i );
414 return NULL;
419 //---------------------------------------------------------------------------
420 // Hilfs Klassen aus MSDFFDEF.HXX
421 //---------------------------------------------------------------------------
423 SvStream& operator>>( SvStream& rIn, DffRecordHeader& rRec )
425 rRec.nFilePos = rIn.Tell();
426 UINT16 nTmp(0);
427 rIn >> nTmp;
428 rRec.nImpVerInst = nTmp;
429 rRec.nRecVer = sal::static_int_cast< BYTE >(nTmp & 0x000F);
430 rRec.nRecInstance = nTmp >> 4;
431 rIn >> rRec.nRecType;
432 rIn >> rRec.nRecLen;
433 return rIn;
436 // Masse fuer dashed lines
437 #define LLEN_MIDDLE (450)
438 #define LLEN_SPACE_MIDDLE (360)
439 #define LLEN_LONG (LLEN_MIDDLE * 2)
440 #define LLEN_SPACE_LONG (LLEN_SPACE_MIDDLE + 20)
441 #define LLEN_POINT (LLEN_MIDDLE / 4)
442 #define LLEN_SPACE_POINT (LLEN_SPACE_MIDDLE / 4)
444 SvStream& operator>>( SvStream& rIn, DffPropSet& rRec )
446 rRec.InitializePropSet();
448 DffRecordHeader aHd;
449 rIn >> aHd;
450 UINT32 nPropCount = aHd.nRecInstance;
452 // FilePos der ComplexData merken
453 UINT32 nComplexDataFilePos = rIn.Tell() + ( nPropCount * 6 );
455 for( UINT32 nPropNum = 0; nPropNum < nPropCount; nPropNum++ )
457 sal_uInt16 nTmp;
458 sal_uInt32 nRecType, nContent, nContentEx = 0xffff0000;
459 rIn >> nTmp
460 >> nContent;
462 nRecType = nTmp & 0x3fff;
464 if ( nRecType > 0x3ff )
465 break;
466 if ( ( nRecType & 0x3f ) == 0x3f )
467 { // clear flags that have to be cleared
468 rRec.mpContents[ nRecType ] &= ( ( nContent >> 16 ) ^ 0xffffffff );
469 // set flags that have to be set
470 rRec.mpContents[ nRecType ] |= nContent;
471 nContentEx |= ( nContent >> 16 );
472 rRec.Replace( nRecType, (void*)nContentEx );
474 else
476 DffPropFlags aPropFlag = { 1, 0, 0, 0 };
477 if ( nTmp & 0x4000 )
478 aPropFlag.bBlip = sal_True;
479 if ( nTmp & 0x8000 )
480 aPropFlag.bComplex = sal_True;
481 if ( aPropFlag.bComplex && nContent && ( nComplexDataFilePos < aHd.GetRecEndFilePos() ) )
483 // normally nContent is the complete size of the complex property,
484 // but this is not always true for IMsoArrays ( what the hell is a IMsoArray ? )
486 // I love special threatments :-(
487 if ( ( nRecType == DFF_Prop_pVertices ) || ( nRecType == DFF_Prop_pSegmentInfo )
488 || ( nRecType == DFF_Prop_fillShadeColors ) || ( nRecType == DFF_Prop_lineDashStyle )
489 || ( nRecType == DFF_Prop_pWrapPolygonVertices ) || ( nRecType == DFF_Prop_connectorPoints )
490 || ( nRecType == DFF_Prop_Handles ) || ( nRecType == DFF_Prop_pFormulas )
491 || ( nRecType == DFF_Prop_textRectangles ) )
493 // now check if the current content size is possible, or 6 bytes too small
494 sal_uInt32 nOldPos = rIn.Tell();
495 sal_Int16 nNumElem, nNumElemReserved, nSize;
497 rIn.Seek( nComplexDataFilePos );
498 rIn >> nNumElem >> nNumElemReserved >> nSize;
499 if ( nNumElemReserved >= nNumElem )
501 // the size of these array elements is nowhere defined,
502 // what if the size is negative ?
503 // ok, we will make it positive and shift it.
504 // for -16 this works
505 if ( nSize < 0 )
506 nSize = ( -nSize ) >> 2;
507 sal_uInt32 nDataSize = (sal_uInt32)( nSize * nNumElem );
509 // sometimes the content size is 6 bytes too small (array header information is missing )
510 if ( nDataSize == nContent )
511 nContent += 6;
513 // check if array fits into the PropertyContainer
514 if ( ( nComplexDataFilePos + nContent ) > aHd.GetRecEndFilePos() )
515 nContent = 0;
517 else
518 nContent = 0;
519 rIn.Seek( nOldPos );
521 if ( nContent )
523 nContentEx = nComplexDataFilePos; // insert the filepos of this property;
524 nComplexDataFilePos += nContent; // store filepos, that is used for the next complex property
526 else // a complex property needs content
527 aPropFlag.bSet = sal_False; // otherwise something is wrong
529 rRec.mpContents[ nRecType ] = nContent;
530 rRec.mpFlags[ nRecType ] = aPropFlag;
531 rRec.Insert( nRecType, (void*)nContentEx );
534 aHd.SeekToEndOfRecord( rIn );
535 return rIn;
538 void DffPropSet::InitializePropSet() const
541 cmc:
542 " Boolean properties are grouped in bitfields by property set; note that
543 the Boolean properties in each property set are contiguous. They are saved
544 under the property ID of the last Boolean property in the set, and are
545 placed in the value field in reverse order starting with the last property
546 in the low bit. "
548 e.g.
550 fEditedWrap
551 fBehindDocument
552 fOnDblClickNotify
553 fIsButton
554 fOneD
555 fHidden
556 fPrint
558 are all part of a group and all are by default false except for fPrint,
559 which equates to a default bit sequence for the group of 0000001 -> 0x1
561 If at a later stage word sets fBehindDocument away from the default it
562 will be done by having a property named fPrint whose bitsequence will have
563 the fBehindDocument bit set. e.g. a DFF_Prop_fPrint with value 0x200020
564 has set bit 6 on so as to enable fBehindDocument (as well as disabling
565 everything else)
568 memset( ( (DffPropSet*) this )->mpFlags, 0, 0x400 * sizeof(DffPropFlags) );
569 ( (DffPropSet*) this )->Clear();
571 DffPropFlags nFlags = { 1, 0, 0, 1 };
573 ( (DffPropSet*) this )->mpContents[ DFF_Prop_LockAgainstGrouping ] = 0x0000; //0x01ff0000;
574 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_LockAgainstGrouping ] = nFlags;
575 ( (DffPropSet*) this )->Insert( DFF_Prop_LockAgainstGrouping, (void*)0xffff0000 );
577 ( (DffPropSet*) this )->mpContents[ DFF_Prop_FitTextToShape ] = 0x0010; //0x001f0010;
578 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_FitTextToShape ] = nFlags;
579 ( (DffPropSet*) this )->Insert( DFF_Prop_FitTextToShape, (void*)0xffff0000 );
581 ( (DffPropSet*) this )->mpContents[ DFF_Prop_gtextFStrikethrough ] = 0x0000; //0xffff0000;
582 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_gtextFStrikethrough ] = nFlags;
583 ( (DffPropSet*) this )->Insert( DFF_Prop_gtextFStrikethrough, (void*)0xffff0000 );
585 ( (DffPropSet*) this )->mpContents[ DFF_Prop_pictureActive ] = 0x0000; //0x000f0000;
586 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_pictureActive ] = nFlags;
587 ( (DffPropSet*) this )->Insert( DFF_Prop_pictureActive, (void*)0xffff0000 );
589 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fFillOK ] = 0x0039; //0x003f0039;
590 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fFillOK ] = nFlags;
591 ( (DffPropSet*) this )->Insert( DFF_Prop_fFillOK, (void*)0xffff0000 );
593 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoFillHitTest ] = 0x001c; //0x001f001c;
594 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoFillHitTest ] = nFlags;
595 ( (DffPropSet*) this )->Insert( DFF_Prop_fNoFillHitTest, (void*)0xffff0000 );
597 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fNoLineDrawDash ] = 0x001e; //0x001f000e;
598 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fNoLineDrawDash ] = nFlags;
599 ( (DffPropSet*) this )->Insert( DFF_Prop_fNoLineDrawDash, (void*)0xffff0000 );
601 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fshadowObscured ] = 0x0000; //0x00030000;
602 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fshadowObscured ] = nFlags;
603 ( (DffPropSet*) this )->Insert( DFF_Prop_fshadowObscured, (void*)0xffff0000 );
605 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fPerspective ] = 0x0000; //0x00010000;
606 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPerspective ] = nFlags;
607 ( (DffPropSet*) this )->Insert( DFF_Prop_fPerspective, (void*)0xffff0000 );
609 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DLightFace ] = 0x0001; //0x000f0001;
610 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DLightFace ] = nFlags;
611 ( (DffPropSet*) this )->Insert( DFF_Prop_fc3DLightFace, (void*)0xffff0000 );
613 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fc3DFillHarsh ] = 0x0016; //0x001f0016;
614 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fc3DFillHarsh ] = nFlags;
615 ( (DffPropSet*) this )->Insert( DFF_Prop_fc3DFillHarsh, (void*)0xffff0000 );
617 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fBackground ] = 0x0000; //0x001f0000;
618 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fBackground ] = nFlags;
619 ( (DffPropSet*) this )->Insert( DFF_Prop_fBackground, (void*)0xffff0000 );
621 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fCalloutLengthSpecified ] = 0x0010; //0x00ef0010;
622 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fCalloutLengthSpecified ] = nFlags;
623 ( (DffPropSet*) this )->Insert( DFF_Prop_fCalloutLengthSpecified, (void*)0xffff0000 );
625 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fPrint ] = 0x0001; //0x00ef0001;
626 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fPrint ] = nFlags;
627 ( (DffPropSet*) this )->Insert( DFF_Prop_fPrint, (void*)0xffff0000 );
629 ( (DffPropSet*) this )->mpContents[ DFF_Prop_fillColor ] = 0xffffff;
630 ( (DffPropSet*) this )->mpFlags[ DFF_Prop_fillColor ] = nFlags;
631 ( (DffPropSet*) this )->Insert( DFF_Prop_fillColor, (void*)0xffff0000 );
634 void DffPropSet::Merge( DffPropSet& rMaster ) const
636 for ( void* pDummy = rMaster.First(); pDummy; pDummy = rMaster.Next() )
638 UINT32 nRecType = rMaster.GetCurKey();
639 if ( ( nRecType & 0x3f ) == 0x3f ) // this is something called FLAGS
641 UINT32 nCurrentFlags = mpContents[ nRecType ];
642 UINT32 nMergeFlags = rMaster.mpContents[ nRecType ];
643 nMergeFlags &= ( nMergeFlags >> 16 ) | 0xffff0000; // clearing low word
644 nMergeFlags &= ( ( nCurrentFlags & 0xffff0000 ) // remove allready hard set
645 | ( nCurrentFlags >> 16 ) ) ^ 0xffffffff; // attributes from mergeflags
646 nCurrentFlags &= ( ( nMergeFlags & 0xffff0000 ) // apply zero master bits
647 | ( nMergeFlags >> 16 ) ) ^ 0xffffffff;
648 nCurrentFlags |= (UINT16)nMergeFlags; // apply filled master bits
649 ( (DffPropSet*) this )->mpContents[ nRecType ] = nCurrentFlags;
652 sal_uInt32 nNewContentEx = (sal_uInt32)(sal_uIntPtr)rMaster.GetCurObject();
653 if ( ((DffPropSet*)this)->Seek( nRecType ) )
654 nNewContentEx |= (sal_uInt32)(sal_uIntPtr)GetCurObject();
655 ( (DffPropSet*) this )->Replace( nRecType, (void*)nNewContentEx );
657 else
659 if ( !IsProperty( nRecType ) || !IsHardAttribute( nRecType ) )
661 ( (DffPropSet*) this )->mpContents[ nRecType ] = rMaster.mpContents[ nRecType ];
662 DffPropFlags nFlags( rMaster.mpFlags[ nRecType ] );
663 nFlags.bSoftAttr = TRUE;
664 ( (DffPropSet*) this )->mpFlags[ nRecType ] = nFlags;
665 ( (DffPropSet*) this )->Insert( nRecType, pDummy );
671 BOOL DffPropSet::IsHardAttribute( UINT32 nId ) const
673 BOOL bRetValue = TRUE;
674 nId &= 0x3ff;
675 if ( ( nId & 0x3f ) >= 48 ) // is this a flag id
677 if ( ((DffPropSet*)this)->Seek( nId | 0x3f ) )
679 sal_uInt32 nContentEx = (sal_uInt32)(sal_uIntPtr)GetCurObject();
680 bRetValue = ( nContentEx & ( 1 << ( 0xf - ( nId & 0xf ) ) ) ) != 0;
683 else
684 bRetValue = ( mpFlags[ nId ].bSoftAttr == 0 );
685 return bRetValue;
688 UINT32 DffPropSet::GetPropertyValue( UINT32 nId, UINT32 nDefault ) const
690 nId &= 0x3ff;
691 return ( mpFlags[ nId ].bSet ) ? mpContents[ nId ] : nDefault;
694 bool DffPropSet::GetPropertyBool( UINT32 nId, bool bDefault ) const
696 UINT32 nBaseId = nId | 31; // base ID to get the UINT32 property value
697 UINT32 nMask = 1 << (nBaseId - nId); // bit mask of the boolean property
699 UINT32 nPropValue = GetPropertyValue( nBaseId, bDefault ? nMask : 0 );
700 return (nPropValue & nMask) != 0;
703 ::rtl::OUString DffPropSet::GetPropertyString( UINT32 nId, SvStream& rStrm ) const
705 sal_Size nOldPos = rStrm.Tell();
706 ::rtl::OUStringBuffer aBuffer;
707 sal_uInt32 nBufferSize = GetPropertyValue( nId );
708 if( (nBufferSize > 0) && SeekToContent( nId, rStrm ) )
710 sal_Int32 nStrLen = static_cast< sal_Int32 >( nBufferSize / 2 );
711 aBuffer.ensureCapacity( nStrLen );
712 for( sal_Int32 nCharIdx = 0; nCharIdx < nStrLen; ++nCharIdx )
714 sal_uInt16 nChar = 0;
715 rStrm >> nChar;
716 if( nChar > 0 )
717 aBuffer.append( static_cast< sal_Unicode >( nChar ) );
718 else
719 break;
722 rStrm.Seek( nOldPos );
723 return aBuffer.makeStringAndClear();
726 void DffPropSet::SetPropertyValue( UINT32 nId, UINT32 nValue ) const
728 if ( !mpFlags[ nId ].bSet )
730 ( (DffPropSet*) this )->Insert( nId, (void*)nValue );
731 ( (DffPropSet*) this )->mpFlags[ nId ].bSet = TRUE;
733 ( (DffPropSet*) this )->mpContents[ nId ] = nValue;
736 BOOL DffPropSet::SeekToContent( UINT32 nRecType, SvStream& rStrm ) const
738 nRecType &= 0x3ff;
739 if ( mpFlags[ nRecType ].bSet )
741 if ( mpFlags[ nRecType ].bComplex )
743 if ( ((DffPropSet*)this)->Seek( nRecType ) )
745 sal_uInt32 nOffset = (sal_uInt32)(sal_uIntPtr)GetCurObject();
746 if ( nOffset && ( ( nOffset & 0xffff0000 ) != 0xffff0000 ) )
748 rStrm.Seek( nOffset );
749 return TRUE;
754 return FALSE;
757 DffPropertyReader::DffPropertyReader( const SvxMSDffManager& rMan ) :
758 rManager( rMan ),
759 pDefaultPropSet( NULL )
761 InitializePropSet();
764 void DffPropertyReader::SetDefaultPropSet( SvStream& rStCtrl, UINT32 nOffsDgg ) const
766 delete pDefaultPropSet;
767 UINT32 nMerk = rStCtrl.Tell();
768 rStCtrl.Seek( nOffsDgg );
769 DffRecordHeader aRecHd;
770 rStCtrl >> aRecHd;
771 if ( aRecHd.nRecType == DFF_msofbtDggContainer )
773 if ( rManager.SeekToRec( rStCtrl, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
775 ( (DffPropertyReader*) this )->pDefaultPropSet = new DffPropSet;
776 rStCtrl >> *pDefaultPropSet;
779 rStCtrl.Seek( nMerk );
782 #ifdef DBG_CUSTOMSHAPE
783 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData, UINT32 nShapeId ) const
784 #else
785 void DffPropertyReader::ReadPropSet( SvStream& rIn, void* pClientData ) const
786 #endif
788 ULONG nFilePos = rIn.Tell();
789 rIn >> (DffPropertyReader&)*this;
791 if ( IsProperty( DFF_Prop_hspMaster ) )
793 if ( rManager.SeekToShape( rIn, pClientData, GetPropertyValue( DFF_Prop_hspMaster ) ) )
795 DffRecordHeader aRecHd;
796 rIn >> aRecHd;
797 if ( rManager.SeekToRec( rIn, DFF_msofbtOPT, aRecHd.GetRecEndFilePos() ) )
799 DffPropSet aMasterPropSet;
800 rIn >> aMasterPropSet;
801 Merge( aMasterPropSet );
805 // if ( pDefaultPropSet )
806 // Merge( *( pDefaultPropSet ) );
808 ( (DffPropertyReader*) this )->mnFix16Angle = Fix16ToAngle( GetPropertyValue( DFF_Prop_Rotation, 0 ) );
810 #ifdef DBG_CUSTOMSHAPE
812 String aURLStr;
814 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( String( RTL_CONSTASCII_STRINGPARAM( "d:\\ashape.dbg" ) ), aURLStr ) )
816 SvStream* pOut = ::utl::UcbStreamHelper::CreateStream( aURLStr, STREAM_WRITE );
818 if( pOut )
820 pOut->Seek( STREAM_SEEK_TO_END );
822 if ( IsProperty( DFF_Prop_adjustValue ) || IsProperty( DFF_Prop_pVertices ) )
824 pOut->WriteLine( "" );
825 ByteString aString( "ShapeId: " );
826 aString.Append( ByteString::CreateFromInt32( nShapeId ) );
827 pOut->WriteLine( aString );
829 for ( sal_uInt32 i = DFF_Prop_adjustValue; i <= DFF_Prop_adjust10Value; i++ )
831 if ( IsProperty( i ) )
833 ByteString aString( "Prop_adjustValue" );
834 aString.Append( ByteString::CreateFromInt32( ( i - DFF_Prop_adjustValue ) + 1 ) );
835 aString.Append( ":" );
836 aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
837 pOut->WriteLine( aString );
840 sal_Int32 i;
841 for ( i = 320; i < 383; i++ )
843 if ( ( i >= DFF_Prop_adjustValue ) && ( i <= DFF_Prop_adjust10Value ) )
844 continue;
845 if ( IsProperty( i ) )
847 if ( SeekToContent( i, rIn ) )
849 INT32 nLen = (INT32)GetPropertyValue( i );
850 if ( nLen )
852 pOut->WriteLine( "" );
853 ByteString aDesc( "Property:" );
854 aDesc.Append( ByteString::CreateFromInt32( i ) );
855 aDesc.Append( ByteString( " Size:" ) );
856 aDesc.Append( ByteString::CreateFromInt32( nLen ) );
857 pOut->WriteLine( aDesc );
858 INT16 nNumElem, nNumElemMem, nNumSize;
859 rIn >> nNumElem >> nNumElemMem >> nNumSize;
860 aDesc = ByteString( "Entries: " );
861 aDesc.Append( ByteString::CreateFromInt32( nNumElem ) );
862 aDesc.Append( ByteString( " Size:" ) );
863 aDesc.Append( ByteString::CreateFromInt32( nNumSize ) );
864 pOut->WriteLine( aDesc );
865 if ( nNumSize < 0 )
866 nNumSize = ( ( -nNumSize ) >> 2 );
867 if ( !nNumSize )
868 nNumSize = 16;
869 nLen -= 6;
870 while ( nLen > 0 )
872 ByteString aString;
873 for ( UINT32 j = 0; nLen && ( j < ( nNumSize >> 1 ) ); j++ )
875 for ( UINT32 k = 0; k < 2; k++ )
877 if ( nLen )
879 BYTE nVal;
880 rIn >> nVal;
881 if ( ( nVal >> 4 ) > 9 )
882 *pOut << (BYTE)( ( nVal >> 4 ) + 'A' - 10 );
883 else
884 *pOut << (BYTE)( ( nVal >> 4 ) + '0' );
886 if ( ( nVal & 0xf ) > 9 )
887 *pOut << (BYTE)( ( nVal & 0xf ) + 'A' - 10 );
888 else
889 *pOut << (BYTE)( ( nVal & 0xf ) + '0' );
891 nLen--;
894 *pOut << (char)( ' ' );
896 pOut->WriteLine( aString );
900 else
902 ByteString aString( "Property" );
903 aString.Append( ByteString::CreateFromInt32( i ) );
904 aString.Append( ":" );
905 aString.Append( ByteString::CreateFromInt32( GetPropertyValue( i ) ) );
906 pOut->WriteLine( aString );
911 delete pOut;
915 #endif
917 rIn.Seek( nFilePos );
921 INT32 DffPropertyReader::Fix16ToAngle( INT32 nContent ) const
923 INT32 nAngle = 0;
924 if ( nContent )
926 nAngle = ( (INT16)( nContent >> 16) * 100L ) + ( ( ( nContent & 0x0000ffff) * 100L ) >> 16 );
927 nAngle = NormAngle360( -nAngle );
929 return nAngle;
932 DffPropertyReader::~DffPropertyReader()
934 delete pDefaultPropSet;
937 ////////////////////////////////////////////////////////////////////////////////////////////////////
939 SvStream& operator>>( SvStream& rIn, SvxMSDffConnectorRule& rRule )
941 rIn >> rRule.nRuleId
942 >> rRule.nShapeA
943 >> rRule.nShapeB
944 >> rRule.nShapeC
945 >> rRule.ncptiA
946 >> rRule.ncptiB;
948 return rIn;
951 SvxMSDffSolverContainer::SvxMSDffSolverContainer()
955 SvxMSDffSolverContainer::~SvxMSDffSolverContainer()
957 for ( SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)aCList.First();
958 pPtr; pPtr = (SvxMSDffConnectorRule*)aCList.Next() )
959 delete pPtr;
962 SvStream& operator>>( SvStream& rIn, SvxMSDffSolverContainer& rContainer )
964 DffRecordHeader aHd;
965 rIn >> aHd;
966 if ( aHd.nRecType == DFF_msofbtSolverContainer )
968 DffRecordHeader aCRule;
969 while ( ( rIn.GetError() == 0 ) && ( rIn.Tell() < aHd.GetRecEndFilePos() ) )
971 rIn >> aCRule;
972 if ( aCRule.nRecType == DFF_msofbtConnectorRule )
974 SvxMSDffConnectorRule* pRule = new SvxMSDffConnectorRule;
975 rIn >> *pRule;
976 rContainer.aCList.Insert( pRule, LIST_APPEND );
978 aCRule.SeekToEndOfRecord( rIn );
981 return rIn;
984 void SvxMSDffManager::SolveSolver( const SvxMSDffSolverContainer& rSolver )
986 sal_Int32 i, nCnt;
987 for ( i = 0, nCnt = rSolver.aCList.Count(); i < nCnt; i++ )
989 SvxMSDffConnectorRule* pPtr = (SvxMSDffConnectorRule*)rSolver.aCList.GetObject( i );
990 if ( pPtr->pCObj )
992 for ( int nN = 0; nN < 2; nN++ )
994 SdrObject* pO;
995 sal_uInt32 nC, nSpFlags;
996 sal_Bool bTail;
997 if ( !nN )
999 bTail = sal_True;
1000 pO = pPtr->pAObj;
1001 nC = pPtr->ncptiA;
1002 nSpFlags = pPtr->nSpFlagsA;
1004 else
1006 bTail = sal_False;
1007 pO = pPtr->pBObj;
1008 nC = pPtr->ncptiB;
1009 nSpFlags = pPtr->nSpFlagsB;
1011 if ( pO )
1013 Any aAny;
1014 SdrGluePoint aGluePoint;
1015 Reference< XShape > aXShape( pO->getUnoShape(), UNO_QUERY );
1016 Reference< XShape > aXConnector( pPtr->pCObj->getUnoShape(), UNO_QUERY );
1017 SdrGluePointList* pList = pO->ForceGluePointList();
1019 sal_Bool bValidGluePoint = sal_False;
1020 sal_Int32 nId = nC;
1021 sal_uInt32 nInventor = pO->GetObjInventor();
1023 if( nInventor == SdrInventor )
1025 sal_uInt32 nObjId = pO->GetObjIdentifier();
1026 switch( nObjId )
1028 case OBJ_GRUP :
1029 case OBJ_GRAF :
1030 case OBJ_RECT :
1031 case OBJ_TEXT :
1032 case OBJ_PAGE :
1033 case OBJ_TEXTEXT :
1034 case OBJ_wegFITTEXT :
1035 case OBJ_wegFITALLTEXT :
1036 case OBJ_TITLETEXT :
1037 case OBJ_OUTLINETEXT :
1039 if ( nC & 1 )
1041 if ( nSpFlags & SP_FFLIPH )
1042 nC ^= 2; // 1 <-> 3
1044 else
1046 if ( nSpFlags & SP_FFLIPV )
1047 nC ^= 1; // 0 <-> 2
1049 switch( nC )
1051 case 0 :
1052 nId = 0; // SDRVERTALIGN_TOP;
1053 break;
1054 case 1 :
1055 nId = 3; // SDRHORZALIGN_RIGHT;
1056 break;
1057 case 2 :
1058 nId = 2; // SDRVERTALIGN_BOTTOM;
1059 break;
1060 case 3 :
1061 nId = 1; // SDRHORZALIGN_LEFT;
1062 break;
1064 if ( nId <= 3 )
1065 bValidGluePoint = sal_True;
1067 break;
1068 case OBJ_POLY :
1069 case OBJ_PLIN :
1070 case OBJ_LINE :
1071 case OBJ_PATHLINE :
1072 case OBJ_PATHFILL :
1073 case OBJ_FREELINE :
1074 case OBJ_FREEFILL :
1075 case OBJ_SPLNLINE :
1076 case OBJ_SPLNFILL :
1077 case OBJ_PATHPOLY :
1078 case OBJ_PATHPLIN :
1080 if ( pList && ( pList->GetCount() > nC ) )
1082 bValidGluePoint = sal_True;
1083 nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
1085 else
1087 sal_Bool bNotFound = sal_True;
1089 PolyPolygon aPolyPoly( EscherPropertyContainer::GetPolyPolygon( aXShape ) );
1090 sal_uInt16 k, j, nPolySize = aPolyPoly.Count();
1091 if ( nPolySize )
1093 sal_uInt32 nPointCount = 0;
1094 Rectangle aBoundRect( aPolyPoly.GetBoundRect() );
1095 if ( aBoundRect.GetWidth() && aBoundRect.GetHeight() )
1097 for ( k = 0; bNotFound && ( k < nPolySize ); k++ )
1099 const Polygon& rPolygon = aPolyPoly.GetObject( k );
1100 for ( j = 0; bNotFound && ( j < rPolygon.GetSize() ); j++ )
1102 PolyFlags eFlags = rPolygon.GetFlags( j );
1103 if ( eFlags == POLY_NORMAL )
1105 if ( nC == nPointCount )
1107 const Point& rPoint = rPolygon.GetPoint( j );
1108 double fXRel = rPoint.X() - aBoundRect.Left();
1109 double fYRel = rPoint.Y() - aBoundRect.Top();
1110 sal_Int32 nWidth = aBoundRect.GetWidth();
1111 if ( !nWidth )
1112 nWidth = 1;
1113 sal_Int32 nHeight= aBoundRect.GetHeight();
1114 if ( !nHeight )
1115 nHeight = 1;
1116 fXRel /= (double)nWidth;
1117 fXRel *= 10000;
1118 fYRel /= (double)nHeight;
1119 fYRel *= 10000;
1120 aGluePoint.SetPos( Point( (sal_Int32)fXRel, (sal_Int32)fYRel ) );
1121 aGluePoint.SetPercent( sal_True );
1122 aGluePoint.SetAlign( SDRVERTALIGN_TOP | SDRHORZALIGN_LEFT );
1123 aGluePoint.SetEscDir( SDRESC_SMART );
1124 nId = (sal_Int32)((*pList)[ pList->Insert( aGluePoint ) ].GetId() + 3 );
1125 bNotFound = sal_False;
1127 nPointCount++;
1133 if ( !bNotFound )
1135 bValidGluePoint = sal_True;
1139 break;
1141 case OBJ_CUSTOMSHAPE :
1143 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pO)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
1144 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
1145 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
1146 sal_Int16 nGluePointType = EnhancedCustomShapeGluePointType::SEGMENTS;
1147 com::sun::star::uno::Any* pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePointType );
1148 if ( pAny )
1149 *pAny >>= nGluePointType;
1150 else
1152 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
1153 rtl::OUString sShapeType;
1154 pAny = aGeometryItem.GetPropertyValueByName( sType );
1155 if ( pAny )
1156 *pAny >>= sShapeType;
1157 MSO_SPT eSpType = EnhancedCustomShapeTypeNames::Get( sShapeType );
1158 nGluePointType = GetCustomShapeConnectionTypeDefault( eSpType );
1160 if ( nGluePointType == EnhancedCustomShapeGluePointType::CUSTOM )
1162 if ( pList && ( pList->GetCount() > nC ) )
1164 bValidGluePoint = sal_True;
1165 nId = (sal_Int32)((*pList)[ (sal_uInt16)nC].GetId() + 3 );
1168 else if ( nGluePointType == EnhancedCustomShapeGluePointType::RECT )
1170 if ( nC & 1 )
1172 if ( nSpFlags & SP_FFLIPH )
1173 nC ^= 2; // 1 <-> 3
1175 else
1177 if ( nSpFlags & SP_FFLIPV )
1178 nC ^= 1; // 0 <-> 2
1180 switch( nC )
1182 case 0 :
1183 nId = 0; // SDRVERTALIGN_TOP;
1184 break;
1185 case 1 :
1186 nId = 3; // SDRHORZALIGN_RIGHT;
1187 break;
1188 case 2 :
1189 nId = 2; // SDRVERTALIGN_BOTTOM;
1190 break;
1191 case 3 :
1192 nId = 1; // SDRHORZALIGN_LEFT;
1193 break;
1195 if ( nId <= 3 )
1196 bValidGluePoint = sal_True;
1198 else if ( nGluePointType == EnhancedCustomShapeGluePointType::SEGMENTS )
1200 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
1201 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
1203 sal_uInt32 k, nPt = nC;
1204 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
1205 pAny = aGeometryItem.GetPropertyValueByName( sPath, sSegments );
1206 if ( pAny )
1208 if ( *pAny >>= aSegments )
1210 for ( nPt = 0, k = 1; nC && ( k < (sal_uInt32)aSegments.getLength() ); k++ )
1212 sal_Int16 j, nCnt2 = aSegments[ k ].Count;
1213 if ( aSegments[ k ].Command != EnhancedCustomShapeSegmentCommand::UNKNOWN )
1215 for ( j = 0; nC && ( j < nCnt2 ); j++ )
1217 switch( aSegments[ k ].Command )
1219 case EnhancedCustomShapeSegmentCommand::ENDSUBPATH :
1220 case EnhancedCustomShapeSegmentCommand::CLOSESUBPATH :
1221 case EnhancedCustomShapeSegmentCommand::LINETO :
1222 case EnhancedCustomShapeSegmentCommand::MOVETO :
1224 nC--;
1225 nPt++;
1227 break;
1228 case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX :
1229 case EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY :
1230 break;
1232 case EnhancedCustomShapeSegmentCommand::CURVETO :
1234 nC--;
1235 nPt += 3;
1237 break;
1239 case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO :
1240 case EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE :
1242 nC--;
1243 nPt += 3;
1245 break;
1246 case EnhancedCustomShapeSegmentCommand::ARCTO :
1247 case EnhancedCustomShapeSegmentCommand::ARC :
1248 case EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO :
1249 case EnhancedCustomShapeSegmentCommand::CLOCKWISEARC :
1251 nC--;
1252 nPt += 4;
1254 break;
1261 pAny = aGeometryItem.GetPropertyValueByName( sPath, sCoordinates );
1262 if ( pAny )
1264 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
1265 *pAny >>= aCoordinates;
1266 if ( nPt < (sal_uInt32)aCoordinates.getLength() )
1268 nId = 4;
1269 com::sun::star::drawing::EnhancedCustomShapeParameterPair& rPara = aCoordinates[ nPt ];
1270 sal_Int32 nX = 0, nY = 0;
1271 if ( ( rPara.First.Value >>= nX ) && ( rPara.Second.Value >>= nY ) )
1273 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
1274 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
1275 pAny = aGeometryItem.GetPropertyValueByName( sPath, sGluePoints );
1276 if ( pAny )
1277 *pAny >>= aGluePoints;
1278 sal_Int32 nGluePoints = aGluePoints.getLength();
1279 aGluePoints.realloc( nGluePoints + 1 );
1280 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].First, nX );
1281 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ nGluePoints ].Second, nY );
1282 PropertyValue aProp;
1283 aProp.Name = sGluePoints;
1284 aProp.Value <<= aGluePoints;
1285 aGeometryItem.SetPropertyValue( sPath, aProp );
1286 bValidGluePoint = sal_True;
1287 ((SdrObjCustomShape*)pO)->SetMergedItem( aGeometryItem );
1288 SdrGluePointList* pLst = pO->ForceGluePointList();
1289 if ( pLst->GetCount() > nGluePoints )
1290 nId = (sal_Int32)((*pLst)[ (sal_uInt16)nGluePoints ].GetId() + 3 );
1296 break;
1298 if ( bValidGluePoint )
1300 Reference< XPropertySet > xPropSet( aXConnector, UNO_QUERY );
1301 if ( xPropSet.is() )
1303 if ( nN )
1305 String aPropName( RTL_CONSTASCII_USTRINGPARAM( "EndShape" ) );
1306 aAny <<= aXShape;
1307 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1308 aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "EndGluePointIndex" ) );
1309 aAny <<= nId;
1310 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1312 else
1314 String aPropName( RTL_CONSTASCII_USTRINGPARAM( "StartShape" ) );
1315 aAny <<= aXShape;
1316 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1317 aPropName = String( RTL_CONSTASCII_USTRINGPARAM( "StartGluePointIndex" ) );
1318 aAny <<= nId;
1319 SetPropValue( aAny, xPropSet, aPropName, sal_True );
1322 // Not sure what this is good for, repaint or broadcast of object change.
1323 //( Thus i am adding repaint here
1324 pO->SetChanged();
1325 pO->BroadcastObjectChange();
1335 ////////////////////////////////////////////////////////////////////////////////////////////////////
1337 static basegfx::B2DPolygon GetLineArrow( const sal_Int32 nLineWidth, const MSO_LineEnd eLineEnd,
1338 const MSO_LineEndWidth eLineWidth, const MSO_LineEndLength eLineLenght,
1339 sal_Int32& rnArrowWidth, sal_Bool& rbArrowCenter,
1340 String& rsArrowName, sal_Bool bScaleArrow )
1342 basegfx::B2DPolygon aRetval;
1343 double fLineWidth = nLineWidth < 70 ? 70.0 : nLineWidth;
1344 double fLenghtMul, fWidthMul;
1345 sal_Int32 nLineNumber;
1346 switch( eLineLenght )
1348 default :
1349 case mso_lineMediumLenArrow : fLenghtMul = 3.0; nLineNumber = 2; break;
1350 case mso_lineShortArrow : fLenghtMul = 2.0; nLineNumber = 1; break;
1351 case mso_lineLongArrow : fLenghtMul = 5.0; nLineNumber = 3; break;
1353 switch( eLineWidth )
1355 default :
1356 case mso_lineMediumWidthArrow : fWidthMul = 3.0; nLineNumber += 3; break;
1357 case mso_lineNarrowArrow : fWidthMul = 2.0; break;
1358 case mso_lineWideArrow : fWidthMul = 5.0; nLineNumber += 6; break;
1361 if ( bScaleArrow ) // #i33630 arrows imported from Word are too big
1363 fWidthMul /= 1.75;
1364 fLenghtMul/= 1.75;
1367 rbArrowCenter = sal_False;
1368 switch ( eLineEnd )
1370 case mso_lineArrowEnd :
1372 basegfx::B2DPolygon aTriangle;
1373 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, 0.0 ));
1374 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth ));
1375 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
1376 aTriangle.setClosed(true);
1377 aRetval = aTriangle;
1378 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowEnd " ), RTL_TEXTENCODING_UTF8 );
1380 break;
1382 case mso_lineArrowOpenEnd :
1384 switch( eLineLenght )
1386 default :
1387 case mso_lineMediumLenArrow : fLenghtMul = 4.5; break;
1388 case mso_lineShortArrow : fLenghtMul = 3.5; break;
1389 case mso_lineLongArrow : fLenghtMul = 6.0; break;
1391 switch( eLineWidth )
1393 default :
1394 case mso_lineMediumWidthArrow : fWidthMul = 4.5; break;
1395 case mso_lineNarrowArrow : fWidthMul = 3.5; break;
1396 case mso_lineWideArrow : fWidthMul = 6.0; break;
1398 basegfx::B2DPolygon aTriangle;
1399 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1400 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth, fLenghtMul * fLineWidth * 0.91 ));
1401 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.85, fLenghtMul * fLineWidth ));
1402 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50, fLenghtMul * fLineWidth * 0.36 ));
1403 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.15, fLenghtMul * fLineWidth ));
1404 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.91 ));
1405 aTriangle.setClosed(true);
1406 aRetval = aTriangle;
1407 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOpenEnd " ), RTL_TEXTENCODING_UTF8 );
1409 break;
1410 case mso_lineArrowStealthEnd :
1412 basegfx::B2DPolygon aTriangle;
1413 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1414 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth ));
1415 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth * 0.60 ));
1416 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth ));
1417 aTriangle.setClosed(true);
1418 aRetval = aTriangle;
1419 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowStealthEnd " ), RTL_TEXTENCODING_UTF8 );
1421 break;
1422 case mso_lineArrowDiamondEnd :
1424 basegfx::B2DPolygon aTriangle;
1425 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , 0.0 ));
1426 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth , fLenghtMul * fLineWidth * 0.50 ));
1427 aTriangle.append(basegfx::B2DPoint( fWidthMul * fLineWidth * 0.50 , fLenghtMul * fLineWidth ));
1428 aTriangle.append(basegfx::B2DPoint( 0.0, fLenghtMul * fLineWidth * 0.50 ));
1429 aTriangle.setClosed(true);
1430 aRetval = aTriangle;
1431 rbArrowCenter = sal_True;
1432 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowDiamondEnd " ), RTL_TEXTENCODING_UTF8 );
1434 break;
1435 case mso_lineArrowOvalEnd :
1437 aRetval = XPolygon( Point( (sal_Int32)( fWidthMul * fLineWidth * 0.50 ), 0 ),
1438 (sal_Int32)( fWidthMul * fLineWidth * 0.50 ),
1439 (sal_Int32)( fLenghtMul * fLineWidth * 0.50 ), 0, 3600 ).getB2DPolygon();
1440 rbArrowCenter = sal_True;
1441 rsArrowName = String( RTL_CONSTASCII_STRINGPARAM( "msArrowOvalEnd " ), RTL_TEXTENCODING_UTF8 );
1443 break;
1444 default: break;
1446 rsArrowName.Append( String::CreateFromInt32( nLineNumber ) );
1447 rnArrowWidth = (sal_Int32)( fLineWidth * fWidthMul );
1449 return aRetval;
1452 void DffPropertyReader::ApplyLineAttributes( SfxItemSet& rSet, const MSO_SPT eShapeType ) const // #i28269#
1454 UINT32 nLineFlags(GetPropertyValue( DFF_Prop_fNoLineDrawDash ));
1456 if(!IsHardAttribute( DFF_Prop_fLine ) && !IsCustomShapeStrokedByDefault( eShapeType ))
1458 nLineFlags &= ~0x08;
1461 if ( nLineFlags & 8 )
1463 // Linienattribute
1464 sal_Int32 nLineWidth = (INT32)GetPropertyValue( DFF_Prop_lineWidth, 9525 );
1466 MSO_LineDashing eLineDashing = (MSO_LineDashing)GetPropertyValue( DFF_Prop_lineDashing, mso_lineSolid );
1467 if ( eLineDashing == mso_lineSolid )
1468 rSet.Put(XLineStyleItem( XLINE_SOLID ) );
1469 else
1471 // MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle, mso_lineEndCapSquare );
1473 XDashStyle eDash = XDASH_RECT;
1474 sal_uInt16 nDots = 1;
1475 sal_uInt32 nDotLen = nLineWidth / 360;
1476 sal_uInt16 nDashes = 0;
1477 sal_uInt32 nDashLen = ( 8 * nLineWidth ) / 360;
1478 sal_uInt32 nDistance = ( 3 * nLineWidth ) / 360;;
1480 switch ( eLineDashing )
1482 default:
1483 case mso_lineDotSys :
1485 nDots = 1;
1486 nDashes = 0;
1487 nDistance = nDotLen;
1489 break;
1491 case mso_lineDashGEL :
1493 nDots = 0;
1494 nDashes = 1;
1495 nDashLen = ( 4 * nLineWidth ) / 360;
1497 break;
1499 case mso_lineDashDotGEL :
1501 nDots = 1;
1502 nDashes = 1;
1503 nDashLen = ( 4 * nLineWidth ) / 360;
1505 break;
1507 case mso_lineLongDashGEL :
1509 nDots = 0;
1510 nDashes = 1;
1512 break;
1514 case mso_lineLongDashDotGEL :
1516 nDots = 1;
1517 nDashes = 1;
1519 break;
1521 case mso_lineLongDashDotDotGEL:
1523 nDots = 2;
1524 nDashes = 1;
1526 break;
1529 rSet.Put( XLineDashItem( String(), XDash( eDash, nDots, nDotLen, nDashes, nDashLen, nDistance ) ) );
1530 rSet.Put( XLineStyleItem( XLINE_DASH ) );
1532 rSet.Put( XLineColorItem( String(), rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_lineColor ), DFF_Prop_lineColor ) ) );
1533 if ( IsProperty( DFF_Prop_lineOpacity ) )
1535 double nTrans = GetPropertyValue(DFF_Prop_lineOpacity, 0x10000);
1536 nTrans = (nTrans * 100) / 65536;
1537 rSet.Put(XLineTransparenceItem(
1538 sal_uInt16(100 - ::rtl::math::round(nTrans))));
1541 rManager.ScaleEmu( nLineWidth );
1542 rSet.Put( XLineWidthItem( nLineWidth ) );
1544 // SJ: LineJoint (setting each time a line is set, because our internal joint type has another default)
1545 MSO_LineJoin eLineJointDefault = mso_lineJoinMiter;
1546 if ( eShapeType == mso_sptMin )
1547 eLineJointDefault = mso_lineJoinRound;
1548 MSO_LineJoin eLineJoint = (MSO_LineJoin)GetPropertyValue( DFF_Prop_lineJoinStyle, eLineJointDefault );
1549 XLineJoint eXLineJoint( XLINEJOINT_MITER );
1550 if ( eLineJoint == mso_lineJoinBevel )
1551 eXLineJoint = XLINEJOINT_BEVEL;
1552 else if ( eLineJoint == mso_lineJoinRound )
1553 eXLineJoint = XLINEJOINT_ROUND;
1554 rSet.Put( XLineJointItem( eXLineJoint ) );
1556 if ( nLineFlags & 0x10 )
1558 sal_Bool bScaleArrows = rManager.pSdrModel->GetScaleUnit() == MAP_TWIP;
1559 ///////////////
1560 // LineStart //
1561 ///////////////
1562 if ( IsProperty( DFF_Prop_lineStartArrowhead ) )
1564 MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineStartArrowhead );
1565 MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineStartArrowWidth, mso_lineMediumWidthArrow );
1566 MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineStartArrowLength, mso_lineMediumLenArrow );
1568 sal_Int32 nArrowWidth;
1569 sal_Bool bArrowCenter;
1570 String aArrowName;
1571 basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
1573 rSet.Put( XLineStartWidthItem( nArrowWidth ) );
1574 rSet.Put( XLineStartItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
1575 rSet.Put( XLineStartCenterItem( bArrowCenter ) );
1577 /////////////
1578 // LineEnd //
1579 /////////////
1580 if ( IsProperty( DFF_Prop_lineEndArrowhead ) )
1582 MSO_LineEnd eLineEnd = (MSO_LineEnd)GetPropertyValue( DFF_Prop_lineEndArrowhead );
1583 MSO_LineEndWidth eWidth = (MSO_LineEndWidth)GetPropertyValue( DFF_Prop_lineEndArrowWidth, mso_lineMediumWidthArrow );
1584 MSO_LineEndLength eLenght = (MSO_LineEndLength)GetPropertyValue( DFF_Prop_lineEndArrowLength, mso_lineMediumLenArrow );
1586 sal_Int32 nArrowWidth;
1587 sal_Bool bArrowCenter;
1588 String aArrowName;
1589 basegfx::B2DPolygon aPoly(GetLineArrow( nLineWidth, eLineEnd, eWidth, eLenght, nArrowWidth, bArrowCenter, aArrowName, bScaleArrows ));
1591 rSet.Put( XLineEndWidthItem( nArrowWidth ) );
1592 rSet.Put( XLineEndItem( aArrowName, basegfx::B2DPolyPolygon(aPoly) ) );
1593 rSet.Put( XLineEndCenterItem( bArrowCenter ) );
1595 if ( IsProperty( DFF_Prop_lineEndCapStyle ) )
1597 MSO_LineCap eLineCap = (MSO_LineCap)GetPropertyValue( DFF_Prop_lineEndCapStyle );
1598 const SfxPoolItem* pPoolItem = NULL;
1599 if ( rSet.GetItemState( XATTR_LINEDASH, FALSE, &pPoolItem ) == SFX_ITEM_SET )
1601 XDashStyle eNewStyle = XDASH_RECT;
1602 if ( eLineCap == mso_lineEndCapRound )
1603 eNewStyle = XDASH_ROUND;
1604 const XDash& rOldDash = ( (const XLineDashItem*)pPoolItem )->GetDashValue();
1605 if ( rOldDash.GetDashStyle() != eNewStyle )
1607 XDash aNew( rOldDash );
1608 aNew.SetDashStyle( eNewStyle );
1609 rSet.Put( XLineDashItem( XubString(), aNew ) );
1615 else
1616 rSet.Put( XLineStyleItem( XLINE_NONE ) );
1619 struct ShadeColor
1621 Color aColor;
1622 double fDist;
1624 ShadeColor( const Color& rC, double fR ) : aColor( rC ), fDist( fR ) {};
1627 void GetShadeColors( const SvxMSDffManager& rManager, const DffPropertyReader& rProperties, SvStream& rIn, std::vector< ShadeColor >& rShadeColors )
1629 sal_uInt32 nPos = rIn.Tell();
1630 if ( rProperties.IsProperty( DFF_Prop_fillShadeColors ) )
1632 if ( rProperties.SeekToContent( DFF_Prop_fillShadeColors, rIn ) )
1634 sal_uInt16 i = 0, nNumElem = 0, nNumElemReserved = 0, nSize = 0;
1635 rIn >> nNumElem >> nNumElemReserved >> nSize;
1636 for ( ; i < nNumElem; i++ )
1638 sal_Int32 nColor;
1639 sal_Int32 nDist;
1641 rIn >> nColor >> nDist;
1642 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( nColor, DFF_Prop_fillColor ), 1.0 - ( nDist / 65536.0 ) ) );
1646 if ( !rShadeColors.size() )
1648 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ), 0 ) );
1649 rShadeColors.push_back( ShadeColor( rManager.MSO_CLR_ToColor( rProperties.GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ), 1 ) );
1651 rIn.Seek( nPos );
1654 struct QuantErr
1656 double fRed;
1657 double fGreen;
1658 double fBlue;
1660 QuantErr() : fRed( 0.0 ), fGreen( 0.0 ), fBlue( 0.0 ){};
1663 void ApplyRectangularGradientAsBitmap( const SvxMSDffManager& rManager, SvStream& rIn, SfxItemSet& rSet, const std::vector< ShadeColor >& rShadeColors, const DffObjData& rObjData, sal_Int32 nFix16Angle )
1665 Size aBitmapSizePixel( static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetWidth() / 2540.0 ) * 90.0 ), // we will create a bitmap with 90 dpi
1666 static_cast< sal_Int32 >( ( rObjData.aBoundRect.GetHeight() / 2540.0 ) * 90.0 ) );
1667 if ( aBitmapSizePixel.Width() && aBitmapSizePixel.Height() && ( aBitmapSizePixel.Width() <= 1024 ) && ( aBitmapSizePixel.Height() <= 1024 ) )
1669 // std::vector< QuantErr > aQuantErrCurrScan( aBitmapSizePixel.Width() + 1 );
1670 // std::vector< QuantErr > aQuantErrNextScan( aBitmapSizePixel.Width() + 1 );
1672 double fFocusX = rManager.GetPropertyValue( DFF_Prop_fillToRight, 0 ) / 65536.0;
1673 double fFocusY = rManager.GetPropertyValue( DFF_Prop_fillToBottom, 0 ) / 65536.0;
1675 Bitmap aBitmap( aBitmapSizePixel, 24 );
1676 BitmapWriteAccess* pAcc = aBitmap.AcquireWriteAccess();
1677 if ( pAcc )
1679 sal_Int32 nX, nY;
1680 for ( nY = 0; nY < aBitmapSizePixel.Height(); nY++ )
1682 for ( nX = 0; nX < aBitmapSizePixel.Width(); nX++ )
1684 double fX = static_cast< double >( nX ) / aBitmapSizePixel.Width();
1685 double fY = static_cast< double >( nY ) / aBitmapSizePixel.Height();
1687 double fD, fDist;
1688 if ( fX < fFocusX )
1690 if ( fY < fFocusY )
1692 if ( fX > fY )
1693 fDist = fY, fD = fFocusY;
1694 else
1695 fDist = fX, fD = fFocusX;
1697 else
1699 if ( fX > ( 1 - fY ) )
1700 fDist = ( 1 - fY ), fD = 1 - fFocusY;
1701 else
1702 fDist = fX, fD = fFocusX;
1705 else
1707 if ( fY < fFocusY )
1709 if ( ( 1 - fX ) > fY )
1710 fDist = fY, fD = fFocusY;
1711 else
1712 fDist = ( 1 - fX ), fD = 1 - fFocusX;
1714 else
1716 if ( ( 1 - fX ) > ( 1 - fY ) )
1717 fDist = ( 1 - fY ), fD = 1 - fFocusY;
1718 else
1719 fDist = ( 1 - fX ), fD = 1 - fFocusX;
1722 if ( fD != 0.0 )
1723 fDist /= fD;
1725 std::vector< ShadeColor >::const_iterator aIter( rShadeColors.begin() );
1726 double fA = 0.0;
1727 Color aColorA = aIter->aColor;
1728 double fB = 1.0;
1729 Color aColorB( aColorA );
1730 while ( aIter != rShadeColors.end() )
1732 if ( aIter->fDist <= fDist )
1734 if ( aIter->fDist >= fA )
1736 fA = aIter->fDist;
1737 aColorA = aIter->aColor;
1740 if ( aIter->fDist > fDist )
1742 if ( aIter->fDist <= fB )
1744 fB = aIter->fDist;
1745 aColorB = aIter->aColor;
1748 aIter++;
1750 double fRed = aColorA.GetRed(), fGreen = aColorA.GetGreen(), fBlue = aColorA.GetBlue();
1751 double fD1 = fB - fA;
1752 if ( fD1 != 0.0 )
1754 fRed += ( ( ( fDist - fA ) * ( aColorB.GetRed() - aColorA.GetRed() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fRed;
1755 fGreen += ( ( ( fDist - fA ) * ( aColorB.GetGreen() - aColorA.GetGreen() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fGreen;
1756 fBlue += ( ( ( fDist - fA ) * ( aColorB.GetBlue() - aColorA.GetBlue() ) ) / fD1 ); // + aQuantErrCurrScan[ nX ].fBlue;
1758 sal_Int16 nRed = static_cast< sal_Int16 >( fRed + 0.5 );
1759 sal_Int16 nGreen = static_cast< sal_Int16 >( fGreen + 0.5 );
1760 sal_Int16 nBlue = static_cast< sal_Int16 >( fBlue + 0.5 );
1762 double fErr = fRed - nRed;
1763 aQuantErrCurrScan[ nX + 1 ].fRed += 7.0 * fErr / 16.0;
1764 if ( nX )
1765 aQuantErrNextScan[ nX - 1 ].fRed += 3.0 * fErr / 16.0;
1766 aQuantErrNextScan[ nX ].fRed += 5.0 * fErr / 16.0;
1767 aQuantErrNextScan[ nX + 1 ].fRed += 1.0 * fErr / 16.0;
1769 fErr = fGreen - nGreen;
1770 aQuantErrCurrScan[ nX + 1 ].fGreen += 7.0 * fErr / 16.0;
1771 if ( nX )
1772 aQuantErrNextScan[ nX - 1 ].fGreen += 3.0 * fErr / 16.0;
1773 aQuantErrNextScan[ nX ].fGreen += 5.0 * fErr / 16.0;
1774 aQuantErrNextScan[ nX + 1 ].fGreen += 1.0 * fErr / 16.0;
1776 fErr = fBlue - nBlue;
1777 aQuantErrCurrScan[ nX + 1 ].fBlue += 7.0 * fErr / 16.0;
1778 if ( nX )
1779 aQuantErrNextScan[ nX - 1 ].fBlue += 3.0 * fErr / 16.0;
1780 aQuantErrNextScan[ nX ].fBlue += 5.0 * fErr / 16.0;
1781 aQuantErrNextScan[ nX + 1 ].fBlue += 1.0 * fErr / 16.0;
1783 if ( nRed < 0 )
1784 nRed = 0;
1785 if ( nRed > 255 )
1786 nRed = 255;
1787 if ( nGreen < 0 )
1788 nGreen = 0;
1789 if ( nGreen > 255 )
1790 nGreen = 255;
1791 if ( nBlue < 0 )
1792 nBlue = 0;
1793 if ( nBlue > 255 )
1794 nBlue = 255;
1796 pAcc->SetPixel( nY, nX, BitmapColor( static_cast< sal_Int8 >( nRed ), static_cast< sal_Int8 >( nGreen ), static_cast< sal_Int8 >( nBlue ) ) );
1799 aQuantErrCurrScan.swap( aQuantErrNextScan );
1800 std::vector< QuantErr >::iterator aIter( aQuantErrNextScan.begin() );
1801 while( aIter != aQuantErrNextScan.end() )
1803 *aIter = QuantErr();
1804 aIter++;
1808 aBitmap.ReleaseAccess( pAcc );
1810 if ( nFix16Angle )
1812 sal_Bool bRotateWithShape = sal_True; // TRUE seems to be default
1813 sal_uInt32 nPos = rIn.Tell();
1814 if ( const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.SeekToContent( rIn, DFF_msofbtUDefProp, SEEK_FROM_CURRENT_AND_RESTART ) )
1816 const_cast< SvxMSDffManager& >( rManager ).maShapeRecords.Current()->SeekToBegOfRecord( rIn );
1817 DffPropertyReader aSecPropSet( rManager );
1818 aSecPropSet.ReadPropSet( rIn, NULL );
1819 sal_Int32 nSecFillProperties = aSecPropSet.GetPropertyValue( DFF_Prop_fNoFillHitTest, 0x200020 );
1820 bRotateWithShape = ( nSecFillProperties & 0x0020 );
1822 rIn.Seek( nPos );
1823 if ( bRotateWithShape )
1825 aBitmap.Rotate( nFix16Angle / 10, rShadeColors[ 0 ].aColor );
1827 ULONG nMirrorFlags = BMP_MIRROR_NONE;
1828 if ( rObjData.nSpFlags & SP_FFLIPV )
1829 nMirrorFlags |= BMP_MIRROR_VERT;
1830 if ( rObjData.nSpFlags & SP_FFLIPH )
1831 nMirrorFlags |= BMP_MIRROR_HORZ;
1832 if ( nMirrorFlags != BMP_MIRROR_NONE )
1833 aBitmap.Mirror( nMirrorFlags );
1837 XOBitmap aXBmp( aBitmap, XBITMAP_STRETCH );
1838 rSet.Put( XFillBmpTileItem( sal_False ) );
1839 rSet.Put( XFillBitmapItem( String(), aXBmp ) );
1844 void DffPropertyReader::ApplyFillAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
1846 UINT32 nFillFlags(GetPropertyValue( DFF_Prop_fNoFillHitTest ));
1848 std::vector< ShadeColor > aShadeColors;
1849 GetShadeColors( rManager, *this, rIn, aShadeColors );
1851 if(!IsHardAttribute( DFF_Prop_fFilled ) && !IsCustomShapeFilledByDefault( rObjData.eShapeType ))
1853 nFillFlags &= ~0x10;
1856 if ( nFillFlags & 0x10 )
1858 MSO_FillType eMSO_FillType = (MSO_FillType)GetPropertyValue( DFF_Prop_fillType, mso_fillSolid );
1859 XFillStyle eXFill = XFILL_NONE;
1860 switch( eMSO_FillType )
1862 case mso_fillSolid : // Fill with a solid color
1863 eXFill = XFILL_SOLID;
1864 break;
1865 case mso_fillPattern : // Fill with a pattern (bitmap)
1866 case mso_fillTexture : // A texture (pattern with its own color map)
1867 case mso_fillPicture : // Center a picture in the shape
1868 eXFill = XFILL_BITMAP;
1869 break;
1870 case mso_fillShadeCenter : // Shade from bounding rectangle to end point
1872 if ( rObjData.aBoundRect.IsEmpty() )// size of object needed to be able
1873 eXFill = XFILL_GRADIENT; // to create a bitmap substitution
1874 else
1875 eXFill = XFILL_BITMAP;
1877 break;
1878 case mso_fillShade : // Shade from start to end points
1879 case mso_fillShadeShape : // Shade from shape outline to end point
1880 case mso_fillShadeScale : // Similar to mso_fillShade, but the fillAngle
1881 case mso_fillShadeTitle : // special type - shade to title --- for PP
1882 eXFill = XFILL_GRADIENT;
1883 break;
1884 // case mso_fillBackground : // Use the background fill color/pattern
1885 default: break;
1887 rSet.Put( XFillStyleItem( eXFill ) );
1889 if (IsProperty(DFF_Prop_fillOpacity))
1891 double nTrans = GetPropertyValue(DFF_Prop_fillOpacity);
1892 nTrans = (nTrans * 100) / 65536;
1893 rSet.Put(XFillTransparenceItem(
1894 sal_uInt16(100 - ::rtl::math::round(nTrans))));
1897 if ( ( eMSO_FillType == mso_fillShadeCenter ) && ( eXFill == XFILL_BITMAP ) )
1899 ApplyRectangularGradientAsBitmap( rManager, rIn, rSet, aShadeColors, rObjData, mnFix16Angle );
1901 else if ( eXFill == XFILL_GRADIENT )
1903 sal_Int32 nAngle = 3600 - ( ( Fix16ToAngle( GetPropertyValue( DFF_Prop_fillAngle, 0 ) ) + 5 ) / 10 );
1905 // Rotationswinkel in Bereich zwingen
1906 while ( nAngle >= 3600 )
1907 nAngle -= 3600;
1908 while ( nAngle < 0 )
1909 nAngle += 3600;
1911 sal_Int32 nFocus = GetPropertyValue( DFF_Prop_fillFocus, 0 );
1912 XGradientStyle eGrad = XGRAD_LINEAR;
1913 sal_Int32 nChgColors = 0;
1915 if ( nFocus < 0 ) // Bei negativem Focus sind die Farben zu tauschen
1917 nFocus =- nFocus;
1918 nChgColors ^= 1;
1920 if( nFocus > 40 && nFocus < 60 )
1922 eGrad = XGRAD_AXIAL; // Besser gehts leider nicht
1925 USHORT nFocusX = (USHORT)nFocus;
1926 USHORT nFocusY = (USHORT)nFocus;
1928 switch( eMSO_FillType )
1930 case mso_fillShadeShape :
1932 eGrad = XGRAD_RECT;
1933 nFocusY = nFocusX = 50;
1934 nChgColors ^= 1;
1936 break;
1937 case mso_fillShadeCenter :
1939 eGrad = XGRAD_RECT;
1940 nFocusX = ( IsProperty( DFF_Prop_fillToRight ) ) ? 100 : 0;
1941 nFocusY = ( IsProperty( DFF_Prop_fillToBottom ) ) ? 100 : 0;
1942 nChgColors ^= 1;
1944 break;
1945 default: break;
1947 Color aCol1( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor, COL_WHITE ), DFF_Prop_fillColor ) );
1948 Color aCol2( rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor, COL_WHITE ), DFF_Prop_fillBackColor ) );
1950 if ( nChgColors )
1952 Color aZwi( aCol1 );
1953 aCol1 = aCol2;
1954 aCol2 = aZwi;
1956 XGradient aGrad( aCol2, aCol1, eGrad, nAngle, nFocusX, nFocusY );
1957 aGrad.SetStartIntens( 100 );
1958 aGrad.SetEndIntens( 100 );
1959 rSet.Put( XFillGradientItem( String(), aGrad ) );
1961 else if ( eXFill == XFILL_BITMAP )
1963 if( IsProperty( DFF_Prop_fillBlip ) )
1965 Graphic aGraf;
1966 // first try to get BLIP from cache
1967 BOOL bOK = rManager.GetBLIP( GetPropertyValue( DFF_Prop_fillBlip ), aGraf, NULL );
1968 // then try directly from stream (i.e. Excel chart hatches/bitmaps)
1969 if ( !bOK )
1970 bOK = SeekToContent( DFF_Prop_fillBlip, rIn ) && rManager.GetBLIPDirect( rIn, aGraf, NULL );
1971 if ( bOK )
1973 Bitmap aBmp( aGraf.GetBitmap() );
1975 if ( eMSO_FillType == mso_fillPattern )
1977 Color aCol1( COL_WHITE ), aCol2( COL_WHITE );
1978 if ( IsProperty( DFF_Prop_fillColor ) )
1979 aCol1 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillColor ), DFF_Prop_fillColor );
1980 if ( IsProperty( DFF_Prop_fillBackColor ) )
1981 aCol2 = rManager.MSO_CLR_ToColor( GetPropertyValue( DFF_Prop_fillBackColor ), DFF_Prop_fillBackColor );
1983 XOBitmap aXOBitmap;
1985 // Bitmap einsetzen
1986 aXOBitmap.SetBitmap( aBmp );
1987 aXOBitmap.SetBitmapType( XBITMAP_IMPORT );
1989 if( aBmp.GetSizePixel().Width() == 8 && aBmp.GetSizePixel().Height() == 8 && aBmp.GetColorCount() == 2)
1991 aXOBitmap.Bitmap2Array();
1992 aXOBitmap.SetBitmapType( XBITMAP_8X8 );
1993 aXOBitmap.SetPixelSize( aBmp.GetSizePixel() );
1995 if( aXOBitmap.GetBackgroundColor() == COL_BLACK )
1997 aXOBitmap.SetPixelColor( aCol1 );
1998 aXOBitmap.SetBackgroundColor( aCol2 );
2000 else
2002 aXOBitmap.SetPixelColor( aCol2 );
2003 aXOBitmap.SetBackgroundColor( aCol1 );
2006 rSet.Put( XFillBitmapItem( String(), aXOBitmap ) );
2008 else if ( eMSO_FillType == mso_fillTexture )
2010 XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
2011 rSet.Put( XFillBmpTileItem( sal_True ) );
2012 rSet.Put( XFillBitmapItem( String(), aXBmp ) );
2013 rSet.Put( XFillBmpSizeXItem( GetPropertyValue( DFF_Prop_fillWidth, 0 ) / 360 ) );
2014 rSet.Put( XFillBmpSizeYItem( GetPropertyValue( DFF_Prop_fillHeight, 0 ) / 360 ) );
2015 rSet.Put( XFillBmpSizeLogItem( sal_True ) );
2017 else
2019 XOBitmap aXBmp( aBmp, XBITMAP_STRETCH );
2020 rSet.Put( XFillBitmapItem( String(), aXBmp ) );
2021 rSet.Put( XFillBmpTileItem( sal_False ) );
2027 else
2028 rSet.Put( XFillStyleItem( XFILL_NONE ) );
2031 void DffPropertyReader::ApplyCustomShapeTextAttributes( SfxItemSet& rSet ) const
2033 // sal_uInt32 nTextFlags = aTextObj.GetTextFlags();
2034 sal_Bool bVerticalText = sal_False;
2035 sal_Int32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 25 * 3600 ) / 360; // 0.25 cm (emu)
2036 sal_Int32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 25 * 3600 ) / 360; // 0.25 cm (emu)
2037 sal_Int32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 13 * 3600 ) / 360; // 0.13 cm (emu)
2038 sal_Int32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 13 * 3600 ) /360; // 0.13 cm (emu)
2040 SdrTextVertAdjust eTVA;
2041 SdrTextHorzAdjust eTHA;
2043 if ( IsProperty( DFF_Prop_txflTextFlow ) )
2045 MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
2046 switch( eTextFlow )
2048 case mso_txflTtoBA : /* #68110# */ // Top to Bottom @-font, oben -> unten
2049 case mso_txflTtoBN : // Top to Bottom non-@, oben -> unten
2050 case mso_txflVertN : // Vertical, non-@, oben -> unten
2051 bVerticalText = sal_True; // nTextRotationAngle += 27000;
2052 break;
2053 default: break;
2056 sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 );
2057 if ( ( nFontDirection == 1 ) || ( nFontDirection == 3 ) )
2058 bVerticalText = !bVerticalText;
2060 if ( bVerticalText )
2062 eTVA = SDRTEXTVERTADJUST_BLOCK;
2063 eTHA = SDRTEXTHORZADJUST_CENTER;
2065 // Textverankerung lesen
2066 MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
2068 switch( eTextAnchor )
2070 case mso_anchorTop:
2071 case mso_anchorTopCentered:
2072 case mso_anchorTopBaseline:
2073 case mso_anchorTopCenteredBaseline:
2074 eTHA = SDRTEXTHORZADJUST_RIGHT;
2075 break;
2077 case mso_anchorMiddle :
2078 case mso_anchorMiddleCentered:
2079 eTHA = SDRTEXTHORZADJUST_CENTER;
2080 break;
2082 case mso_anchorBottom:
2083 case mso_anchorBottomCentered:
2084 case mso_anchorBottomBaseline:
2085 case mso_anchorBottomCenteredBaseline:
2086 eTHA = SDRTEXTHORZADJUST_LEFT;
2087 break;
2089 // if there is a 100% use of following attributes, the textbox can been aligned also in vertical direction
2090 switch ( eTextAnchor )
2092 case mso_anchorTopCentered :
2093 case mso_anchorMiddleCentered :
2094 case mso_anchorBottomCentered :
2095 case mso_anchorTopCenteredBaseline:
2096 case mso_anchorBottomCenteredBaseline:
2097 eTVA = SDRTEXTVERTADJUST_CENTER;
2098 break;
2100 default :
2101 eTVA = SDRTEXTVERTADJUST_TOP;
2102 break;
2105 else
2107 eTVA = SDRTEXTVERTADJUST_CENTER;
2108 eTHA = SDRTEXTHORZADJUST_BLOCK;
2110 // Textverankerung lesen
2111 MSO_Anchor eTextAnchor = (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText, mso_anchorTop );
2113 switch( eTextAnchor )
2115 case mso_anchorTop:
2116 case mso_anchorTopCentered:
2117 case mso_anchorTopBaseline:
2118 case mso_anchorTopCenteredBaseline:
2119 eTVA = SDRTEXTVERTADJUST_TOP;
2120 break;
2122 case mso_anchorMiddle :
2123 case mso_anchorMiddleCentered:
2124 eTVA = SDRTEXTVERTADJUST_CENTER;
2125 break;
2127 case mso_anchorBottom:
2128 case mso_anchorBottomCentered:
2129 case mso_anchorBottomBaseline:
2130 case mso_anchorBottomCenteredBaseline:
2131 eTVA = SDRTEXTVERTADJUST_BOTTOM;
2132 break;
2134 // if there is a 100% usage of following attributes, the textbox can be aligned also in horizontal direction
2135 switch ( eTextAnchor )
2137 case mso_anchorTopCentered :
2138 case mso_anchorMiddleCentered :
2139 case mso_anchorBottomCentered :
2140 case mso_anchorTopCenteredBaseline:
2141 case mso_anchorBottomCenteredBaseline:
2142 eTHA = SDRTEXTHORZADJUST_CENTER; // the text has to be displayed using the full width;
2143 break;
2145 default :
2146 eTHA = SDRTEXTHORZADJUST_LEFT;
2147 break;
2150 rSet.Put( SvxFrameDirectionItem( bVerticalText ? FRMDIR_VERT_TOP_RIGHT : FRMDIR_HORI_LEFT_TOP, EE_PARA_WRITINGDIR ) );
2152 rSet.Put( SdrTextVertAdjustItem( eTVA ) );
2153 rSet.Put( SdrTextHorzAdjustItem( eTHA ) );
2155 rSet.Put( SdrTextLeftDistItem( nTextLeft ) );
2156 rSet.Put( SdrTextRightDistItem( nTextRight ) );
2157 rSet.Put( SdrTextUpperDistItem( nTextTop ) );
2158 rSet.Put( SdrTextLowerDistItem( nTextBottom ) );
2160 rSet.Put( SdrTextWordWrapItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_True : sal_False ) );
2161 rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
2163 // rSet.Put( SdrTextAutoGrowWidthItem( (MSO_WrapMode)GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) != mso_wrapNone ? sal_False : sal_True ) );
2164 // rSet.Put( SdrTextAutoGrowHeightItem( ( GetPropertyValue( DFF_Prop_FitTextToShape ) & 2 ) != 0 ) );
2167 void DffPropertyReader::ApplyCustomShapeGeometryAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
2170 sal_uInt32 nAdjustmentsWhichNeedsToBeConverted = 0;
2172 ///////////////////////////////////////
2173 // creating SdrCustomShapeGeometryItem //
2174 ///////////////////////////////////////
2175 typedef uno::Sequence< beans::PropertyValue > PropSeq;
2176 typedef std::vector< beans::PropertyValue > PropVec;
2177 typedef PropVec::iterator PropVecIter;
2178 PropVecIter aIter;
2179 PropVecIter aEnd;
2182 // aPropVec will be filled with all PropertyValues
2183 PropVec aPropVec;
2184 PropertyValue aProp;
2186 /////////////////////////////////////////////////////////////////////
2187 // "Type" property, including the predefined CustomShape type name //
2188 /////////////////////////////////////////////////////////////////////
2189 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
2190 aProp.Name = sType;
2191 aProp.Value <<= EnhancedCustomShapeTypeNames::Get( rObjData.eShapeType );
2192 aPropVec.push_back( aProp );
2195 /////////////////
2196 // "MirroredX" //
2197 /////////////////
2198 if ( nShapeFlags & SP_FFLIPH )
2200 const rtl::OUString sMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
2201 sal_Bool bMirroredX = sal_True;
2202 aProp.Name = sMirroredX;
2203 aProp.Value <<= bMirroredX;
2204 aPropVec.push_back( aProp );
2206 /////////////////
2207 // "MirroredY" //
2208 /////////////////
2209 if ( nShapeFlags & SP_FFLIPV )
2211 const rtl::OUString sMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
2212 sal_Bool bMirroredY = sal_True;
2213 aProp.Name = sMirroredY;
2214 aProp.Value <<= bMirroredY;
2215 aPropVec.push_back( aProp );
2218 ///////////////
2219 // "ViewBox" //
2220 ///////////////
2222 sal_Int32 nCoordWidth = 21600; // needed to replace handle type center with absolute value
2223 sal_Int32 nCoordHeight= 21600;
2224 if ( IsProperty( DFF_Prop_geoLeft ) || IsProperty( DFF_Prop_geoTop ) || IsProperty( DFF_Prop_geoRight ) || IsProperty( DFF_Prop_geoBottom ) )
2226 com::sun::star::awt::Rectangle aViewBox;
2227 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
2228 aViewBox.X = GetPropertyValue( DFF_Prop_geoLeft, 0 );
2229 aViewBox.Y = GetPropertyValue( DFF_Prop_geoTop, 0 );
2230 aViewBox.Width = nCoordWidth = ((sal_Int32)GetPropertyValue( DFF_Prop_geoRight, 21600 ) ) - aViewBox.X;
2231 aViewBox.Height = nCoordHeight = ((sal_Int32)GetPropertyValue( DFF_Prop_geoBottom, 21600 ) ) - aViewBox.Y;
2232 aProp.Name = sViewBox;
2233 aProp.Value <<= aViewBox;
2234 aPropVec.push_back( aProp );
2236 /////////////////////
2237 // TextRotateAngle //
2238 /////////////////////
2239 if ( IsProperty( DFF_Prop_txflTextFlow ) || IsProperty( DFF_Prop_cdirFont ) )
2241 sal_Int32 nTextRotateAngle = 0;
2242 MSO_TextFlow eTextFlow = (MSO_TextFlow)( GetPropertyValue( DFF_Prop_txflTextFlow ) & 0xFFFF );
2243 /* sal_Int32 nFontDirection = GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ); */
2245 if ( eTextFlow == mso_txflBtoT ) // Bottom to Top non-@, unten -> oben
2246 nTextRotateAngle += 90;
2247 switch( GetPropertyValue( DFF_Prop_cdirFont, mso_cdir0 ) ) // SJ: mso_cdir90 and mso_cdir270 will be simulated by
2248 { // activating vertical writing for the text objects
2249 case mso_cdir90 :
2251 if ( eTextFlow == mso_txflTtoBA )
2252 nTextRotateAngle -= 180;
2254 break;
2255 case mso_cdir180: nTextRotateAngle -= 180; break;
2256 case mso_cdir270:
2258 if ( eTextFlow != mso_txflTtoBA )
2259 nTextRotateAngle -= 180;
2261 break;
2262 default: break;
2264 if ( nTextRotateAngle )
2266 double fTextRotateAngle = nTextRotateAngle;
2267 const rtl::OUString sTextRotateAngle( RTL_CONSTASCII_USTRINGPARAM ( "TextRotateAngle" ) );
2268 aProp.Name = sTextRotateAngle;
2269 aProp.Value <<= fTextRotateAngle;
2270 aPropVec.push_back( aProp );
2273 //////////////////////////////////////////
2274 // "Extrusion" PropertySequence element //
2275 //////////////////////////////////////////
2276 sal_Bool bExtrusionOn = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 8 ) != 0;
2277 if ( bExtrusionOn )
2279 PropVec aExtrusionPropVec;
2281 // "Extrusion"
2282 const rtl::OUString sExtrusionOn( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
2283 aProp.Name = sExtrusionOn;
2284 aProp.Value <<= bExtrusionOn;
2285 aExtrusionPropVec.push_back( aProp );
2287 // "Brightness"
2288 if ( IsProperty( DFF_Prop_c3DAmbientIntensity ) )
2290 const rtl::OUString sExtrusionBrightness( RTL_CONSTASCII_USTRINGPARAM ( "Brightness" ) );
2291 double fBrightness = (sal_Int32)GetPropertyValue( DFF_Prop_c3DAmbientIntensity );
2292 fBrightness /= 655.36;
2293 aProp.Name = sExtrusionBrightness;
2294 aProp.Value <<= fBrightness;
2295 aExtrusionPropVec.push_back( aProp );
2297 // "Depth" in 1/100mm
2298 if ( IsProperty( DFF_Prop_c3DExtrudeBackward ) || IsProperty( DFF_Prop_c3DExtrudeForward ) )
2300 const rtl::OUString sDepth( RTL_CONSTASCII_USTRINGPARAM ( "Depth" ) );
2301 double fBackDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeBackward, 1270 * 360 )) / 360.0;
2302 double fForeDepth = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DExtrudeForward ), 0 ) / 360.0;
2303 double fDepth = fBackDepth + fForeDepth;
2304 double fFraction = fDepth != 0.0 ? fForeDepth / fDepth : 0;
2305 EnhancedCustomShapeParameterPair aDepthParaPair;
2306 aDepthParaPair.First.Value <<= fDepth;
2307 aDepthParaPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2308 aDepthParaPair.Second.Value <<= fFraction;
2309 aDepthParaPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2310 aProp.Name = sDepth;
2311 aProp.Value <<= aDepthParaPair;
2312 aExtrusionPropVec.push_back( aProp );
2314 // "Diffusion"
2315 if ( IsProperty( DFF_Prop_c3DDiffuseAmt ) )
2317 const rtl::OUString sExtrusionDiffusion( RTL_CONSTASCII_USTRINGPARAM ( "Diffusion" ) );
2318 double fDiffusion = (sal_Int32)GetPropertyValue( DFF_Prop_c3DDiffuseAmt );
2319 fDiffusion /= 655.36;
2320 aProp.Name = sExtrusionDiffusion;
2321 aProp.Value <<= fDiffusion;
2322 aExtrusionPropVec.push_back( aProp );
2324 // "NumberOfLineSegments"
2325 if ( IsProperty( DFF_Prop_c3DTolerance ) )
2327 const rtl::OUString sExtrusionNumberOfLineSegments( RTL_CONSTASCII_USTRINGPARAM ( "NumberOfLineSegments" ) );
2328 aProp.Name = sExtrusionNumberOfLineSegments;
2329 aProp.Value <<= (sal_Int32)GetPropertyValue( DFF_Prop_c3DTolerance );
2330 aExtrusionPropVec.push_back( aProp );
2332 // "LightFace"
2333 const rtl::OUString sExtrusionLightFace( RTL_CONSTASCII_USTRINGPARAM ( "LightFace" ) );
2334 sal_Bool bExtrusionLightFace = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 1 ) != 0;
2335 aProp.Name = sExtrusionLightFace;
2336 aProp.Value <<= bExtrusionLightFace;
2337 aExtrusionPropVec.push_back( aProp );
2338 // "FirstLightHarsh"
2339 const rtl::OUString sExtrusionFirstLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightHarsh" ) );
2340 sal_Bool bExtrusionFirstLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 2 ) != 0;
2341 aProp.Name = sExtrusionFirstLightHarsh;
2342 aProp.Value <<= bExtrusionFirstLightHarsh;
2343 aExtrusionPropVec.push_back( aProp );
2344 // "SecondLightHarsh"
2345 const rtl::OUString sExtrusionSecondLightHarsh( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightHarsh" ) );
2346 sal_Bool bExtrusionSecondLightHarsh = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 1 ) != 0;
2347 aProp.Name = sExtrusionSecondLightHarsh;
2348 aProp.Value <<= bExtrusionSecondLightHarsh;
2349 aExtrusionPropVec.push_back( aProp );
2350 // "FirstLightLevel"
2351 if ( IsProperty( DFF_Prop_c3DKeyIntensity ) )
2353 const rtl::OUString sExtrusionFirstLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightLevel" ) );
2354 double fFirstLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyIntensity );
2355 fFirstLightLevel /= 655.36;
2356 aProp.Name = sExtrusionFirstLightLevel;
2357 aProp.Value <<= fFirstLightLevel;
2358 aExtrusionPropVec.push_back( aProp );
2360 // "SecondLightLevel"
2361 if ( IsProperty( DFF_Prop_c3DFillIntensity ) )
2363 const rtl::OUString sExtrusionSecondLightLevel( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightLevel" ) );
2364 double fSecondLightLevel = (sal_Int32)GetPropertyValue( DFF_Prop_c3DFillIntensity );
2365 fSecondLightLevel /= 655.36;
2366 aProp.Name = sExtrusionSecondLightLevel;
2367 aProp.Value <<= fSecondLightLevel;
2368 aExtrusionPropVec.push_back( aProp );
2370 // "FirtstLightDirection"
2371 if ( IsProperty( DFF_Prop_c3DKeyX ) || IsProperty( DFF_Prop_c3DKeyY ) || IsProperty( DFF_Prop_c3DKeyZ ) )
2373 double fLightX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyX, 50000 ));
2374 double fLightY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyY, 0 ));
2375 double fLightZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DKeyZ, 10000 ));
2376 ::com::sun::star::drawing::Direction3D aExtrusionFirstLightDirection( fLightX, fLightY, fLightZ );
2377 const rtl::OUString sExtrusionFirstLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "FirstLightDirection" ) );
2378 aProp.Name = sExtrusionFirstLightDirection;
2379 aProp.Value <<= aExtrusionFirstLightDirection;
2380 aExtrusionPropVec.push_back( aProp );
2382 // "SecondLightDirection"
2383 if ( IsProperty( DFF_Prop_c3DFillX ) || IsProperty( DFF_Prop_c3DFillY ) || IsProperty( DFF_Prop_c3DFillZ ) )
2385 double fLight2X = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillX, (sal_uInt32)-50000 ));
2386 double fLight2Y = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillY, 0 ));
2387 double fLight2Z = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DFillZ, 10000 ));
2388 ::com::sun::star::drawing::Direction3D aExtrusionSecondLightDirection( fLight2X, fLight2Y, fLight2Z );
2389 const rtl::OUString sExtrusionSecondLightDirection( RTL_CONSTASCII_USTRINGPARAM ( "SecondLightDirection" ) );
2390 aProp.Name = sExtrusionSecondLightDirection;
2391 aProp.Value <<= aExtrusionSecondLightDirection;
2392 aExtrusionPropVec.push_back( aProp );
2395 /* LockRotationCenter, OrientationAngle and Orientation needs to be converted to use the properties AngleX, AngleY and RotationAngle instead.
2396 // "LockRotationCenter"
2397 const rtl::OUString sExtrusionLockRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "LockRotationCenter" ) );
2398 sal_Bool bExtrusionLockRotationCenter = ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 16 ) != 0;
2399 aProp.Name = sExtrusionLockRotationCenter;
2400 aProp.Value <<= bExtrusionLockRotationCenter;
2401 aExtrusionPropVec.push_back( aProp );
2403 // "Orientation"
2404 if ( IsProperty( DFF_Prop_c3DRotationAxisX ) || IsProperty( DFF_Prop_c3DRotationAxisY ) || IsProperty( DFF_Prop_c3DRotationAxisZ ) )
2406 double fRotX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisX, 100 ));
2407 double fRotY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisY, 0 ));
2408 double fRotZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAxisZ, 0 ));
2409 ::com::sun::star::drawing::Direction3D aExtrusionDirection( fRotX, fRotY, fRotZ );
2410 const rtl::OUString sExtrusionDirection( RTL_CONSTASCII_USTRINGPARAM ( "Orientation" ) );
2411 aProp.Name = sExtrusionDirection;
2412 aProp.Value <<= aExtrusionDirection;
2413 aExtrusionPropVec.push_back( aProp );
2415 // "OrientationAngle" in Grad
2416 if ( IsProperty( DFF_Prop_c3DRotationAngle ) )
2418 const rtl::OUString sExtrusionOrientationAngle( RTL_CONSTASCII_USTRINGPARAM ( "OrientationAngle" ) );
2419 double fOrientationAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationAngle )) / 65536.0;
2420 aProp.Name = sExtrusionOrientationAngle;
2421 aProp.Value <<= fOrientationAngle;
2422 aExtrusionPropVec.push_back( aProp );
2426 // "Metal"
2427 const rtl::OUString sExtrusionMetal( RTL_CONSTASCII_USTRINGPARAM ( "Metal" ) );
2428 sal_Bool bExtrusionMetal = ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 4 ) != 0;
2429 aProp.Name = sExtrusionMetal;
2430 aProp.Value <<= bExtrusionMetal;
2431 aExtrusionPropVec.push_back( aProp );
2432 // if ( IsProperty( DFF_Prop_c3DExtrudePlane ) )
2433 // {
2434 // UPS
2435 // }
2436 // "ShadeMode"
2437 if ( IsProperty( DFF_Prop_c3DRenderMode ) )
2439 const rtl::OUString sExtrusionShadeMode( RTL_CONSTASCII_USTRINGPARAM ( "ShadeMode" ) );
2440 sal_uInt32 nExtrusionRenderMode = GetPropertyValue( DFF_Prop_c3DRenderMode );
2441 com::sun::star::drawing::ShadeMode eExtrusionShadeMode( com::sun::star::drawing::ShadeMode_FLAT );
2442 if ( nExtrusionRenderMode == mso_Wireframe )
2443 eExtrusionShadeMode = com::sun::star::drawing::ShadeMode_DRAFT;
2445 aProp.Name = sExtrusionShadeMode;
2446 aProp.Value <<= eExtrusionShadeMode;
2447 aExtrusionPropVec.push_back( aProp );
2449 // "RotateAngle" in Grad
2450 if ( IsProperty( DFF_Prop_c3DXRotationAngle ) || IsProperty( DFF_Prop_c3DYRotationAngle ) )
2452 const rtl::OUString sExtrusionAngle( RTL_CONSTASCII_USTRINGPARAM ( "RotateAngle" ) );
2453 double fAngleX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXRotationAngle, 0 )) / 65536.0;
2454 double fAngleY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYRotationAngle, 0 )) / 65536.0;
2455 EnhancedCustomShapeParameterPair aRotateAnglePair;
2456 aRotateAnglePair.First.Value <<= fAngleX;
2457 aRotateAnglePair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2458 aRotateAnglePair.Second.Value <<= fAngleY;
2459 aRotateAnglePair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2460 aProp.Name = sExtrusionAngle;
2461 aProp.Value <<= aRotateAnglePair;
2462 aExtrusionPropVec.push_back( aProp );
2465 // "AutoRotationCenter"
2466 if ( ( GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 8 ) == 0 )
2468 // "RotationCenter"
2469 if ( IsProperty( DFF_Prop_c3DRotationCenterX ) || IsProperty( DFF_Prop_c3DRotationCenterY ) || IsProperty( DFF_Prop_c3DRotationCenterZ ) )
2471 ::com::sun::star::drawing::Direction3D aRotationCenter(
2472 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterX, 0 )) / 360.0,
2473 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterY, 0 )) / 360.0,
2474 (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DRotationCenterZ, 0 )) / 360.0 );
2476 const rtl::OUString sExtrusionRotationCenter( RTL_CONSTASCII_USTRINGPARAM ( "RotationCenter" ) );
2477 aProp.Name = sExtrusionRotationCenter;
2478 aProp.Value <<= aRotationCenter;
2479 aExtrusionPropVec.push_back( aProp );
2482 // "Shininess"
2483 if ( IsProperty( DFF_Prop_c3DShininess ) )
2485 const rtl::OUString sExtrusionShininess( RTL_CONSTASCII_USTRINGPARAM ( "Shininess" ) );
2486 double fShininess = (sal_Int32)GetPropertyValue( DFF_Prop_c3DShininess );
2487 fShininess /= 655.36;
2488 aProp.Name = sExtrusionShininess;
2489 aProp.Value <<= fShininess;
2490 aExtrusionPropVec.push_back( aProp );
2492 // "Skew"
2493 if ( IsProperty( DFF_Prop_c3DSkewAmount ) || IsProperty( DFF_Prop_c3DSkewAngle ) )
2495 const rtl::OUString sExtrusionSkew( RTL_CONSTASCII_USTRINGPARAM ( "Skew" ) );
2496 double fSkewAmount = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAmount, 50 );
2497 double fSkewAngle = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DSkewAngle, sal::static_int_cast< UINT32 >(-135 * 65536) )) / 65536.0;
2499 EnhancedCustomShapeParameterPair aSkewPair;
2500 aSkewPair.First.Value <<= fSkewAmount;
2501 aSkewPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2502 aSkewPair.Second.Value <<= fSkewAngle;
2503 aSkewPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2504 aProp.Name = sExtrusionSkew;
2505 aProp.Value <<= aSkewPair;
2506 aExtrusionPropVec.push_back( aProp );
2508 // "Specularity"
2509 if ( IsProperty( DFF_Prop_c3DSpecularAmt ) )
2511 const rtl::OUString sExtrusionSpecularity( RTL_CONSTASCII_USTRINGPARAM ( "Specularity" ) );
2512 double fSpecularity = (sal_Int32)GetPropertyValue( DFF_Prop_c3DSpecularAmt );
2513 fSpecularity /= 1333;
2514 aProp.Name = sExtrusionSpecularity;
2515 aProp.Value <<= fSpecularity;
2516 aExtrusionPropVec.push_back( aProp );
2518 // "ProjectionMode"
2519 const rtl::OUString sExtrusionProjectionMode( RTL_CONSTASCII_USTRINGPARAM ( "ProjectionMode" ) );
2520 ProjectionMode eProjectionMode = GetPropertyValue( DFF_Prop_fc3DFillHarsh ) & 4 ? ProjectionMode_PARALLEL : ProjectionMode_PERSPECTIVE;
2521 aProp.Name = sExtrusionProjectionMode;
2522 aProp.Value <<= eProjectionMode;
2523 aExtrusionPropVec.push_back( aProp );
2525 // "ViewPoint" in 1/100mm
2526 if ( IsProperty( DFF_Prop_c3DXViewpoint ) || IsProperty( DFF_Prop_c3DYViewpoint ) || IsProperty( DFF_Prop_c3DZViewpoint ) )
2528 double fViewX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DXViewpoint, 1249920 )) / 360.0;
2529 double fViewY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DYViewpoint, (sal_uInt32)-1249920 ))/ 360.0;
2530 double fViewZ = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DZViewpoint, 9000000 )) / 360.0;
2531 ::com::sun::star::drawing::Position3D aExtrusionViewPoint( fViewX, fViewY, fViewZ );
2532 const rtl::OUString sExtrusionViewPoint( RTL_CONSTASCII_USTRINGPARAM ( "ViewPoint" ) );
2533 aProp.Name = sExtrusionViewPoint;
2534 aProp.Value <<= aExtrusionViewPoint;
2535 aExtrusionPropVec.push_back( aProp );
2537 // "Origin"
2538 if ( IsProperty( DFF_Prop_c3DOriginX ) || IsProperty( DFF_Prop_c3DOriginY ) )
2540 const rtl::OUString sExtrusionOrigin( RTL_CONSTASCII_USTRINGPARAM ( "Origin" ) );
2541 double fOriginX = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginX, 0 ));
2542 double fOriginY = (double)((sal_Int32)GetPropertyValue( DFF_Prop_c3DOriginY, 0 ));
2543 fOriginX /= 65536;
2544 fOriginY /= 65536;
2545 EnhancedCustomShapeParameterPair aOriginPair;
2546 aOriginPair.First.Value <<= fOriginX;
2547 aOriginPair.First.Type = EnhancedCustomShapeParameterType::NORMAL;
2548 aOriginPair.Second.Value <<= fOriginY;
2549 aOriginPair.Second.Type = EnhancedCustomShapeParameterType::NORMAL;
2550 aProp.Name = sExtrusionOrigin;
2551 aProp.Value <<= aOriginPair;
2552 aExtrusionPropVec.push_back( aProp );
2554 // "ExtrusionColor"
2555 const rtl::OUString sExtrusionColor( RTL_CONSTASCII_USTRINGPARAM ( "Color" ) );
2556 sal_Bool bExtrusionColor = IsProperty( DFF_Prop_c3DExtrusionColor ); // ( GetPropertyValue( DFF_Prop_fc3DLightFace ) & 2 ) != 0;
2557 aProp.Name = sExtrusionColor;
2558 aProp.Value <<= bExtrusionColor;
2559 aExtrusionPropVec.push_back( aProp );
2560 if ( IsProperty( DFF_Prop_c3DExtrusionColor ) )
2561 rSet.Put( XSecondaryFillColorItem( String(), rManager.MSO_CLR_ToColor(
2562 GetPropertyValue( DFF_Prop_c3DExtrusionColor ), DFF_Prop_c3DExtrusionColor ) ) );
2563 // pushing the whole Extrusion element
2564 const rtl::OUString sExtrusion( RTL_CONSTASCII_USTRINGPARAM ( "Extrusion" ) );
2565 PropSeq aExtrusionPropSeq( aExtrusionPropVec.size() );
2566 aIter = aExtrusionPropVec.begin();
2567 aEnd = aExtrusionPropVec.end();
2568 beans::PropertyValue* pExtrusionValues = aExtrusionPropSeq.getArray();
2569 while ( aIter != aEnd )
2570 *pExtrusionValues++ = *aIter++;
2571 aProp.Name = sExtrusion;
2572 aProp.Value <<= aExtrusionPropSeq;
2573 aPropVec.push_back( aProp );
2576 /////////////////////////////////////////
2577 // "Equations" PropertySequence element //
2578 /////////////////////////////////////////
2579 if ( IsProperty( DFF_Prop_pFormulas ) )
2581 sal_uInt16 i;
2582 sal_uInt16 nNumElem = 0;
2583 sal_uInt16 nNumElemMem = 0;
2584 sal_uInt16 nElemSize = 8;
2586 if ( SeekToContent( DFF_Prop_pFormulas, rIn ) )
2587 rIn >> nNumElem >> nNumElemMem >> nElemSize;
2589 sal_Int16 nP1, nP2, nP3;
2590 sal_uInt16 nFlags;
2592 uno::Sequence< rtl::OUString > aEquations( nNumElem );
2593 for ( i = 0; i < nNumElem; i++ )
2595 rIn >> nFlags >> nP1 >> nP2 >> nP3;
2596 aEquations[ i ] = EnhancedCustomShape2d::GetEquation( nFlags, nP1, nP2, nP3 );
2598 // pushing the whole Equations element
2599 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
2600 aProp.Name = sEquations;
2601 aProp.Value <<= aEquations;
2602 aPropVec.push_back( aProp );
2605 ////////////////////////////////////////
2606 // "Handles" PropertySequence element //
2607 ////////////////////////////////////////
2608 if ( IsProperty( DFF_Prop_Handles ) )
2610 sal_uInt16 i;
2611 sal_uInt16 nNumElem = 0;
2612 sal_uInt16 nNumElemMem = 0;
2613 sal_uInt16 nElemSize = 36;
2615 if ( SeekToContent( DFF_Prop_Handles, rIn ) )
2616 rIn >> nNumElem >> nNumElemMem >> nElemSize;
2617 if ( nElemSize == 36 )
2619 uno::Sequence< beans::PropertyValues > aHandles( nNumElem );
2620 for ( i = 0; i < nNumElem; i++ )
2622 PropVec aHandlePropVec;
2623 sal_uInt32 nFlags;
2624 sal_Int32 nPositionX, nPositionY, nCenterX, nCenterY, nRangeXMin, nRangeXMax, nRangeYMin, nRangeYMax;
2625 rIn >> nFlags
2626 >> nPositionX
2627 >> nPositionY
2628 >> nCenterX
2629 >> nCenterY
2630 >> nRangeXMin
2631 >> nRangeXMax
2632 >> nRangeYMin
2633 >> nRangeYMax;
2635 if ( nPositionX == 2 ) // replacing center position with absolute value
2636 nPositionX = nCoordWidth / 2;
2637 if ( nPositionY == 2 )
2638 nPositionY = nCoordHeight / 2;
2639 EnhancedCustomShapeParameterPair aPosition;
2640 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.First, nPositionX, sal_True, sal_True );
2641 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPosition.Second, nPositionY, sal_True, sal_False );
2642 const rtl::OUString sHandlePosition( RTL_CONSTASCII_USTRINGPARAM ( "Position" ) );
2643 aProp.Name = sHandlePosition;
2644 aProp.Value <<= aPosition;
2645 aHandlePropVec.push_back( aProp );
2647 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_X )
2649 sal_Bool bMirroredX = sal_True;
2650 const rtl::OUString sHandleMirroredX( RTL_CONSTASCII_USTRINGPARAM ( "MirroredX" ) );
2651 aProp.Name = sHandleMirroredX;
2652 aProp.Value <<= bMirroredX;
2653 aHandlePropVec.push_back( aProp );
2655 if ( nFlags & MSDFF_HANDLE_FLAGS_MIRRORED_Y )
2657 sal_Bool bMirroredY = sal_True;
2658 const rtl::OUString sHandleMirroredY( RTL_CONSTASCII_USTRINGPARAM ( "MirroredY" ) );
2659 aProp.Name = sHandleMirroredY;
2660 aProp.Value <<= bMirroredY;
2661 aHandlePropVec.push_back( aProp );
2663 if ( nFlags & MSDFF_HANDLE_FLAGS_SWITCHED )
2665 sal_Bool bSwitched = sal_True;
2666 const rtl::OUString sHandleSwitched( RTL_CONSTASCII_USTRINGPARAM ( "Switched" ) );
2667 aProp.Name = sHandleSwitched;
2668 aProp.Value <<= bSwitched;
2669 aHandlePropVec.push_back( aProp );
2671 if ( nFlags & MSDFF_HANDLE_FLAGS_POLAR )
2673 if ( nCenterX == 2 )
2674 nCenterX = nCoordWidth / 2;
2675 if ( nCenterY == 2 )
2676 nCenterY = nCoordHeight / 2;
2677 if ( ( nPositionY >= 0x256 ) || ( nPositionY <= 0x107 ) ) // position y
2678 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
2679 EnhancedCustomShapeParameterPair aPolar;
2680 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True );
2681 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aPolar.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
2682 const rtl::OUString sHandlePolar( RTL_CONSTASCII_USTRINGPARAM ( "Polar" ) );
2683 aProp.Name = sHandlePolar;
2684 aProp.Value <<= aPolar;
2685 aHandlePropVec.push_back( aProp );
2687 if ( nFlags & MSDFF_HANDLE_FLAGS_MAP )
2689 if ( nCenterX == 2 )
2690 nCenterX = nCoordWidth / 2;
2691 if ( nCenterY == 2 )
2692 nCenterY = nCoordHeight / 2;
2693 EnhancedCustomShapeParameterPair aMap;
2694 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.First, nCenterX, ( nFlags & 0x800 ) != 0, sal_True );
2695 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aMap.Second, nCenterY, ( nFlags & 0x1000 ) != 0, sal_False );
2696 const rtl::OUString sHandleMap( RTL_CONSTASCII_USTRINGPARAM ( "Map" ) );
2697 aProp.Name = sHandleMap;
2698 aProp.Value <<= aMap;
2699 aHandlePropVec.push_back( aProp );
2701 if ( nFlags & MSDFF_HANDLE_FLAGS_RANGE )
2703 if ( (sal_uInt32)nRangeXMin != 0x80000000 )
2705 if ( nRangeXMin == 2 )
2706 nRangeXMin = nCoordWidth / 2;
2707 EnhancedCustomShapeParameter aRangeXMinimum;
2708 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMinimum, nRangeXMin,
2709 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
2710 const rtl::OUString sHandleRangeXMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMinimum" ) );
2711 aProp.Name = sHandleRangeXMinimum;
2712 aProp.Value <<= aRangeXMinimum;
2713 aHandlePropVec.push_back( aProp );
2715 if ( (sal_uInt32)nRangeXMax != 0x7fffffff )
2717 if ( nRangeXMax == 2 )
2718 nRangeXMax = nCoordWidth / 2;
2719 EnhancedCustomShapeParameter aRangeXMaximum;
2720 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeXMaximum, nRangeXMax,
2721 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
2722 const rtl::OUString sHandleRangeXMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeXMaximum" ) );
2723 aProp.Name = sHandleRangeXMaximum;
2724 aProp.Value <<= aRangeXMaximum;
2725 aHandlePropVec.push_back( aProp );
2727 if ( (sal_uInt32)nRangeYMin != 0x80000000 )
2729 if ( nRangeYMin == 2 )
2730 nRangeYMin = nCoordHeight / 2;
2731 EnhancedCustomShapeParameter aRangeYMinimum;
2732 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMinimum, nRangeYMin,
2733 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MIN_IS_SPECIAL ) != 0, sal_True );
2734 const rtl::OUString sHandleRangeYMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMinimum" ) );
2735 aProp.Name = sHandleRangeYMinimum;
2736 aProp.Value <<= aRangeYMinimum;
2737 aHandlePropVec.push_back( aProp );
2739 if ( (sal_uInt32)nRangeYMax != 0x7fffffff )
2741 if ( nRangeYMax == 2 )
2742 nRangeYMax = nCoordHeight / 2;
2743 EnhancedCustomShapeParameter aRangeYMaximum;
2744 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRangeYMaximum, nRangeYMax,
2745 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_Y_MAX_IS_SPECIAL ) != 0, sal_False );
2746 const rtl::OUString sHandleRangeYMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RangeYMaximum" ) );
2747 aProp.Name = sHandleRangeYMaximum;
2748 aProp.Value <<= aRangeYMaximum;
2749 aHandlePropVec.push_back( aProp );
2752 if ( nFlags & MSDFF_HANDLE_FLAGS_RADIUS_RANGE )
2754 if ( (sal_uInt32)nRangeXMin != 0x7fffffff )
2756 if ( nRangeXMin == 2 )
2757 nRangeXMin = nCoordWidth / 2;
2758 EnhancedCustomShapeParameter aRadiusRangeMinimum;
2759 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMinimum, nRangeXMin,
2760 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MIN_IS_SPECIAL ) != 0, sal_True );
2761 const rtl::OUString sHandleRadiusRangeMinimum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMinimum" ) );
2762 aProp.Name = sHandleRadiusRangeMinimum;
2763 aProp.Value <<= aRadiusRangeMinimum;
2764 aHandlePropVec.push_back( aProp );
2766 if ( (sal_uInt32)nRangeXMax != 0x80000000 )
2768 if ( nRangeXMax == 2 )
2769 nRangeXMax = nCoordWidth / 2;
2770 EnhancedCustomShapeParameter aRadiusRangeMaximum;
2771 EnhancedCustomShape2d::SetEnhancedCustomShapeHandleParameter( aRadiusRangeMaximum, nRangeXMax,
2772 ( nFlags & MSDFF_HANDLE_FLAGS_RANGE_X_MAX_IS_SPECIAL ) != 0, sal_False );
2773 const rtl::OUString sHandleRadiusRangeMaximum( RTL_CONSTASCII_USTRINGPARAM ( "RadiusRangeMaximum" ) );
2774 aProp.Name = sHandleRadiusRangeMaximum;
2775 aProp.Value <<= aRadiusRangeMaximum;
2776 aHandlePropVec.push_back( aProp );
2779 if ( aHandlePropVec.size() )
2781 PropSeq aHandlePropSeq( aHandlePropVec.size() );
2782 aIter = aHandlePropVec.begin();
2783 aEnd = aHandlePropVec.end();
2784 beans::PropertyValue* pHandleValues = aHandlePropSeq.getArray();
2785 while ( aIter != aEnd )
2786 *pHandleValues++ = *aIter++;
2787 aHandles[ i ] = aHandlePropSeq;
2790 // pushing the whole Handles element
2791 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
2792 aProp.Name = sHandles;
2793 aProp.Value <<= aHandles;
2794 aPropVec.push_back( aProp );
2797 else
2799 const mso_CustomShape* pDefCustomShape = GetCustomShapeContent( rObjData.eShapeType );
2800 if ( pDefCustomShape && pDefCustomShape->nHandles && pDefCustomShape->pHandles )
2802 sal_Int32 i, nCnt = pDefCustomShape->nHandles;
2803 const SvxMSDffHandle* pData = pDefCustomShape->pHandles;
2804 for ( i = 0; i < nCnt; i++, pData++ )
2806 if ( pData->nFlags & MSDFF_HANDLE_FLAGS_POLAR )
2808 if ( ( pData->nPositionY >= 0x256 ) || ( pData->nPositionY <= 0x107 ) )
2809 nAdjustmentsWhichNeedsToBeConverted |= ( 1 << i );
2814 /////////////////////////////////////
2815 // "Path" PropertySequence element //
2816 /////////////////////////////////////
2818 PropVec aPathPropVec;
2820 // "Path/ExtrusionAllowed"
2821 if ( IsHardAttribute( DFF_Prop_f3DOK ) )
2823 const rtl::OUString sExtrusionAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ExtrusionAllowed" ) );
2824 sal_Bool bExtrusionAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 16 ) != 0;
2825 aProp.Name = sExtrusionAllowed;
2826 aProp.Value <<= bExtrusionAllowed;
2827 aPathPropVec.push_back( aProp );
2829 // "Path/ConcentricGradientFillAllowed"
2830 if ( IsHardAttribute( DFF_Prop_fFillShadeShapeOK ) )
2832 const rtl::OUString sConcentricGradientFillAllowed( RTL_CONSTASCII_USTRINGPARAM ( "ConcentricGradientFillAllowed" ) );
2833 sal_Bool bConcentricGradientFillAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 2 ) != 0;
2834 aProp.Name = sConcentricGradientFillAllowed;
2835 aProp.Value <<= bConcentricGradientFillAllowed;
2836 aPathPropVec.push_back( aProp );
2838 // "Path/TextPathAllowed"
2839 if ( IsHardAttribute( DFF_Prop_fGtextOK ) || ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) )
2841 const rtl::OUString sTextPathAllowed( RTL_CONSTASCII_USTRINGPARAM ( "TextPathAllowed" ) );
2842 sal_Bool bTextPathAllowed = ( GetPropertyValue( DFF_Prop_fFillOK ) & 4 ) != 0;
2843 aProp.Name = sTextPathAllowed;
2844 aProp.Value <<= bTextPathAllowed;
2845 aPathPropVec.push_back( aProp );
2847 // Path/Coordinates
2848 if ( IsProperty( DFF_Prop_pVertices ) )
2850 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aCoordinates;
2852 sal_uInt16 i;
2853 sal_uInt16 nNumElemVert = 0;
2854 sal_uInt16 nNumElemMemVert = 0;
2855 sal_uInt16 nElemSizeVert = 8;
2857 if ( SeekToContent( DFF_Prop_pVertices, rIn ) )
2858 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
2859 if ( nNumElemVert )
2861 sal_Int32 nX, nY;
2862 sal_Int16 nTmpA, nTmpB;
2863 aCoordinates.realloc( nNumElemVert );
2864 for ( i = 0; i < nNumElemVert; i++ )
2866 if ( nElemSizeVert == 8 )
2868 rIn >> nX
2869 >> nY;
2871 else
2873 rIn >> nTmpA
2874 >> nTmpB;
2876 nX = nTmpA;
2877 nY = nTmpB;
2879 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].First, nX );
2880 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aCoordinates[ i ].Second, nY );
2883 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
2884 aProp.Name = sCoordinates;
2885 aProp.Value <<= aCoordinates;
2886 aPathPropVec.push_back( aProp );
2888 // Path/Segments
2889 if ( IsProperty( DFF_Prop_pSegmentInfo ) )
2891 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeSegment > aSegments;
2893 sal_uInt16 i, nTmp;
2894 sal_uInt16 nNumElemSeg = 0;
2895 sal_uInt16 nNumElemMemSeg = 0;
2896 sal_uInt16 nElemSizeSeg = 2;
2898 if ( SeekToContent( DFF_Prop_pSegmentInfo, rIn ) )
2899 rIn >> nNumElemSeg >> nNumElemMemSeg >> nElemSizeSeg;
2900 if ( nNumElemSeg )
2902 sal_Int16 nCommand;
2903 sal_Int16 nCnt;
2904 aSegments.realloc( nNumElemSeg );
2905 for ( i = 0; i < nNumElemSeg; i++ )
2907 rIn >> nTmp;
2908 nCommand = EnhancedCustomShapeSegmentCommand::UNKNOWN;
2909 nCnt = (sal_Int16)( nTmp & 0xfff );
2910 switch( nTmp >> 12 )
2912 case 0x0: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break;
2913 case 0x1: nCommand = EnhancedCustomShapeSegmentCommand::LINETO; if ( !nCnt ) nCnt = 1; break; // seems to the relative lineto
2914 case 0x4: nCommand = EnhancedCustomShapeSegmentCommand::MOVETO; if ( !nCnt ) nCnt = 1; break;
2915 case 0x2: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break;
2916 case 0x3: nCommand = EnhancedCustomShapeSegmentCommand::CURVETO; if ( !nCnt ) nCnt = 1; break; // seems to be the relative curveto
2917 case 0x8: nCommand = EnhancedCustomShapeSegmentCommand::ENDSUBPATH; nCnt = 0; break;
2918 case 0x6: nCommand = EnhancedCustomShapeSegmentCommand::CLOSESUBPATH; nCnt = 0; break;
2919 case 0xa:
2920 case 0xb:
2922 switch ( ( nTmp >> 8 ) & 0xf )
2924 case 0x0:
2926 nCommand = EnhancedCustomShapeSegmentCommand::LINETO;
2927 if ( !nCnt )
2928 nCnt = 1;
2930 break;
2931 case 0x1:
2933 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSETO;
2934 nCnt = ( nTmp & 0xff ) / 3;
2936 break;
2937 case 0x2:
2939 nCommand = EnhancedCustomShapeSegmentCommand::ANGLEELLIPSE;
2940 nCnt = ( nTmp & 0xff ) / 3;
2942 break;
2943 case 0x3:
2945 nCommand = EnhancedCustomShapeSegmentCommand::ARCTO;
2946 nCnt = ( nTmp & 0xff ) >> 2;
2948 break;
2949 case 0x4:
2951 nCommand = EnhancedCustomShapeSegmentCommand::ARC;
2952 nCnt = ( nTmp & 0xff ) >> 2;
2954 break;
2955 case 0x5:
2957 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARCTO;
2958 nCnt = ( nTmp & 0xff ) >> 2;
2960 break;
2961 case 0x6:
2963 nCommand = EnhancedCustomShapeSegmentCommand::CLOCKWISEARC;
2964 nCnt = ( nTmp & 0xff ) >> 2;
2966 break;
2967 case 0x7:
2969 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTX;
2970 nCnt = nTmp & 0xff;
2972 break;
2973 case 0x8:
2975 nCommand = EnhancedCustomShapeSegmentCommand::ELLIPTICALQUADRANTY;
2976 nCnt = nTmp & 0xff;
2978 break;
2979 case 0xa: nCommand = EnhancedCustomShapeSegmentCommand::NOFILL; nCnt = 0; break;
2980 case 0xb: nCommand = EnhancedCustomShapeSegmentCommand::NOSTROKE; nCnt = 0; break;
2983 break;
2985 // if the command is unknown, we will store all the data in nCnt, so it will be possible to export without loss
2986 if ( nCommand == EnhancedCustomShapeSegmentCommand::UNKNOWN )
2987 nCnt = (sal_Int16)nTmp;
2988 aSegments[ i ].Command = nCommand;
2989 aSegments[ i ].Count = nCnt;
2992 const rtl::OUString sSegments( RTL_CONSTASCII_USTRINGPARAM ( "Segments" ) );
2993 aProp.Name = sSegments;
2994 aProp.Value <<= aSegments;
2995 aPathPropVec.push_back( aProp );
2997 // Path/StretchX
2998 if ( IsProperty( DFF_Prop_stretchPointX ) )
3000 const rtl::OUString sStretchX( RTL_CONSTASCII_USTRINGPARAM ( "StretchX" ) );
3001 sal_Int32 nStretchX = GetPropertyValue( DFF_Prop_stretchPointX, 0 );
3002 aProp.Name = sStretchX;
3003 aProp.Value <<= nStretchX;
3004 aPathPropVec.push_back( aProp );
3006 // Path/StretchX
3007 if ( IsProperty( DFF_Prop_stretchPointY ) )
3009 const rtl::OUString sStretchY( RTL_CONSTASCII_USTRINGPARAM ( "StretchY" ) );
3010 sal_Int32 nStretchY = GetPropertyValue( DFF_Prop_stretchPointY, 0 );
3011 aProp.Name = sStretchY;
3012 aProp.Value <<= nStretchY;
3013 aPathPropVec.push_back( aProp );
3015 // Path/TextFrames
3016 if ( IsProperty( DFF_Prop_textRectangles ) )
3018 sal_uInt16 i;
3019 sal_uInt16 nNumElem = 0;
3020 sal_uInt16 nNumElemMem = 0;
3021 sal_uInt16 nElemSize = 16;
3023 if ( SeekToContent( DFF_Prop_textRectangles, rIn ) )
3024 rIn >> nNumElem >> nNumElemMem >> nElemSize;
3025 if ( nElemSize == 16 )
3027 sal_Int32 nLeft, nTop, nRight, nBottom;
3028 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrames( nNumElem );
3029 for ( i = 0; i < nNumElem; i++ )
3031 rIn >> nLeft
3032 >> nTop
3033 >> nRight
3034 >> nBottom;
3036 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.First, nLeft );
3037 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].TopLeft.Second, nTop );
3038 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.First, nRight );
3039 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrames[ i ].BottomRight.Second, nBottom);
3041 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
3042 aProp.Name = sTextFrames;
3043 aProp.Value <<= aTextFrames;
3044 aPathPropVec.push_back( aProp );
3047 //Path/GluePoints
3048 if ( IsProperty( DFF_Prop_connectorPoints ) )
3050 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair > aGluePoints;
3052 sal_uInt16 i;
3053 sal_uInt16 nNumElemVert = 0;
3054 sal_uInt16 nNumElemMemVert = 0;
3055 sal_uInt16 nElemSizeVert = 8;
3057 if ( SeekToContent( DFF_Prop_connectorPoints, rIn ) )
3058 rIn >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
3060 sal_Int32 nX, nY;
3061 sal_Int16 nTmpA, nTmpB;
3062 aGluePoints.realloc( nNumElemVert );
3063 for ( i = 0; i < nNumElemVert; i++ )
3065 if ( nElemSizeVert == 8 )
3067 rIn >> nX
3068 >> nY;
3070 else
3072 rIn >> nTmpA
3073 >> nTmpB;
3075 nX = nTmpA;
3076 nY = nTmpB;
3078 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].First, nX );
3079 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aGluePoints[ i ].Second, nY );
3081 const rtl::OUString sGluePoints( RTL_CONSTASCII_USTRINGPARAM ( "GluePoints" ) );
3082 aProp.Name = sGluePoints;
3083 aProp.Value <<= aGluePoints;
3084 aPathPropVec.push_back( aProp );
3086 if ( IsProperty( DFF_Prop_connectorType ) )
3088 sal_Int16 nGluePointType = (sal_uInt16)GetPropertyValue( DFF_Prop_connectorType );
3089 const rtl::OUString sGluePointType( RTL_CONSTASCII_USTRINGPARAM ( "GluePointType" ) );
3090 aProp.Name = sGluePointType;
3091 aProp.Value <<= nGluePointType;
3092 aPathPropVec.push_back( aProp );
3094 // pushing the whole Path element
3095 if ( aPathPropVec.size() )
3097 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
3098 PropSeq aPathPropSeq( aPathPropVec.size() );
3099 aIter = aPathPropVec.begin();
3100 aEnd = aPathPropVec.end();
3101 beans::PropertyValue* pPathValues = aPathPropSeq.getArray();
3102 while ( aIter != aEnd )
3103 *pPathValues++ = *aIter++;
3104 aProp.Name = sPath;
3105 aProp.Value <<= aPathPropSeq;
3106 aPropVec.push_back( aProp );
3109 /////////////////////////////////////////
3110 // "TextPath" PropertySequence element //
3111 /////////////////////////////////////////
3112 sal_Bool bTextPathOn = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x4000 ) != 0;
3113 if ( bTextPathOn )
3115 PropVec aTextPathPropVec;
3117 // TextPath
3118 const rtl::OUString sTextPathOn( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
3119 aProp.Name = sTextPathOn;
3120 aProp.Value <<= bTextPathOn;
3121 aTextPathPropVec.push_back( aProp );
3123 // TextPathMode
3124 const rtl::OUString sTextPathMode( RTL_CONSTASCII_USTRINGPARAM ( "TextPathMode" ) );
3125 sal_Bool bTextPathFitPath = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x100 ) != 0;
3127 sal_Bool bTextPathFitShape;
3128 if ( IsHardAttribute( DFF_Prop_gtextFStretch ) )
3129 bTextPathFitShape = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x400 ) != 0;
3130 else
3132 bTextPathFitShape = true;
3133 switch( rObjData.eShapeType )
3135 case mso_sptTextArchUpCurve :
3136 case mso_sptTextArchDownCurve :
3137 case mso_sptTextCircleCurve :
3138 case mso_sptTextButtonCurve :
3139 bTextPathFitShape = false;
3140 default : break;
3143 EnhancedCustomShapeTextPathMode eTextPathMode( EnhancedCustomShapeTextPathMode_NORMAL );
3144 if ( bTextPathFitShape )
3145 eTextPathMode = EnhancedCustomShapeTextPathMode_SHAPE;
3146 else if ( bTextPathFitPath )
3147 eTextPathMode = EnhancedCustomShapeTextPathMode_PATH;
3148 aProp.Name = sTextPathMode;
3149 aProp.Value <<= eTextPathMode;
3150 aTextPathPropVec.push_back( aProp );
3152 // ScaleX
3153 const rtl::OUString sTextPathScaleX( RTL_CONSTASCII_USTRINGPARAM ( "ScaleX" ) );
3154 sal_Bool bTextPathScaleX = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x40 ) != 0;
3155 aProp.Name = sTextPathScaleX;
3156 aProp.Value <<= bTextPathScaleX;
3157 aTextPathPropVec.push_back( aProp );
3158 // SameLetterHeights
3159 const rtl::OUString sSameLetterHeight( RTL_CONSTASCII_USTRINGPARAM ( "SameLetterHeights" ) );
3160 sal_Bool bSameLetterHeight = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough ) & 0x80 ) != 0;
3161 aProp.Name = sSameLetterHeight;
3162 aProp.Value <<= bSameLetterHeight;
3163 aTextPathPropVec.push_back( aProp );
3165 // pushing the whole TextPath element
3166 const rtl::OUString sTextPath( RTL_CONSTASCII_USTRINGPARAM ( "TextPath" ) );
3167 PropSeq aTextPathPropSeq( aTextPathPropVec.size() );
3168 aIter = aTextPathPropVec.begin();
3169 aEnd = aTextPathPropVec.end();
3170 beans::PropertyValue* pTextPathValues = aTextPathPropSeq.getArray();
3171 while ( aIter != aEnd )
3172 *pTextPathValues++ = *aIter++;
3173 aProp.Name = sTextPath;
3174 aProp.Value <<= aTextPathPropSeq;
3175 aPropVec.push_back( aProp );
3177 ////////////////////////
3178 // "AdjustmentValues" // The AdjustmentValues are imported at last, because depending to the type of the
3179 //////////////////////// handle (POLAR) we will convert the adjustment value from a fixed float to double
3181 // checking the last used adjustment handle, so we can determine how many handles are to allocate
3182 sal_Int32 i = DFF_Prop_adjust10Value;
3183 while ( ( i >= DFF_Prop_adjustValue ) && !IsProperty( i ) )
3184 i--;
3185 sal_Int32 nAdjustmentValues = ( i - DFF_Prop_adjustValue ) + 1;
3186 if ( nAdjustmentValues )
3188 uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > aAdjustmentSeq( nAdjustmentValues );
3189 while( --nAdjustmentValues >= 0 )
3191 sal_Int32 nValue = 0;
3192 beans::PropertyState ePropertyState = beans::PropertyState_DEFAULT_VALUE;
3193 if ( IsProperty( i ) )
3195 nValue = GetPropertyValue( i );
3196 ePropertyState = beans::PropertyState_DIRECT_VALUE;
3198 if ( nAdjustmentsWhichNeedsToBeConverted & ( 1 << ( i - DFF_Prop_adjustValue ) ) )
3200 double fValue = nValue;
3201 fValue /= 65536;
3202 aAdjustmentSeq[ nAdjustmentValues ].Value <<= fValue;
3204 else
3205 aAdjustmentSeq[ nAdjustmentValues ].Value <<= nValue;
3206 aAdjustmentSeq[ nAdjustmentValues ].State = ePropertyState;
3207 i--;
3209 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
3210 aProp.Name = sAdjustmentValues;
3211 aProp.Value <<= aAdjustmentSeq;
3212 aPropVec.push_back( aProp );
3215 // creating the whole property set
3216 PropSeq aSeq( aPropVec.size() );
3217 beans::PropertyValue* pValues = aSeq.getArray();
3218 aIter = aPropVec.begin();
3219 aEnd = aPropVec.end();
3220 while ( aIter != aEnd )
3221 *pValues++ = *aIter++;
3222 rSet.Put( SdrCustomShapeGeometryItem( aSeq ) );
3225 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet ) const
3227 Rectangle aEmptyRect;
3228 DffRecordHeader aHdTemp;
3229 DffObjData aDffObjTemp( aHdTemp, aEmptyRect, 0 );
3230 ApplyAttributes( rIn, rSet, aDffObjTemp );
3233 void DffPropertyReader::ApplyAttributes( SvStream& rIn, SfxItemSet& rSet, const DffObjData& rObjData ) const
3235 // MapUnit eMap( rManager.GetModel()->GetScaleUnit() );
3237 for ( void* pDummy = ((DffPropertyReader*)this)->First(); pDummy; pDummy = ((DffPropertyReader*)this)->Next() )
3239 UINT32 nRecType = GetCurKey();
3240 UINT32 nContent = mpContents[ nRecType ];
3241 switch ( nRecType )
3243 case DFF_Prop_gtextSize :
3244 rSet.Put( SvxFontHeightItem( rManager.ScalePt( nContent ), 100, EE_CHAR_FONTHEIGHT ) );
3245 break;
3246 // GeoText
3247 case DFF_Prop_gtextFStrikethrough :
3249 if ( nContent & 0x20 )
3250 rSet.Put( SvxWeightItem( nContent ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
3251 if ( nContent & 0x10 )
3252 rSet.Put( SvxPostureItem( nContent ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
3253 if ( nContent & 0x08 )
3254 rSet.Put( SvxUnderlineItem( nContent ? UNDERLINE_SINGLE : UNDERLINE_NONE, EE_CHAR_UNDERLINE ) );
3255 if ( nContent & 0x40 )
3256 rSet.Put(SvxShadowedItem( nContent != 0, EE_CHAR_SHADOW ) );
3257 // if ( nContent & 0x02 )
3258 // rSet.Put( SvxCaseMapItem( nContent ? SVX_CASEMAP_KAPITAELCHEN : SVX_CASEMAP_NOT_MAPPED ) );
3259 if ( nContent & 0x01 )
3260 rSet.Put( SvxCrossedOutItem( nContent ? STRIKEOUT_SINGLE : STRIKEOUT_NONE, EE_CHAR_STRIKEOUT ) );
3262 break;
3264 case DFF_Prop_fillColor :
3265 rSet.Put( XFillColorItem( String(), rManager.MSO_CLR_ToColor( nContent, DFF_Prop_fillColor ) ) );
3266 break;
3268 // ShadowStyle
3269 case DFF_Prop_shadowType :
3271 MSO_ShadowType eShadowType = (MSO_ShadowType)nContent;
3272 if( eShadowType != mso_shadowOffset )
3274 // mso_shadowDouble
3275 // mso_shadowRich
3276 // mso_shadowEmbossOrEngrave
3277 // koennen wir nicht, kreiere Default-Schatten mit default-
3278 // Abstand
3279 rSet.Put( SdrShadowXDistItem( 35 ) ); // 0,35 mm Schattendistanz
3280 rSet.Put( SdrShadowYDistItem( 35 ) );
3283 break;
3284 case DFF_Prop_shadowColor :
3285 rSet.Put( SdrShadowColorItem( String(), rManager.MSO_CLR_ToColor( nContent, DFF_Prop_shadowColor ) ) );
3286 break;
3287 case DFF_Prop_shadowOpacity :
3288 rSet.Put( SdrShadowTransparenceItem( (sal_uInt16)( ( 0x10000 - nContent ) / 655 ) ) );
3289 break;
3290 case DFF_Prop_shadowOffsetX :
3292 INT32 nVal = (INT32)nContent;
3293 rManager.ScaleEmu( nVal );
3294 if ( nVal )
3295 rSet.Put( SdrShadowXDistItem( nVal ) );
3297 break;
3298 case DFF_Prop_shadowOffsetY :
3300 INT32 nVal = (INT32)nContent;
3301 rManager.ScaleEmu( nVal );
3302 if ( nVal )
3303 rSet.Put( SdrShadowYDistItem( nVal ) );
3305 break;
3306 case DFF_Prop_fshadowObscured :
3308 sal_Bool bHasShadow = ( nContent & 2 ) != 0;
3309 rSet.Put( SdrShadowItem( bHasShadow ) );
3310 if ( bHasShadow )
3312 if ( !IsProperty( DFF_Prop_shadowOffsetX ) )
3313 rSet.Put( SdrShadowXDistItem( 35 ) );
3314 if ( !IsProperty( DFF_Prop_shadowOffsetY ) )
3315 rSet.Put( SdrShadowYDistItem( 35 ) );
3318 break;
3322 ApplyLineAttributes( rSet, rObjData.eShapeType ); // #i28269#
3323 ApplyFillAttributes( rIn, rSet, rObjData );
3324 if ( rObjData.eShapeType != mso_sptNil )
3326 ApplyCustomShapeGeometryAttributes( rIn, rSet, rObjData );
3327 ApplyCustomShapeTextAttributes( rSet );
3331 //---------------------------------------------------------------------------
3332 //- Record Manager ----------------------------------------------------------
3333 //---------------------------------------------------------------------------
3335 DffRecordList::DffRecordList( DffRecordList* pList ) :
3336 nCount ( 0 ),
3337 nCurrent ( 0 ),
3338 pPrev ( pList ),
3339 pNext ( NULL )
3341 if ( pList )
3342 pList->pNext = this;
3345 DffRecordList::~DffRecordList()
3347 delete pNext;
3350 DffRecordManager::DffRecordManager() :
3351 DffRecordList ( NULL ),
3352 pCList ( (DffRecordList*)this )
3356 DffRecordManager::DffRecordManager( SvStream& rIn ) :
3357 DffRecordList ( NULL ),
3358 pCList ( (DffRecordList*)this )
3360 Consume( rIn );
3363 DffRecordManager::~DffRecordManager()
3368 void DffRecordManager::Consume( SvStream& rIn, BOOL bAppend, UINT32 nStOfs )
3370 if ( !bAppend )
3371 Clear();
3372 UINT32 nOldPos = rIn.Tell();
3373 if ( !nStOfs )
3375 DffRecordHeader aHd;
3376 rIn >> aHd;
3377 if ( aHd.nRecVer == DFF_PSFLAG_CONTAINER )
3378 nStOfs = aHd.GetRecEndFilePos();
3380 if ( nStOfs )
3382 pCList = (DffRecordList*)this;
3383 while ( pCList->pNext )
3384 pCList = pCList->pNext;
3385 while ( ( rIn.GetError() == 0 ) && ( ( rIn.Tell() + 8 ) <= nStOfs ) )
3387 if ( pCList->nCount == DFF_RECORD_MANAGER_BUF_SIZE )
3388 pCList = new DffRecordList( pCList );
3389 rIn >> pCList->mHd[ pCList->nCount ];
3390 pCList->mHd[ pCList->nCount++ ].SeekToEndOfRecord( rIn );
3392 rIn.Seek( nOldPos );
3396 void DffRecordManager::Clear()
3398 pCList = (DffRecordList*)this;
3399 delete pNext, pNext = NULL;
3400 nCurrent = 0;
3401 nCount = 0;
3404 DffRecordHeader* DffRecordManager::Current()
3406 DffRecordHeader* pRet = NULL;
3407 if ( pCList->nCurrent < pCList->nCount )
3408 pRet = &pCList->mHd[ pCList->nCurrent ];
3409 return pRet;
3412 DffRecordHeader* DffRecordManager::First()
3414 DffRecordHeader* pRet = NULL;
3415 pCList = (DffRecordList*)this;
3416 if ( pCList->nCount )
3418 pCList->nCurrent = 0;
3419 pRet = &pCList->mHd[ 0 ];
3421 return pRet;
3424 DffRecordHeader* DffRecordManager::Next()
3426 DffRecordHeader* pRet = NULL;
3427 UINT32 nC = pCList->nCurrent + 1;
3428 if ( nC < pCList->nCount )
3430 pCList->nCurrent++;
3431 pRet = &pCList->mHd[ nC ];
3433 else if ( pCList->pNext )
3435 pCList = pCList->pNext;
3436 pCList->nCurrent = 0;
3437 pRet = &pCList->mHd[ 0 ];
3439 return pRet;
3442 DffRecordHeader* DffRecordManager::Prev()
3444 DffRecordHeader* pRet = NULL;
3445 UINT32 nCur = pCList->nCurrent;
3446 if ( !nCur && pCList->pPrev )
3448 pCList = pCList->pPrev;
3449 nCur = pCList->nCount;
3451 if ( nCur-- )
3453 pCList->nCurrent = nCur;
3454 pRet = &pCList->mHd[ nCur ];
3456 return pRet;
3459 DffRecordHeader* DffRecordManager::Last()
3461 DffRecordHeader* pRet = NULL;
3462 while ( pCList->pNext )
3463 pCList = pCList->pNext;
3464 UINT32 nCnt = pCList->nCount;
3465 if ( nCnt-- )
3467 pCList->nCurrent = nCnt;
3468 pRet = &pCList->mHd[ nCnt ];
3470 return pRet;
3473 BOOL DffRecordManager::SeekToContent( SvStream& rIn, UINT16 nRecId, DffSeekToContentMode eMode )
3475 DffRecordHeader* pHd = GetRecordHeader( nRecId, eMode );
3476 if ( pHd )
3478 pHd->SeekToContent( rIn );
3479 return TRUE;
3481 else
3482 return FALSE;
3485 DffRecordHeader* DffRecordManager::GetRecordHeader( UINT16 nRecId, DffSeekToContentMode eMode )
3487 UINT32 nOldCurrent = pCList->nCurrent;
3488 DffRecordList* pOldList = pCList;
3489 DffRecordHeader* pHd;
3491 if ( eMode == SEEK_FROM_BEGINNING )
3492 pHd = First();
3493 else
3494 pHd = Next();
3496 while ( pHd )
3498 if ( pHd->nRecType == nRecId )
3499 break;
3500 pHd = Next();
3502 if ( !pHd && eMode == SEEK_FROM_CURRENT_AND_RESTART )
3504 DffRecordHeader* pBreak = &pOldList->mHd[ nOldCurrent ];
3505 pHd = First();
3506 if ( pHd )
3508 while ( pHd != pBreak )
3510 if ( pHd->nRecType == nRecId )
3511 break;
3512 pHd = Next();
3514 if ( pHd->nRecType != nRecId )
3515 pHd = NULL;
3518 if ( !pHd )
3520 pCList = pOldList;
3521 pOldList->nCurrent = nOldCurrent;
3523 return pHd;
3526 //---------------------------------------------------------------------------
3527 // private Methoden
3528 //---------------------------------------------------------------------------
3530 struct EscherBlipCacheEntry
3532 ByteString aUniqueID;
3533 sal_uInt32 nBlip;
3535 EscherBlipCacheEntry( sal_uInt32 nBlipId, const ByteString& rUniqueID ) :
3536 aUniqueID( rUniqueID ),
3537 nBlip( nBlipId ) {}
3540 void SvxMSDffManager::Scale( sal_Int32& rVal ) const
3542 if ( bNeedMap )
3543 rVal = BigMulDiv( rVal, nMapMul, nMapDiv );
3546 void SvxMSDffManager::Scale( Point& rPos ) const
3548 rPos.X() += nMapXOfs;
3549 rPos.Y() += nMapYOfs;
3550 if ( bNeedMap )
3552 rPos.X() = BigMulDiv( rPos.X(), nMapMul, nMapDiv );
3553 rPos.Y() = BigMulDiv( rPos.Y(), nMapMul, nMapDiv );
3557 void SvxMSDffManager::Scale( Size& rSiz ) const
3559 if ( bNeedMap )
3561 rSiz.Width() = BigMulDiv( rSiz.Width(), nMapMul, nMapDiv );
3562 rSiz.Height() = BigMulDiv( rSiz.Height(), nMapMul, nMapDiv );
3566 void SvxMSDffManager::Scale( Rectangle& rRect ) const
3568 rRect.Move( nMapXOfs, nMapYOfs );
3569 if ( bNeedMap )
3571 rRect.Left() =BigMulDiv( rRect.Left() , nMapMul, nMapDiv );
3572 rRect.Top() =BigMulDiv( rRect.Top() , nMapMul, nMapDiv );
3573 rRect.Right() =BigMulDiv( rRect.Right() , nMapMul, nMapDiv );
3574 rRect.Bottom()=BigMulDiv( rRect.Bottom(), nMapMul, nMapDiv );
3578 void SvxMSDffManager::Scale( Polygon& rPoly ) const
3580 if ( !bNeedMap )
3581 return;
3582 USHORT nPointAnz = rPoly.GetSize();
3583 for ( USHORT nPointNum = 0; nPointNum < nPointAnz; nPointNum++ )
3584 Scale( rPoly[ nPointNum ] );
3587 void SvxMSDffManager::Scale( PolyPolygon& rPoly ) const
3589 if ( !bNeedMap )
3590 return;
3591 USHORT nPolyAnz = rPoly.Count();
3592 for ( USHORT nPolyNum = 0; nPolyNum < nPolyAnz; nPolyNum++ )
3593 Scale( rPoly[ nPolyNum ] );
3596 void SvxMSDffManager::ScaleEmu( sal_Int32& rVal ) const
3598 rVal = BigMulDiv( rVal, nEmuMul, nEmuDiv );
3601 UINT32 SvxMSDffManager::ScalePt( UINT32 nVal ) const
3603 MapUnit eMap = pSdrModel->GetScaleUnit();
3604 Fraction aFact( GetMapFactor( MAP_POINT, eMap ).X() );
3605 long aMul = aFact.GetNumerator();
3606 long aDiv = aFact.GetDenominator() * 65536;
3607 aFact = Fraction( aMul, aDiv ); // nochmal versuchen zu kuerzen
3608 return BigMulDiv( nVal, aFact.GetNumerator(), aFact.GetDenominator() );
3611 INT32 SvxMSDffManager::ScalePoint( INT32 nVal ) const
3613 return BigMulDiv( nVal, nPntMul, nPntDiv );
3616 void SvxMSDffManager::SetModel(SdrModel* pModel, long nApplicationScale)
3618 pSdrModel = pModel;
3619 if( pModel && (0 < nApplicationScale) )
3621 // PPT arbeitet nur mit Einheiten zu 576DPI
3622 // WW hingegen verwendet twips, dh. 1440DPI.
3623 MapUnit eMap = pSdrModel->GetScaleUnit();
3624 Fraction aFact( GetMapFactor(MAP_INCH, eMap).X() );
3625 long nMul=aFact.GetNumerator();
3626 long nDiv=aFact.GetDenominator()*nApplicationScale;
3627 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3628 // Bei 100TH_MM -> 2540/576=635/144
3629 // Bei Twip -> 1440/576=5/2
3630 nMapMul = aFact.GetNumerator();
3631 nMapDiv = aFact.GetDenominator();
3632 bNeedMap = nMapMul!=nMapDiv;
3634 // MS-DFF-Properties sind grossteils in EMU (English Metric Units) angegeben
3635 // 1mm=36000emu, 1twip=635emu
3636 aFact=GetMapFactor(MAP_100TH_MM,eMap).X();
3637 nMul=aFact.GetNumerator();
3638 nDiv=aFact.GetDenominator()*360;
3639 aFact=Fraction(nMul,nDiv); // nochmal versuchen zu kuerzen
3640 // Bei 100TH_MM -> 1/360
3641 // Bei Twip -> 14,40/(25,4*360)=144/91440=1/635
3642 nEmuMul=aFact.GetNumerator();
3643 nEmuDiv=aFact.GetDenominator();
3645 // Und noch was fuer typografische Points
3646 aFact=GetMapFactor(MAP_POINT,eMap).X();
3647 nPntMul=aFact.GetNumerator();
3648 nPntDiv=aFact.GetDenominator();
3650 else
3652 pModel = 0;
3653 nMapMul = nMapDiv = nMapXOfs = nMapYOfs = nEmuMul = nEmuDiv = nPntMul = nPntDiv = 0;
3654 bNeedMap = FALSE;
3658 BOOL SvxMSDffManager::SeekToShape( SvStream& rSt, void* /* pClientData */, UINT32 nId ) const
3660 BOOL bRet = FALSE;
3661 if ( mpFidcls )
3663 UINT32 nMerk = rSt.Tell();
3664 UINT32 nShapeId, nSec = ( nId >> 10 ) - 1;
3665 if ( nSec < mnIdClusters )
3667 sal_IntPtr nOfs = (sal_IntPtr)maDgOffsetTable.Get( mpFidcls[ nSec ].dgid );
3668 if ( nOfs )
3670 rSt.Seek( nOfs );
3671 DffRecordHeader aEscherF002Hd;
3672 rSt >> aEscherF002Hd;
3673 ULONG nEscherF002End = aEscherF002Hd.GetRecEndFilePos();
3674 DffRecordHeader aEscherObjListHd;
3675 while ( rSt.Tell() < nEscherF002End )
3677 rSt >> aEscherObjListHd;
3678 if ( aEscherObjListHd.nRecVer != 0xf )
3679 aEscherObjListHd.SeekToEndOfRecord( rSt );
3680 else if ( aEscherObjListHd.nRecType == DFF_msofbtSpContainer )
3682 DffRecordHeader aShapeHd;
3683 if ( SeekToRec( rSt, DFF_msofbtSp, aEscherObjListHd.GetRecEndFilePos(), &aShapeHd ) )
3685 rSt >> nShapeId;
3686 if ( nId == nShapeId )
3688 aEscherObjListHd.SeekToBegOfRecord( rSt );
3689 bRet = TRUE;
3690 break;
3693 aEscherObjListHd.SeekToEndOfRecord( rSt );
3698 if ( !bRet )
3699 rSt.Seek( nMerk );
3701 return bRet;
3704 FASTBOOL SvxMSDffManager::SeekToRec( SvStream& rSt, USHORT nRecId, ULONG nMaxFilePos, DffRecordHeader* pRecHd, ULONG nSkipCount ) const
3706 FASTBOOL bRet = FALSE;
3707 ULONG nFPosMerk = rSt.Tell(); // FilePos merken fuer ggf. spaetere Restauration
3708 DffRecordHeader aHd;
3711 rSt >> aHd;
3712 if ( aHd.nRecType == nRecId )
3714 if ( nSkipCount )
3715 nSkipCount--;
3716 else
3718 bRet = TRUE;
3719 if ( pRecHd != NULL )
3720 *pRecHd = aHd;
3721 else
3722 aHd.SeekToBegOfRecord( rSt );
3725 if ( !bRet )
3726 aHd.SeekToEndOfRecord( rSt );
3728 while ( rSt.GetError() == 0 && rSt.Tell() < nMaxFilePos && !bRet );
3729 if ( !bRet )
3730 rSt.Seek( nFPosMerk ); // FilePos restaurieren
3731 return bRet;
3734 FASTBOOL SvxMSDffManager::SeekToRec2( USHORT nRecId1, USHORT nRecId2, ULONG nMaxFilePos, DffRecordHeader* pRecHd, ULONG nSkipCount ) const
3736 FASTBOOL bRet = FALSE;
3737 ULONG nFPosMerk = rStCtrl.Tell(); // FilePos merken fuer ggf. spaetere Restauration
3738 DffRecordHeader aHd;
3741 rStCtrl >> aHd;
3742 if ( aHd.nRecType == nRecId1 || aHd.nRecType == nRecId2 )
3744 if ( nSkipCount )
3745 nSkipCount--;
3746 else
3748 bRet = TRUE;
3749 if ( pRecHd )
3750 *pRecHd = aHd;
3751 else
3752 aHd.SeekToBegOfRecord( rStCtrl );
3755 if ( !bRet )
3756 aHd.SeekToEndOfRecord( rStCtrl );
3758 while ( rStCtrl.GetError() == 0 && rStCtrl.Tell() < nMaxFilePos && !bRet );
3759 if ( !bRet )
3760 rStCtrl.Seek( nFPosMerk ); // FilePos restaurieren
3761 return bRet;
3765 FASTBOOL SvxMSDffManager::GetColorFromPalette( USHORT /* nNum */, Color& rColor ) const
3767 // diese Methode ist in der zum Excel-Import
3768 // abgeleiteten Klasse zu ueberschreiben...
3769 rColor.SetColor( COL_WHITE );
3770 return TRUE;
3774 Color SvxMSDffManager::MSO_CLR_ToColor( sal_uInt32 nColorCode, sal_uInt16 nContentProperty ) const
3776 Color aColor( mnDefaultColor );
3778 // Fuer Textfarben: Header ist 0xfeRRGGBB
3779 if ( ( nColorCode & 0xfe000000 ) == 0xfe000000 )
3780 nColorCode &= 0x00ffffff;
3782 sal_uInt8 nUpper = (sal_uInt8)( nColorCode >> 24 );
3783 if( nUpper & 0x19 ) // if( nUpper & 0x1f )
3785 if( ( nUpper & 0x08 ) || ( ( nUpper & 0x10 ) == 0 ) )
3787 // SCHEMECOLOR
3788 if ( !GetColorFromPalette( ( nUpper & 8 ) ? (sal_uInt16)nColorCode : nUpper, aColor ) )
3790 switch( nContentProperty )
3792 case DFF_Prop_pictureTransparent :
3793 case DFF_Prop_shadowColor :
3794 case DFF_Prop_fillBackColor :
3795 case DFF_Prop_fillColor :
3796 aColor = Color( COL_WHITE );
3797 break;
3798 case DFF_Prop_lineColor :
3800 aColor = Color( COL_BLACK );
3802 break;
3806 else // SYSCOLOR
3808 const StyleSettings& rStyleSettings = Application::GetSettings().GetStyleSettings();
3810 // UINT16 nParameter = (BYTE)( nColorCode >> 16); // SJ: nice compiler optimization bug on windows, though downcasting
3811 UINT16 nParameter = sal_uInt16(( nColorCode >> 16 ) & 0x00ff); // the HiByte of nParameter is not zero, an exclusive AND is helping :o
3812 UINT16 nFunctionBits = (UINT16)( ( nColorCode & 0x00000f00 ) >> 8 );
3813 UINT16 nAdditionalFlags = (UINT16)( ( nColorCode & 0x0000f000) >> 8 );
3814 UINT16 nColorIndex = sal_uInt16(nColorCode & 0x00ff);
3815 UINT32 nPropColor = 0;
3817 sal_uInt16 nCProp = 0;
3819 switch ( nColorIndex )
3821 case mso_syscolorButtonFace : aColor = rStyleSettings.GetFaceColor(); break;
3822 case mso_syscolorWindowText : aColor = rStyleSettings.GetWindowTextColor(); break;
3823 case mso_syscolorMenu : aColor = rStyleSettings.GetMenuColor(); break;
3824 case mso_syscolor3DLight :
3825 case mso_syscolorButtonHighlight :
3826 case mso_syscolorHighlight : aColor = rStyleSettings.GetHighlightColor(); break;
3827 case mso_syscolorHighlightText : aColor = rStyleSettings.GetHighlightTextColor(); break;
3828 case mso_syscolorCaptionText : aColor = rStyleSettings.GetMenuTextColor(); break;
3829 case mso_syscolorActiveCaption : aColor = rStyleSettings.GetHighlightColor(); break;
3830 case mso_syscolorButtonShadow : aColor = rStyleSettings.GetShadowColor(); break;
3831 case mso_syscolorButtonText : aColor = rStyleSettings.GetButtonTextColor(); break;
3832 case mso_syscolorGrayText : aColor = rStyleSettings.GetDeactiveColor(); break;
3833 case mso_syscolorInactiveCaption : aColor = rStyleSettings.GetDeactiveColor(); break;
3834 case mso_syscolorInactiveCaptionText : aColor = rStyleSettings.GetDeactiveColor(); break;
3835 case mso_syscolorInfoBackground : aColor = rStyleSettings.GetFaceColor(); break;
3836 case mso_syscolorInfoText : aColor = rStyleSettings.GetInfoTextColor(); break;
3837 case mso_syscolorMenuText : aColor = rStyleSettings.GetMenuTextColor(); break;
3838 case mso_syscolorScrollbar : aColor = rStyleSettings.GetFaceColor(); break;
3839 case mso_syscolorWindow : aColor = rStyleSettings.GetWindowColor(); break;
3840 case mso_syscolorWindowFrame : aColor = rStyleSettings.GetWindowColor(); break;
3842 case mso_colorFillColor :
3844 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3845 nCProp = DFF_Prop_fillColor;
3847 break;
3848 case mso_colorLineOrFillColor : // ( use the line color only if there is a line )
3850 if ( GetPropertyValue( DFF_Prop_fNoLineDrawDash ) & 8 )
3852 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3853 nCProp = DFF_Prop_lineColor;
3855 else
3857 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff );
3858 nCProp = DFF_Prop_fillColor;
3861 break;
3862 case mso_colorLineColor :
3864 nPropColor = GetPropertyValue( DFF_Prop_lineColor, 0 );
3865 nCProp = DFF_Prop_lineColor;
3867 break;
3868 case mso_colorShadowColor :
3870 nPropColor = GetPropertyValue( DFF_Prop_shadowColor, 0x808080 );
3871 nCProp = DFF_Prop_shadowColor;
3873 break;
3874 case mso_colorThis : // ( use this color ... )
3876 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3877 nCProp = DFF_Prop_fillColor;
3879 break;
3880 case mso_colorFillBackColor :
3882 nPropColor = GetPropertyValue( DFF_Prop_fillBackColor, 0xffffff );
3883 nCProp = DFF_Prop_fillBackColor;
3885 break;
3886 case mso_colorLineBackColor :
3888 nPropColor = GetPropertyValue( DFF_Prop_lineBackColor, 0xffffff );
3889 nCProp = DFF_Prop_lineBackColor;
3891 break;
3892 case mso_colorFillThenLine : // ( use the fillcolor unless no fill and line )
3894 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3895 nCProp = DFF_Prop_fillColor;
3897 break;
3898 case mso_colorIndexMask : // ( extract the color index ) ?
3900 nPropColor = GetPropertyValue( DFF_Prop_fillColor, 0xffffff ); //?????????????
3901 nCProp = DFF_Prop_fillColor;
3903 break;
3905 if ( nCProp && ( nPropColor & 0x10000000 ) == 0 ) // beware of looping recursive
3906 aColor = MSO_CLR_ToColor( nPropColor, nCProp );
3908 if( nAdditionalFlags & 0x80 ) // make color gray
3910 UINT8 nZwi = aColor.GetLuminance();
3911 aColor = Color( nZwi, nZwi, nZwi );
3913 switch( nFunctionBits )
3915 case 0x01 : // darken color by parameter
3917 aColor.SetRed( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetRed() ) >> 8 ) );
3918 aColor.SetGreen( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetGreen() ) >> 8 ) );
3919 aColor.SetBlue( sal::static_int_cast< UINT8 >( ( nParameter * aColor.GetBlue() ) >> 8 ) );
3921 break;
3922 case 0x02 : // lighten color by parameter
3924 UINT16 nInvParameter = ( 0x00ff - nParameter ) * 0xff;
3925 aColor.SetRed( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetRed() ) ) >> 8 ) );
3926 aColor.SetGreen( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetGreen() ) ) >> 8 ) );
3927 aColor.SetBlue( sal::static_int_cast< UINT8 >( ( nInvParameter + ( nParameter * aColor.GetBlue() ) ) >> 8 ) );
3929 break;
3930 case 0x03 : // add grey level RGB(p,p,p)
3932 INT16 nR = (INT16)aColor.GetRed() + (INT16)nParameter;
3933 INT16 nG = (INT16)aColor.GetGreen() + (INT16)nParameter;
3934 INT16 nB = (INT16)aColor.GetBlue() + (INT16)nParameter;
3935 if ( nR > 0x00ff )
3936 nR = 0x00ff;
3937 if ( nG > 0x00ff )
3938 nG = 0x00ff;
3939 if ( nB > 0x00ff )
3940 nB = 0x00ff;
3941 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3943 break;
3944 case 0x04 : // substract grey level RGB(p,p,p)
3946 INT16 nR = (INT16)aColor.GetRed() - (INT16)nParameter;
3947 INT16 nG = (INT16)aColor.GetGreen() - (INT16)nParameter;
3948 INT16 nB = (INT16)aColor.GetBlue() - (INT16)nParameter;
3949 if ( nR < 0 )
3950 nR = 0;
3951 if ( nG < 0 )
3952 nG = 0;
3953 if ( nB < 0 )
3954 nB = 0;
3955 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3957 break;
3958 case 0x05 : // substract from grey level RGB(p,p,p)
3960 INT16 nR = (INT16)nParameter - (INT16)aColor.GetRed();
3961 INT16 nG = (INT16)nParameter - (INT16)aColor.GetGreen();
3962 INT16 nB = (INT16)nParameter - (INT16)aColor.GetBlue();
3963 if ( nR < 0 )
3964 nR = 0;
3965 if ( nG < 0 )
3966 nG = 0;
3967 if ( nB < 0 )
3968 nB = 0;
3969 aColor = Color( (UINT8)nR, (UINT8)nG, (UINT8)nB );
3971 break;
3972 case 0x06 : // per component: black if < p, white if >= p
3974 aColor.SetRed( aColor.GetRed() < nParameter ? 0x00 : 0xff );
3975 aColor.SetGreen( aColor.GetGreen() < nParameter ? 0x00 : 0xff );
3976 aColor.SetBlue( aColor.GetBlue() < nParameter ? 0x00 : 0xff );
3978 break;
3980 if ( nAdditionalFlags & 0x40 ) // top-bit invert
3981 aColor = Color( aColor.GetRed() ^ 0x80, aColor.GetGreen() ^ 0x80, aColor.GetBlue() ^ 0x80 );
3983 if ( nAdditionalFlags & 0x20 ) // invert color
3984 aColor = Color(0xff - aColor.GetRed(), 0xff - aColor.GetGreen(), 0xff - aColor.GetBlue());
3987 else if ( ( nUpper & 4 ) && ( ( nColorCode & 0xfffff8 ) == 0 ) )
3988 { // case of nUpper == 4 powerpoint takes this as agrument for a colorschemecolor
3989 GetColorFromPalette( nUpper, aColor );
3991 else // hart attributiert, eventuell mit Hinweis auf SYSTEMRGB
3992 aColor = Color( (BYTE)nColorCode, (BYTE)( nColorCode >> 8 ), (BYTE)( nColorCode >> 16 ) );
3993 return aColor;
3996 FASTBOOL SvxMSDffManager::ReadDffString(SvStream& rSt, String& rTxt) const
3998 FASTBOOL bRet=FALSE;
3999 DffRecordHeader aStrHd;
4000 if( !ReadCommonRecordHeader(aStrHd, rSt) )
4001 rSt.Seek( aStrHd.nFilePos );
4002 else if ( aStrHd.nRecType == DFF_PST_TextBytesAtom || aStrHd.nRecType == DFF_PST_TextCharsAtom )
4004 FASTBOOL bUniCode=aStrHd.nRecType==DFF_PST_TextCharsAtom;
4005 bRet=TRUE;
4006 ULONG nBytes = aStrHd.nRecLen;
4007 MSDFFReadZString( rSt, rTxt, nBytes, bUniCode );
4008 if( !bUniCode )
4010 for ( xub_StrLen n = 0; n < nBytes; n++ )
4012 if( rTxt.GetChar( n ) == 0x0B )
4013 rTxt.SetChar( n, ' ' ); // Weicher Umbruch
4014 // TODO: Zeilenumbruch im Absatz via Outliner setzen.
4017 aStrHd.SeekToEndOfRecord( rSt );
4019 else
4020 aStrHd.SeekToBegOfRecord( rSt );
4021 return bRet;
4024 // sj: I just want to set a string for a text object that may contain multiple
4025 // paragraphs. If I now take a look at the follwing code I get the impression that
4026 // our outliner is too complicate to be used properly,
4027 void SvxMSDffManager::ReadObjText( const String& rText, SdrObject* pObj ) const
4029 SdrTextObj* pText = PTR_CAST( SdrTextObj, pObj );
4030 if ( pText )
4032 SdrOutliner& rOutliner = pText->ImpGetDrawOutliner();
4033 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
4035 BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
4036 rOutliner.SetUpdateMode( FALSE );
4037 rOutliner.SetVertical( pText->IsVerticalWriting() );
4039 sal_uInt16 nParaIndex = 0;
4040 sal_uInt32 nParaSize;
4041 const sal_Unicode* pCurrent, *pBuf = rText.GetBuffer();
4042 const sal_Unicode* pEnd = rText.GetBuffer() + rText.Len();
4044 while( pBuf < pEnd )
4046 pCurrent = pBuf;
4048 for ( nParaSize = 0; pBuf < pEnd; )
4050 sal_Unicode nChar = *pBuf++;
4051 if ( nChar == 0xa )
4053 if ( ( pBuf < pEnd ) && ( *pBuf == 0xd ) )
4054 pBuf++;
4055 break;
4057 else if ( nChar == 0xd )
4059 if ( ( pBuf < pEnd ) && ( *pBuf == 0xa ) )
4060 pBuf++;
4061 break;
4063 else
4064 nParaSize++;
4066 ESelection aSelection( nParaIndex, 0, nParaIndex, 0 );
4067 String aParagraph( pCurrent, (sal_uInt16)nParaSize );
4068 if ( !nParaIndex && !aParagraph.Len() ) // SJ: we are crashing if the first paragraph is empty ?
4069 aParagraph += (sal_Unicode)' '; // otherwise these two lines can be removed.
4070 rOutliner.Insert( aParagraph, nParaIndex, 0 );
4071 rOutliner.SetParaAttribs( nParaIndex, rOutliner.GetEmptyItemSet() );
4073 SfxItemSet aParagraphAttribs( rOutliner.GetEmptyItemSet() );
4074 if ( !aSelection.nStartPos )
4075 aParagraphAttribs.Put( SfxBoolItem( EE_PARA_BULLETSTATE, FALSE ) );
4076 aSelection.nStartPos = 0;
4077 rOutliner.QuickSetAttribs( aParagraphAttribs, aSelection );
4078 nParaIndex++;
4080 OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
4081 rOutliner.Clear();
4082 rOutliner.SetUpdateMode( bOldUpdateMode );
4083 pText->SetOutlinerParaObject( pNewText );
4087 FASTBOOL SvxMSDffManager::ReadObjText(SvStream& rSt, SdrObject* pObj) const
4089 FASTBOOL bRet=FALSE;
4090 SdrTextObj* pText = PTR_CAST(SdrTextObj, pObj);
4091 if( pText )
4093 DffRecordHeader aTextHd;
4094 if( !ReadCommonRecordHeader(aTextHd, rSt) )
4095 rSt.Seek( aTextHd.nFilePos );
4096 else if ( aTextHd.nRecType==DFF_msofbtClientTextbox )
4098 bRet=TRUE;
4099 ULONG nRecEnd=aTextHd.GetRecEndFilePos();
4100 DffRecordHeader aHd;
4101 String aText;
4102 // UINT32 nInvent=pText->GetObjInventor();
4103 // UINT16 nIdent=pText->GetObjIdentifier();
4105 SdrOutliner& rOutliner=pText->ImpGetDrawOutliner();
4106 // sal_Int16 nMinDepth = rOutliner.GetMinDepth();
4107 USHORT nOutlMode = rOutliner.GetMode();
4109 { // Wohl 'nen kleiner Bug der EditEngine, das die
4110 // Absastzattribute bei Clear() nicht entfernt werden.
4111 FASTBOOL bClearParaAttribs = TRUE;
4112 rOutliner.SetStyleSheet( 0, NULL );
4113 SfxItemSet aSet(rOutliner.GetEmptyItemSet());
4114 aSet.Put(SvxColorItem( COL_BLACK ));
4115 rOutliner.SetParaAttribs(0,aSet);
4116 pText->SetMergedItemSet(aSet);
4118 bClearParaAttribs = FALSE;
4119 if( bClearParaAttribs )
4121 // Wohl 'nen kleiner Bug der EditEngine, dass die
4122 // Absastzattribute bei Clear() nicht entfernt werden.
4123 rOutliner.SetParaAttribs(0,rOutliner.GetEmptyItemSet());
4126 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
4128 // ULONG nFilePosMerker=rSt.Tell();
4129 ////////////////////////////////////
4130 // TextString und MetaChars lesen //
4131 ////////////////////////////////////
4134 if( !ReadCommonRecordHeader(aHd, rSt) )
4135 rSt.Seek( aHd.nFilePos );
4136 else
4138 switch (aHd.nRecType)
4140 //case TextHeaderAtom
4141 //case TextSpecInfoAtom
4142 case DFF_PST_TextBytesAtom:
4143 case DFF_PST_TextCharsAtom:
4145 aHd.SeekToBegOfRecord(rSt);
4146 ReadDffString(rSt, aText);
4148 break;
4149 case DFF_PST_TextRulerAtom :
4151 UINT16 nLen = (UINT16)aHd.nRecLen;
4152 if(nLen)
4154 UINT16 nVal1, nVal2, nVal3;
4155 UINT16 nDefaultTab = 2540; // PPT def: 1 Inch //rOutliner.GetDefTab();
4156 UINT16 nMostrightTab = 0;
4157 SfxItemSet aSet(rOutliner.GetEmptyItemSet());
4158 SvxTabStopItem aTabItem(0, 0, SVX_TAB_ADJUST_DEFAULT, EE_PARA_TABS);
4160 rSt >> nVal1;
4161 rSt >> nVal2;
4162 nLen -= 4;
4164 // Allg. TAB verstellt auf Wert in nVal3
4165 if(nLen && (nVal1 & 0x0001))
4167 rSt >> nVal3;
4168 nLen -= 2;
4169 nDefaultTab = (UINT16)(((UINT32)nVal3 * 1000) / 240);
4172 // Weitere, frei gesetzte TABs
4173 if(nLen && (nVal1 & 0x0004))
4175 rSt >> nVal1;
4176 nLen -= 2;
4178 // fest gesetzte TABs importieren
4179 while(nLen && nVal1--)
4181 rSt >> nVal2;
4182 rSt >> nVal3;
4183 nLen -= 4;
4185 UINT16 nNewTabPos = (UINT16)(((UINT32)nVal2 * 1000) / 240);
4186 if(nNewTabPos > nMostrightTab)
4187 nMostrightTab = nNewTabPos;
4189 SvxTabStop aTabStop(nNewTabPos);
4190 aTabItem.Insert(aTabStop);
4194 // evtl. noch default-TABs ergaenzen (immer)
4195 UINT16 nObjWidth = sal_uInt16(pObj->GetSnapRect().GetWidth() + 1);
4196 UINT16 nDefaultTabPos = nDefaultTab;
4198 while(nDefaultTabPos <= nObjWidth && nDefaultTabPos <= nMostrightTab)
4199 nDefaultTabPos =
4200 nDefaultTabPos + nDefaultTab;
4202 while(nDefaultTabPos <= nObjWidth)
4204 SvxTabStop aTabStop(nDefaultTabPos);
4205 aTabItem.Insert(aTabStop);
4206 nDefaultTabPos =
4207 nDefaultTabPos + nDefaultTab;
4210 // Falls TABs angelegt wurden, setze diese
4211 if(aTabItem.Count())
4213 aSet.Put(aTabItem);
4214 rOutliner.SetParaAttribs(0, aSet);
4218 break;
4220 aHd.SeekToEndOfRecord( rSt );
4223 while ( rSt.GetError() == 0 && rSt.Tell() < nRecEnd );
4225 ////////////////////////
4226 // SHIFT-Ret ersetzen //
4227 ////////////////////////
4228 if ( aText.Len() )
4230 aText += ' ';
4231 aText.SetChar( aText.Len()-1, 0x0D );
4232 rOutliner.SetText( aText, rOutliner.GetParagraph( 0 ) );
4234 // SHIFT-Ret ersetzen im Outliner
4235 if(aText.GetTokenCount(0x0B) > 1)
4237 UINT32 nParaCount = rOutliner.GetParagraphCount();
4238 for(UINT16 a=0;a<nParaCount;a++)
4240 Paragraph* pActPara = rOutliner.GetParagraph(a);
4241 String aParaText = rOutliner.GetText(pActPara);
4242 for(UINT16 b=0;b<aParaText.Len();b++)
4244 if( aParaText.GetChar( b ) == 0x0B)
4246 ESelection aSelection(a, b, a, b+1);
4247 rOutliner.QuickInsertLineBreak(aSelection);
4253 OutlinerParaObject* pNewText=rOutliner.CreateParaObject();
4254 rOutliner.Init( nOutlMode );
4255 pText->NbcSetOutlinerParaObject(pNewText);
4257 else
4258 aTextHd.SeekToBegOfRecord(rSt);
4261 return bRet;
4264 //static
4265 void SvxMSDffManager::MSDFFReadZString( SvStream& rIn, String& rStr,
4266 ULONG nRecLen, FASTBOOL bUniCode )
4268 sal_uInt16 nLen = (sal_uInt16)nRecLen;
4269 if( nLen )
4271 if ( bUniCode )
4272 nLen >>= 1;
4274 String sBuf;
4275 sal_Unicode* pBuf = sBuf.AllocBuffer( nLen );
4277 if( bUniCode )
4279 rIn.Read( (sal_Char*)pBuf, nLen << 1 );
4281 #ifdef OSL_BIGENDIAN
4282 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf )
4283 *pBuf = SWAPSHORT( *pBuf );
4284 #endif // ifdef OSL_BIGENDIAN
4286 else
4288 // use the String-Data as buffer for the 8bit characters and
4289 // change then all to unicode
4290 sal_Char* pReadPos = ((sal_Char*)pBuf) + nLen;
4291 rIn.Read( (sal_Char*)pReadPos, nLen );
4292 for( sal_uInt16 n = 0; n < nLen; ++n, ++pBuf, ++pReadPos )
4293 *pBuf = ByteString::ConvertToUnicode( *pReadPos, RTL_TEXTENCODING_MS_1252 );
4296 rStr = sBuf.EraseTrailingChars( 0 );
4298 else
4299 rStr.Erase();
4302 SdrObject* SvxMSDffManager::ImportFontWork( SvStream& rStCt, SfxItemSet& rSet, Rectangle& rBoundRect ) const
4304 SdrObject* pRet = NULL;
4305 String aObjectText;
4306 String aFontName;
4307 BOOL bTextRotate = FALSE;
4309 ((SvxMSDffManager*)this)->mnFix16Angle = 0; // we don't want to use this property in future
4310 if ( SeekToContent( DFF_Prop_gtextUNICODE, rStCt ) )
4311 MSDFFReadZString( rStCt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), TRUE );
4312 if ( SeekToContent( DFF_Prop_gtextFont, rStCt ) )
4313 MSDFFReadZString( rStCt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), TRUE );
4314 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 )
4316 // Text ist senkrecht formatiert, Box Kippen
4317 INT32 nHalfWidth = ( rBoundRect.GetWidth() + 1) >> 1;
4318 INT32 nHalfHeight = ( rBoundRect.GetHeight() + 1) >> 1;
4319 Point aTopLeft( rBoundRect.Left() + nHalfWidth - nHalfHeight,
4320 rBoundRect.Top() + nHalfHeight - nHalfWidth);
4321 Size aNewSize( rBoundRect.GetHeight(), rBoundRect.GetWidth() );
4322 Rectangle aNewRect( aTopLeft, aNewSize );
4323 rBoundRect = aNewRect;
4325 String aSrcText( aObjectText );
4326 aObjectText.Erase();
4327 for( UINT16 a = 0; a < aSrcText.Len(); a++ )
4329 aObjectText += aSrcText.GetChar( a );
4330 aObjectText += '\n';
4332 rSet.Put( SdrTextHorzAdjustItem( SDRTEXTHORZADJUST_CENTER ) );
4333 bTextRotate = TRUE;
4335 if ( aObjectText.Len() )
4336 { // FontWork-Objekt Mit dem Text in aObjectText erzeugen
4337 SdrObject* pNewObj = new SdrRectObj( OBJ_TEXT, rBoundRect );
4338 if( pNewObj )
4340 pNewObj->SetModel( pSdrModel );
4341 ((SdrRectObj*)pNewObj)->SetText( aObjectText );
4342 SdrFitToSizeType eFTS = SDRTEXTFIT_PROPORTIONAL;
4343 rSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
4344 rSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
4345 rSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
4346 rSet.Put( SvxFontItem( FAMILY_DONTKNOW, aFontName, String(),
4347 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
4349 pNewObj->SetMergedItemSet(rSet);
4351 pRet = pNewObj->ConvertToPolyObj( FALSE, FALSE );
4352 if( !pRet )
4353 pRet = pNewObj;
4354 else
4356 pRet->NbcSetSnapRect( rBoundRect );
4357 SdrObject::Free( pNewObj );
4359 if( bTextRotate )
4361 double a = 9000 * nPi180;
4362 pRet->NbcRotate( rBoundRect.Center(), 9000, sin( a ), cos( a ) );
4366 return pRet;
4369 static Size lcl_GetPrefSize(const Graphic& rGraf, MapMode aWanted)
4371 MapMode aPrefMapMode(rGraf.GetPrefMapMode());
4372 if (aPrefMapMode == aWanted)
4373 return rGraf.GetPrefSize();
4374 Size aRetSize;
4375 if (aPrefMapMode == MAP_PIXEL)
4377 aRetSize = Application::GetDefaultDevice()->PixelToLogic(
4378 rGraf.GetPrefSize(), aWanted);
4380 else
4382 aRetSize = Application::GetDefaultDevice()->LogicToLogic(
4383 rGraf.GetPrefSize(), rGraf.GetPrefMapMode(), aWanted);
4385 return aRetSize;
4388 // sj: if the parameter pSet is null, then the resulting crop bitmap will be stored in rGraf,
4389 // otherwise rGraf is untouched and pSet is used to store the corresponding SdrGrafCropItem
4390 static void lcl_ApplyCropping( const DffPropSet& rPropSet, SfxItemSet* pSet, Graphic& rGraf )
4392 sal_Int32 nCropTop = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromTop, 0 );
4393 sal_Int32 nCropBottom = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromBottom, 0 );
4394 sal_Int32 nCropLeft = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromLeft, 0 );
4395 sal_Int32 nCropRight = (sal_Int32)rPropSet.GetPropertyValue( DFF_Prop_cropFromRight, 0 );
4397 if( nCropTop || nCropBottom || nCropLeft || nCropRight )
4399 double fFactor;
4400 Size aCropSize;
4401 BitmapEx aCropBitmap;
4402 sal_uInt32 nTop( 0 ), nBottom( 0 ), nLeft( 0 ), nRight( 0 );
4404 if ( pSet ) // use crop attributes ?
4405 aCropSize = lcl_GetPrefSize( rGraf, MAP_100TH_MM );
4406 else
4408 aCropBitmap = rGraf.GetBitmapEx();
4409 aCropSize = aCropBitmap.GetSizePixel();
4411 if ( nCropTop )
4413 fFactor = (double)nCropTop / 65536.0;
4414 nTop = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
4416 if ( nCropBottom )
4418 fFactor = (double)nCropBottom / 65536.0;
4419 nBottom = (sal_uInt32)( ( (double)( aCropSize.Height() + 1 ) * fFactor ) + 0.5 );
4421 if ( nCropLeft )
4423 fFactor = (double)nCropLeft / 65536.0;
4424 nLeft = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
4426 if ( nCropRight )
4428 fFactor = (double)nCropRight / 65536.0;
4429 nRight = (sal_uInt32)( ( (double)( aCropSize.Width() + 1 ) * fFactor ) + 0.5 );
4431 if ( pSet ) // use crop attributes ?
4432 pSet->Put( SdrGrafCropItem( nLeft, nTop, nRight, nBottom ) );
4433 else
4435 Rectangle aCropRect( nLeft, nTop, aCropSize.Width() - nRight, aCropSize.Height() - nBottom );
4436 aCropBitmap.Crop( aCropRect );
4437 rGraf = aCropBitmap;
4442 SdrObject* SvxMSDffManager::ImportGraphic( SvStream& rSt, SfxItemSet& rSet, const DffObjData& rObjData ) const
4444 SdrObject* pRet = NULL;
4445 String aFilename;
4446 String aLinkFileName, aLinkFilterName;
4447 Rectangle aVisArea;
4449 MSO_BlipFlags eFlags = (MSO_BlipFlags)GetPropertyValue( DFF_Prop_pibFlags, mso_blipflagDefault );
4450 sal_uInt32 nBlipId = GetPropertyValue( DFF_Prop_pib, 0 );
4451 sal_Bool bGrfRead = sal_False,
4453 // Grafik verlinkt
4454 bLinkGrf = 0 != ( eFlags & mso_blipflagLinkToFile );
4456 Graphic aGraf; // be sure this graphic is deleted before swapping out
4457 if( SeekToContent( DFF_Prop_pibName, rSt ) )
4458 MSDFFReadZString( rSt, aFilename, GetPropertyValue( DFF_Prop_pibName ), TRUE );
4460 // UND, ODER folgendes:
4461 if( !( eFlags & mso_blipflagDoNotSave ) ) // Grafik embedded
4463 bGrfRead = GetBLIP( nBlipId, aGraf, &aVisArea );
4464 if ( !bGrfRead )
4467 Still no luck, lets look at the end of this record for a FBSE pool,
4468 this fallback is a specific case for how word does it sometimes
4470 rObjData.rSpHd.SeekToEndOfRecord( rSt );
4471 DffRecordHeader aHd;
4472 rSt >> aHd;
4473 if( DFF_msofbtBSE == aHd.nRecType )
4475 const ULONG nSkipBLIPLen = 20;
4476 const ULONG nSkipShapePos = 4;
4477 const ULONG nSkipBLIP = 4;
4478 const ULONG nSkip =
4479 nSkipBLIPLen + 4 + nSkipShapePos + 4 + nSkipBLIP;
4481 if (nSkip <= aHd.nRecLen)
4483 rSt.SeekRel(nSkip);
4484 if (0 == rSt.GetError())
4485 bGrfRead = GetBLIPDirect( rSt, aGraf, &aVisArea );
4490 if ( bGrfRead )
4492 // the writer is doing it's own cropping, so this part affects only impress and calc
4493 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_CROP_BITMAPS )
4494 lcl_ApplyCropping( *this, ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 ? &rSet : NULL, aGraf );
4496 if ( IsProperty( DFF_Prop_pictureTransparent ) )
4498 UINT32 nTransColor = GetPropertyValue( DFF_Prop_pictureTransparent, 0 );
4500 if ( aGraf.GetType() == GRAPHIC_BITMAP )
4502 BitmapEx aBitmapEx( aGraf.GetBitmapEx() );
4503 Bitmap aBitmap( aBitmapEx.GetBitmap() );
4504 Bitmap aMask( aBitmap.CreateMask( MSO_CLR_ToColor( nTransColor, DFF_Prop_pictureTransparent ), 9 ) );
4505 if ( aBitmapEx.IsTransparent() )
4506 aMask.CombineSimple( aBitmapEx.GetMask(), BMP_COMBINE_OR );
4507 aGraf = BitmapEx( aBitmap, aMask );
4511 sal_Int32 nContrast = GetPropertyValue( DFF_Prop_pictureContrast, 0x10000 );
4513 0x10000 is msoffice 50%
4514 < 0x10000 is in units of 1/50th of 0x10000 per 1%
4515 > 0x10000 is in units where
4516 a msoffice x% is stored as 50/(100-x) * 0x10000
4518 plus, a (ui) microsoft % ranges from 0 to 100, OOO
4519 from -100 to 100, so also normalize into that range
4521 if ( nContrast > 0x10000 )
4523 double fX = nContrast;
4524 fX /= 0x10000;
4525 fX /= 51; // 50 + 1 to round
4526 fX = 1/fX;
4527 nContrast = static_cast<sal_Int32>(fX);
4528 nContrast -= 100;
4529 nContrast = -nContrast;
4530 nContrast = (nContrast-50)*2;
4532 else if ( nContrast == 0x10000 )
4533 nContrast = 0;
4534 else
4536 nContrast *= 101; //100 + 1 to round
4537 nContrast /= 0x10000;
4538 nContrast -= 100;
4540 sal_Int16 nBrightness = (sal_Int16)( (sal_Int32)GetPropertyValue( DFF_Prop_pictureBrightness, 0 ) / 327 );
4541 sal_Int32 nGamma = GetPropertyValue( DFF_Prop_pictureGamma, 0x10000 );
4542 GraphicDrawMode eDrawMode = GRAPHICDRAWMODE_STANDARD;
4543 switch ( GetPropertyValue( DFF_Prop_pictureActive ) & 6 )
4545 case 4 : eDrawMode = GRAPHICDRAWMODE_GREYS; break;
4546 case 6 : eDrawMode = GRAPHICDRAWMODE_MONO; break;
4547 case 0 :
4549 //office considers the converted values of (in OOo) 70 to be the
4550 //"watermark" values, which can vary slightly due to rounding from the
4551 //above values
4552 if (( nContrast == -70 ) && ( nBrightness == 70 ))
4554 nContrast = 0;
4555 nBrightness = 0;
4556 eDrawMode = GRAPHICDRAWMODE_WATERMARK;
4559 break;
4562 if ( nContrast || nBrightness || ( nGamma != 0x10000 ) || ( eDrawMode != GRAPHICDRAWMODE_STANDARD ) )
4564 if ( ( rObjData.nSpFlags & SP_FOLESHAPE ) == 0 )
4566 if ( nBrightness )
4567 rSet.Put( SdrGrafLuminanceItem( nBrightness ) );
4568 if ( nContrast )
4569 rSet.Put( SdrGrafContrastItem( (sal_Int16)nContrast ) );
4570 if ( nGamma != 0x10000 )
4571 rSet.Put( SdrGrafGamma100Item( nGamma / 655 ) );
4572 if ( eDrawMode != GRAPHICDRAWMODE_STANDARD )
4573 rSet.Put( SdrGrafModeItem( eDrawMode ) );
4575 else
4577 if ( eDrawMode == GRAPHICDRAWMODE_WATERMARK )
4579 nContrast = 60;
4580 nBrightness = 70;
4581 eDrawMode = GRAPHICDRAWMODE_STANDARD;
4583 switch ( aGraf.GetType() )
4585 case GRAPHIC_BITMAP :
4587 BitmapEx aBitmapEx( aGraf.GetBitmapEx() );
4588 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
4589 aBitmapEx.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, FALSE );
4590 if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
4591 aBitmapEx.Convert( BMP_CONVERSION_8BIT_GREYS );
4592 else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
4593 aBitmapEx.Convert( BMP_CONVERSION_1BIT_THRESHOLD );
4594 aGraf = aBitmapEx;
4597 break;
4599 case GRAPHIC_GDIMETAFILE :
4601 GDIMetaFile aGdiMetaFile( aGraf.GetGDIMetaFile() );
4602 if ( nBrightness || nContrast || ( nGamma != 0x10000 ) )
4603 aGdiMetaFile.Adjust( nBrightness, (sal_Int16)nContrast, 0, 0, 0, (double)nGamma / 0x10000, FALSE );
4604 if ( eDrawMode == GRAPHICDRAWMODE_GREYS )
4605 aGdiMetaFile.Convert( MTF_CONVERSION_8BIT_GREYS );
4606 else if ( eDrawMode == GRAPHICDRAWMODE_MONO )
4607 aGdiMetaFile.Convert( MTF_CONVERSION_1BIT_THRESHOLD );
4608 aGraf = aGdiMetaFile;
4610 break;
4611 default: break;
4617 // sollte es ein OLE-Object sein?
4618 if( bGrfRead && !bLinkGrf && IsProperty( DFF_Prop_pictureId ) )
4620 // TODO/LATER: in future probably the correct aspect should be provided here
4621 sal_Int64 nAspect = embed::Aspects::MSOLE_CONTENT;
4622 // --> OD 2004-12-14 #i32596# - pass <nCalledByGroup> to method
4623 pRet = ImportOLE( GetPropertyValue( DFF_Prop_pictureId ), aGraf, rObjData.aBoundRect, aVisArea, rObjData.nCalledByGroup, nAspect );
4624 // <--
4626 if( !pRet )
4628 pRet = new SdrGrafObj;
4629 if( bGrfRead )
4630 ((SdrGrafObj*)pRet)->SetGraphic( aGraf );
4632 if( bLinkGrf && !bGrfRead ) // sj: #i55484# if the graphic was embedded ( bGrfRead == true ) then
4633 { // we do not need to set a link. TODO: not to lose the information where the graphic is linked from
4634 UniString aName( ::URIHelper::SmartRel2Abs( INetURLObject(maBaseURL), aFilename, URIHelper::GetMaybeFileHdl(), true, false,
4635 INetURLObject::WAS_ENCODED,
4636 INetURLObject::DECODE_UNAMBIGUOUS ) );
4638 String aFilterName;
4639 INetURLObject aURLObj( aName );
4641 if( aURLObj.GetProtocol() == INET_PROT_NOT_VALID )
4643 String aValidURL;
4645 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( aName, aValidURL ) )
4646 aURLObj = INetURLObject( aValidURL );
4649 if( aURLObj.GetProtocol() != INET_PROT_NOT_VALID )
4651 GraphicFilter* pGrfFilter = GetGrfFilter();
4652 aFilterName = pGrfFilter->GetImportFormatName(
4653 pGrfFilter->GetImportFormatNumberForShortName( aURLObj.getExtension() ) );
4656 aLinkFileName = aName;
4657 aLinkFilterName = aFilterName;
4661 // set the size from BLIP if there is one
4662 if ( pRet && bGrfRead && !aVisArea.IsEmpty() )
4663 pRet->SetBLIPSizeRectangle( aVisArea );
4665 if ( !pRet->GetName().Len() ) // SJ 22.02.00 : PPT OLE IMPORT:
4666 { // name is already set in ImportOLE !!
4667 // JP 01.12.99: SetName before SetModel - because in the other order the Bug 70098 is active
4668 if ( ( eFlags & mso_blipflagType ) != mso_blipflagComment )
4670 INetURLObject aURL;
4671 aURL.SetSmartURL( aFilename );
4672 pRet->SetName( aURL.getBase() );
4674 else
4675 pRet->SetName( aFilename );
4678 pRet->SetModel( pSdrModel ); // fuer GraphicLink erforderlich
4679 pRet->SetLogicRect( rObjData.aBoundRect );
4681 if ( pRet->ISA( SdrGrafObj ) )
4683 if( aLinkFileName.Len() )
4684 ((SdrGrafObj*)pRet)->SetGraphicLink( aLinkFileName, aLinkFilterName );
4686 if ( bLinkGrf && !bGrfRead )
4688 ((SdrGrafObj*)pRet)->ForceSwapIn();
4689 Graphic aGraf(((SdrGrafObj*)pRet)->GetGraphic());
4690 lcl_ApplyCropping( *this, &rSet, aGraf );
4692 ((SdrGrafObj*)pRet)->ForceSwapOut();
4695 return pRet;
4698 // PptSlidePersistEntry& rPersistEntry, SdPage* pPage
4699 SdrObject* SvxMSDffManager::ImportObj( SvStream& rSt, void* pClientData,
4700 Rectangle& rClientRect, const Rectangle& rGlobalChildRect, int nCalledByGroup, sal_Int32* pShapeId )
4702 SdrObject* pRet = NULL;
4703 DffRecordHeader aObjHd;
4704 rSt >> aObjHd;
4705 if ( aObjHd.nRecType == DFF_msofbtSpgrContainer )
4707 pRet = ImportGroup( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4709 else if ( aObjHd.nRecType == DFF_msofbtSpContainer )
4711 pRet = ImportShape( aObjHd, rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup, pShapeId );
4713 aObjHd.SeekToBegOfRecord( rSt ); // FilePos restaurieren
4714 return pRet;
4717 SdrObject* SvxMSDffManager::ImportGroup( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4718 Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4719 int nCalledByGroup, sal_Int32* pShapeId )
4721 SdrObject* pRet = NULL;
4723 if( pShapeId )
4724 *pShapeId = 0;
4726 rHd.SeekToContent( rSt );
4727 DffRecordHeader aRecHd; // the first atom has to be the SpContainer for the GroupObject
4728 rSt >> aRecHd;
4729 if ( aRecHd.nRecType == DFF_msofbtSpContainer )
4731 INT32 nGroupRotateAngle = 0;
4732 INT32 nSpFlags = 0;
4733 mnFix16Angle = 0;
4734 aRecHd.SeekToBegOfRecord( rSt );
4735 pRet = ImportObj( rSt, pClientData, rClientRect, rGlobalChildRect, nCalledByGroup + 1, pShapeId );
4736 if ( pRet )
4738 nSpFlags = nGroupShapeFlags;
4739 nGroupRotateAngle = mnFix16Angle;
4741 Rectangle aClientRect( rClientRect );
4743 Rectangle aGlobalChildRect;
4744 if ( !nCalledByGroup || rGlobalChildRect.IsEmpty() )
4745 aGlobalChildRect = GetGlobalChildAnchor( rHd, rSt, aClientRect );
4746 else
4747 aGlobalChildRect = rGlobalChildRect;
4749 if ( ( nGroupRotateAngle > 4500 && nGroupRotateAngle <= 13500 )
4750 || ( nGroupRotateAngle > 22500 && nGroupRotateAngle <= 31500 ) )
4752 sal_Int32 nHalfWidth = ( aClientRect.GetWidth() + 1 ) >> 1;
4753 sal_Int32 nHalfHeight = ( aClientRect.GetHeight() + 1 ) >> 1;
4754 Point aTopLeft( aClientRect.Left() + nHalfWidth - nHalfHeight,
4755 aClientRect.Top() + nHalfHeight - nHalfWidth );
4756 Size aNewSize( aClientRect.GetHeight(), aClientRect.GetWidth() );
4757 Rectangle aNewRect( aTopLeft, aNewSize );
4758 aClientRect = aNewRect;
4761 // now importing the inner objects of the group
4762 aRecHd.SeekToEndOfRecord( rSt );
4763 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
4765 DffRecordHeader aRecHd2;
4766 rSt >> aRecHd2;
4767 if ( aRecHd2.nRecType == DFF_msofbtSpgrContainer )
4769 Rectangle aGroupClientAnchor, aGroupChildAnchor;
4770 GetGroupAnchors( aRecHd2, rSt, aGroupClientAnchor, aGroupChildAnchor, aClientRect, aGlobalChildRect );
4771 aRecHd2.SeekToBegOfRecord( rSt );
4772 sal_Int32 nShapeId;
4773 SdrObject* pTmp = ImportGroup( aRecHd2, rSt, pClientData, aGroupClientAnchor, aGroupChildAnchor, nCalledByGroup + 1, &nShapeId );
4774 if ( pTmp )
4776 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4777 if( nShapeId )
4778 insertShapeId( nShapeId, pTmp );
4781 else if ( aRecHd2.nRecType == DFF_msofbtSpContainer )
4783 aRecHd2.SeekToBegOfRecord( rSt );
4784 sal_Int32 nShapeId;
4785 SdrObject* pTmp = ImportShape( aRecHd2, rSt, pClientData, aClientRect, aGlobalChildRect, nCalledByGroup + 1, &nShapeId );
4786 if ( pTmp )
4788 ((SdrObjGroup*)pRet)->GetSubList()->NbcInsertObject( pTmp );
4789 if( nShapeId )
4790 insertShapeId( nShapeId, pTmp );
4793 aRecHd2.SeekToEndOfRecord( rSt );
4796 // pRet->NbcSetSnapRect( aGroupBound );
4797 if ( nGroupRotateAngle )
4799 double a = nGroupRotateAngle * nPi180;
4800 pRet->NbcRotate( aClientRect.Center(), nGroupRotateAngle, sin( a ), cos( a ) );
4802 if ( nSpFlags & SP_FFLIPV ) // Vertikal gespiegelt?
4803 { // BoundRect in aBoundRect
4804 Point aLeft( aClientRect.Left(), ( aClientRect.Top() + aClientRect.Bottom() ) >> 1 );
4805 Point aRight( aLeft.X() + 1000, aLeft.Y() );
4806 pRet->NbcMirror( aLeft, aRight );
4808 if ( nSpFlags & SP_FFLIPH ) // Horizontal gespiegelt?
4809 { // BoundRect in aBoundRect
4810 Point aTop( ( aClientRect.Left() + aClientRect.Right() ) >> 1, aClientRect.Top() );
4811 Point aBottom( aTop.X(), aTop.Y() + 1000 );
4812 pRet->NbcMirror( aTop, aBottom );
4816 return pRet;
4819 SdrObject* SvxMSDffManager::ImportShape( const DffRecordHeader& rHd, SvStream& rSt, void* pClientData,
4820 Rectangle& rClientRect, const Rectangle& rGlobalChildRect,
4821 int nCalledByGroup, sal_Int32* pShapeId )
4823 SdrObject* pRet = NULL;
4825 if( pShapeId )
4826 *pShapeId = 0;
4828 rHd.SeekToBegOfRecord( rSt );
4829 DffObjData aObjData( rHd, rClientRect, nCalledByGroup );
4830 maShapeRecords.Consume( rSt, FALSE );
4831 aObjData.bShapeType = maShapeRecords.SeekToContent( rSt, DFF_msofbtSp, SEEK_FROM_BEGINNING );
4832 if ( aObjData.bShapeType )
4834 rSt >> aObjData.nShapeId
4835 >> aObjData.nSpFlags;
4836 aObjData.eShapeType = (MSO_SPT)maShapeRecords.Current()->nRecInstance;
4838 else
4840 aObjData.nShapeId = 0;
4841 aObjData.nSpFlags = 0;
4842 aObjData.eShapeType = mso_sptNil;
4845 if( pShapeId )
4846 *pShapeId = aObjData.nShapeId;
4848 if ( mbTracing )
4849 mpTracer->AddAttribute( aObjData.nSpFlags & SP_FGROUP
4850 ? rtl::OUString::createFromAscii( "GroupShape" )
4851 : rtl::OUString::createFromAscii( "Shape" ),
4852 rtl::OUString::valueOf( (sal_Int32)aObjData.nShapeId ) );
4853 aObjData.bOpt = maShapeRecords.SeekToContent( rSt, DFF_msofbtOPT, SEEK_FROM_CURRENT_AND_RESTART );
4854 if ( aObjData.bOpt )
4856 maShapeRecords.Current()->SeekToBegOfRecord( rSt );
4857 #ifdef DBG_AUTOSHAPE
4858 ReadPropSet( rSt, pClientData, (UINT32)aObjData.eShapeType );
4859 #else
4860 ReadPropSet( rSt, pClientData );
4861 #endif
4863 else
4865 InitializePropSet(); // get the default PropSet
4866 ( (DffPropertyReader*) this )->mnFix16Angle = 0;
4869 aObjData.bChildAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtChildAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4870 if ( aObjData.bChildAnchor )
4872 INT32 l, o, r, u;
4873 rSt >> l >> o >> r >> u;
4874 Scale( l );
4875 Scale( o );
4876 Scale( r );
4877 Scale( u );
4878 aObjData.aChildAnchor = Rectangle( l, o, r, u );
4879 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
4881 double fl = l;
4882 double fo = o;
4883 double fWidth = r - l;
4884 double fHeight= u - o;
4885 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
4886 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
4887 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
4888 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top();
4889 fWidth *= fXScale;
4890 fHeight *= fYScale;
4891 aObjData.aChildAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
4895 aObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt, DFF_msofbtClientAnchor, SEEK_FROM_CURRENT_AND_RESTART );
4896 if ( aObjData.bClientAnchor )
4897 ProcessClientAnchor2( rSt, *maShapeRecords.Current(), pClientData, aObjData );
4899 if ( aObjData.bChildAnchor )
4900 aObjData.aBoundRect = aObjData.aChildAnchor;
4902 if ( aObjData.nSpFlags & SP_FBACKGROUND )
4903 aObjData.aBoundRect = Rectangle( Point(), Size( 1, 1 ) );
4905 Rectangle aTextRect;
4906 if ( !aObjData.aBoundRect.IsEmpty() )
4907 { // Rotation auf BoundingBox anwenden, BEVOR ien Objekt generiert wurde
4908 if( mnFix16Angle )
4910 long nAngle = mnFix16Angle;
4911 if ( ( nAngle > 4500 && nAngle <= 13500 ) || ( nAngle > 22500 && nAngle <= 31500 ) )
4913 INT32 nHalfWidth = ( aObjData.aBoundRect.GetWidth() + 1 ) >> 1;
4914 INT32 nHalfHeight = ( aObjData.aBoundRect.GetHeight() + 1 ) >> 1;
4915 Point aTopLeft( aObjData.aBoundRect.Left() + nHalfWidth - nHalfHeight,
4916 aObjData.aBoundRect.Top() + nHalfHeight - nHalfWidth );
4917 Size aNewSize( aObjData.aBoundRect.GetHeight(), aObjData.aBoundRect.GetWidth() );
4918 Rectangle aNewRect( aTopLeft, aNewSize );
4919 aObjData.aBoundRect = aNewRect;
4922 aTextRect = aObjData.aBoundRect;
4923 FASTBOOL bGraphic = IsProperty( DFF_Prop_pib ) ||
4924 IsProperty( DFF_Prop_pibName ) ||
4925 IsProperty( DFF_Prop_pibFlags );
4927 if ( aObjData.nSpFlags & SP_FGROUP )
4929 pRet = new SdrObjGroup;
4930 /* After CWS aw033 has been integrated, an empty group object
4931 cannot store its resulting bounding rectangle anymore. We have
4932 to return this rectangle via rClientRect now, but only, if
4933 caller has not passed an own bounding ractangle. */
4934 if ( rClientRect.IsEmpty() )
4935 rClientRect = aObjData.aBoundRect;
4936 nGroupShapeFlags = aObjData.nSpFlags; // #73013#
4938 else if ( ( aObjData.eShapeType != mso_sptNil ) || IsProperty( DFF_Prop_pVertices ) || bGraphic )
4940 SfxItemSet aSet( pSdrModel->GetItemPool() );
4942 sal_Bool bIsConnector = ( ( aObjData.eShapeType >= mso_sptStraightConnector1 ) && ( aObjData.eShapeType <= mso_sptCurvedConnector5 ) );
4943 sal_Bool bIsCustomShape = sal_False;
4944 sal_Int32 nObjectRotation = mnFix16Angle;
4945 sal_uInt32 nSpFlags = aObjData.nSpFlags;
4947 if ( bGraphic )
4949 pRet = ImportGraphic( rSt, aSet, aObjData ); // SJ: #68396# is no longer true (fixed in ppt2000)
4950 ApplyAttributes( rSt, aSet, aObjData );
4951 pRet->SetMergedItemSet(aSet);
4953 else if ( aObjData.eShapeType == mso_sptLine )
4955 basegfx::B2DPolygon aPoly;
4956 aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Left(), aObjData.aBoundRect.Top()));
4957 aPoly.append(basegfx::B2DPoint(aObjData.aBoundRect.Right(), aObjData.aBoundRect.Bottom()));
4958 pRet = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aPoly));
4959 pRet->SetModel( pSdrModel );
4960 ApplyAttributes( rSt, aSet, aObjData );
4961 pRet->SetMergedItemSet(aSet);
4963 else
4965 if ( GetCustomShapeContent( aObjData.eShapeType ) || IsProperty( DFF_Prop_pVertices ) )
4968 ApplyAttributes( rSt, aSet, aObjData );
4970 // the com.sun.star.drawing.EnhancedCustomShapeEngine is default, so we do not need to set a hard attribute
4971 // aSet.Put( SdrCustomShapeEngineItem( String::CreateFromAscii( "com.sun.star.drawing.EnhancedCustomShapeEngine" ) ) );
4972 pRet = new SdrObjCustomShape();
4973 pRet->SetModel( pSdrModel );
4975 sal_Bool bIsFontwork = ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x4000 ) != 0;
4977 // in case of a FontWork, the text is set by the escher import
4978 if ( bIsFontwork )
4980 String aObjectText;
4981 String aFontName;
4982 MSO_GeoTextAlign eGeoTextAlign;
4984 if ( SeekToContent( DFF_Prop_gtextFont, rSt ) )
4986 SvxFontItem aLatin(EE_CHAR_FONTINFO), aAsian(EE_CHAR_FONTINFO_CJK), aComplex(EE_CHAR_FONTINFO_CTL);
4987 GetDefaultFonts( aLatin, aAsian, aComplex );
4989 MSDFFReadZString( rSt, aFontName, GetPropertyValue( DFF_Prop_gtextFont ), TRUE );
4990 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4991 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO ));
4992 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4993 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CJK ) );
4994 aSet.Put( SvxFontItem( aLatin.GetFamily(), aFontName, aLatin.GetStyleName(),
4995 PITCH_DONTKNOW, RTL_TEXTENCODING_DONTKNOW, EE_CHAR_FONTINFO_CTL ) );
4998 // SJ: applying fontattributes for Fontwork :
4999 if ( IsHardAttribute( DFF_Prop_gtextFItalic ) )
5000 aSet.Put( SvxPostureItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0010 ) != 0 ? ITALIC_NORMAL : ITALIC_NONE, EE_CHAR_ITALIC ) );
5002 if ( IsHardAttribute( DFF_Prop_gtextFBold ) )
5003 aSet.Put( SvxWeightItem( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x0020 ) != 0 ? WEIGHT_BOLD : WEIGHT_NORMAL, EE_CHAR_WEIGHT ) );
5005 // SJ TODO: Vertical Writing is not correct, instead this should be
5006 // replaced through "CharacterRotation" by 90°, therefore a new Item has to be
5007 // supported by svx core, api and xml file format
5008 ((SdrObjCustomShape*)pRet)->SetVerticalWriting( ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x2000 ) != 0 );
5010 if ( SeekToContent( DFF_Prop_gtextUNICODE, rSt ) )
5012 MSDFFReadZString( rSt, aObjectText, GetPropertyValue( DFF_Prop_gtextUNICODE ), TRUE );
5013 ReadObjText( aObjectText, pRet );
5016 eGeoTextAlign = ( (MSO_GeoTextAlign)GetPropertyValue( DFF_Prop_gtextAlign, mso_alignTextCenter ) );
5018 SdrTextHorzAdjust eHorzAdjust;
5019 switch( eGeoTextAlign )
5021 case mso_alignTextLetterJust :
5022 case mso_alignTextWordJust :
5023 case mso_alignTextStretch : eHorzAdjust = SDRTEXTHORZADJUST_BLOCK; break;
5024 default:
5025 case mso_alignTextInvalid :
5026 case mso_alignTextCenter : eHorzAdjust = SDRTEXTHORZADJUST_CENTER; break;
5027 case mso_alignTextLeft : eHorzAdjust = SDRTEXTHORZADJUST_LEFT; break;
5028 case mso_alignTextRight : eHorzAdjust = SDRTEXTHORZADJUST_RIGHT; break;
5030 aSet.Put( SdrTextHorzAdjustItem( eHorzAdjust ) );
5032 SdrFitToSizeType eFTS = SDRTEXTFIT_NONE;
5033 if ( eGeoTextAlign == mso_alignTextStretch )
5034 eFTS = SDRTEXTFIT_ALLLINES;
5035 aSet.Put( SdrTextFitToSizeTypeItem( eFTS ) );
5037 if ( IsProperty( DFF_Prop_gtextSpacing ) )
5039 sal_Int32 nTextWidth = GetPropertyValue( DFF_Prop_gtextSpacing, 100 < 16 ) / 655;
5040 if ( nTextWidth != 100 )
5041 aSet.Put( SvxCharScaleWidthItem( (sal_uInt16)nTextWidth, EE_CHAR_FONTWIDTH ) );
5043 if ( GetPropertyValue( DFF_Prop_gtextFStrikethrough, 0 ) & 0x1000 ) // SJ: Font Kerning On ?
5044 aSet.Put( SvxKerningItem( 1, EE_CHAR_KERNING ) );
5046 pRet->SetMergedItemSet( aSet );
5048 // sj: taking care of rtl, ltr. In case of fontwork mso. seems not to be able to set
5049 // proper text directions, instead the text default is depending to the string.
5050 // so we have to calculate the a text direction from string:
5051 if ( bIsFontwork )
5053 OutlinerParaObject* pParaObj = ((SdrObjCustomShape*)pRet)->GetOutlinerParaObject();
5054 if ( pParaObj )
5056 SdrOutliner& rOutliner = ((SdrObjCustomShape*)pRet)->ImpGetDrawOutliner();
5057 BOOL bOldUpdateMode = rOutliner.GetUpdateMode();
5058 SdrModel* pModel = pRet->GetModel();
5059 if ( pModel )
5060 rOutliner.SetStyleSheetPool( (SfxStyleSheetPool*)pModel->GetStyleSheetPool() );
5061 rOutliner.SetUpdateMode( FALSE );
5062 rOutliner.SetText( *pParaObj );
5063 VirtualDevice aVirDev( 1 );
5064 aVirDev.SetMapMode( MAP_100TH_MM );
5065 sal_uInt32 i, nParagraphs = rOutliner.GetParagraphCount();
5066 if ( nParagraphs )
5068 sal_Bool bCreateNewParaObject = sal_False;
5069 for ( i = 0; i < nParagraphs; i++ )
5071 BOOL bIsRTL = aVirDev.GetTextIsRTL( rOutliner.GetText( rOutliner.GetParagraph( i ) ), 0, STRING_LEN );
5072 if ( bIsRTL )
5074 SfxItemSet aSet2( rOutliner.GetParaAttribs( (USHORT)i ) );
5075 aSet2.Put( SvxFrameDirectionItem( FRMDIR_HORI_RIGHT_TOP, EE_PARA_WRITINGDIR ) );
5076 rOutliner.SetParaAttribs( (USHORT)i, aSet2 );
5077 bCreateNewParaObject = sal_True;
5080 if ( bCreateNewParaObject )
5082 OutlinerParaObject* pNewText = rOutliner.CreateParaObject();
5083 rOutliner.Init( OUTLINERMODE_TEXTOBJECT );
5084 ((SdrObjCustomShape*)pRet)->NbcSetOutlinerParaObject( pNewText );
5087 rOutliner.Clear();
5088 rOutliner.SetUpdateMode( bOldUpdateMode );
5092 // mso_sptArc special treating:
5093 // sj: since we actually can't render the arc because of its weird SnapRect settings,
5094 // we will create a new CustomShape, that can be saved/loaded without problems.
5095 // We will change the shape type, so this code applys only if importing arcs from msoffice.
5096 if ( aObjData.eShapeType == mso_sptArc )
5098 const rtl::OUString sAdjustmentValues( RTL_CONSTASCII_USTRINGPARAM ( "AdjustmentValues" ) );
5099 const rtl::OUString sCoordinates( RTL_CONSTASCII_USTRINGPARAM ( "Coordinates" ) );
5100 const rtl::OUString sHandles( RTL_CONSTASCII_USTRINGPARAM ( "Handles" ) );
5101 const rtl::OUString sEquations( RTL_CONSTASCII_USTRINGPARAM ( "Equations" ) );
5102 const rtl::OUString sViewBox( RTL_CONSTASCII_USTRINGPARAM ( "ViewBox" ) );
5103 const rtl::OUString sPath( RTL_CONSTASCII_USTRINGPARAM ( "Path" ) );
5104 const rtl::OUString sTextFrames( RTL_CONSTASCII_USTRINGPARAM ( "TextFrames" ) );
5105 SdrCustomShapeGeometryItem aGeometryItem( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
5106 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeParameterPair> seqCoordinates;
5107 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeAdjustmentValue > seqAdjustmentValues;
5109 // before clearing the GeometryItem we have to store the current Coordinates
5110 const uno::Any* pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sPath, sCoordinates );
5111 Rectangle aPolyBoundRect;
5112 if ( pAny && ( *pAny >>= seqCoordinates ) && ( seqCoordinates.getLength() >= 4 ) )
5114 sal_Int32 nPtNum, nNumElemVert = seqCoordinates.getLength();
5115 XPolygon aXP( (sal_uInt16)nNumElemVert );
5116 // const EnhancedCustomShapeParameterPair* pTmp = seqCoordinates.getArray();
5117 for ( nPtNum = 0; nPtNum < nNumElemVert; nPtNum++ )
5119 Point aP;
5120 sal_Int32 nX = 0, nY = 0;
5121 seqCoordinates[ nPtNum ].First.Value >>= nX;
5122 seqCoordinates[ nPtNum ].Second.Value >>= nY;
5123 aP.X() = nX;
5124 aP.Y() = nY;
5125 aXP[ (sal_uInt16)nPtNum ] = aP;
5127 aPolyBoundRect = Rectangle( aXP.GetBoundRect() );
5129 else
5130 aPolyBoundRect = Rectangle( -21600, 0, 21600, 43200 ); // defaulting
5132 // clearing items, so MergeDefaultAttributes will set the corresponding defaults from EnhancedCustomShapeGeometry
5133 aGeometryItem.ClearPropertyValue( sHandles );
5134 aGeometryItem.ClearPropertyValue( sEquations );
5135 aGeometryItem.ClearPropertyValue( sViewBox );
5136 aGeometryItem.ClearPropertyValue( sPath );
5138 sal_Int32 nEndAngle = 9000;
5139 sal_Int32 nStartAngle = 0;
5140 pAny = ((SdrCustomShapeGeometryItem&)aGeometryItem).GetPropertyValueByName( sAdjustmentValues );
5141 if ( pAny && ( *pAny >>= seqAdjustmentValues ) && seqAdjustmentValues.getLength() > 1 )
5143 double fNumber;
5144 if ( seqAdjustmentValues[ 0 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
5146 seqAdjustmentValues[ 0 ].Value >>= fNumber;
5147 nEndAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
5149 else
5151 fNumber = 270.0;
5152 seqAdjustmentValues[ 0 ].Value <<= fNumber;
5153 seqAdjustmentValues[ 0 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE; // so this value will properly be stored
5156 if ( seqAdjustmentValues[ 1 ].State == com::sun::star::beans::PropertyState_DIRECT_VALUE )
5158 seqAdjustmentValues[ 1 ].Value >>= fNumber;
5159 nStartAngle = NormAngle360( - (sal_Int32)fNumber * 100 );
5161 else
5163 fNumber = 0.0;
5164 seqAdjustmentValues[ 0 ].Value <<= fNumber;
5165 seqAdjustmentValues[ 1 ].State = com::sun::star::beans::PropertyState_DIRECT_VALUE;
5168 PropertyValue aPropVal;
5169 aPropVal.Name = sAdjustmentValues;
5170 aPropVal.Value <<= seqAdjustmentValues;
5171 aGeometryItem.SetPropertyValue( aPropVal ); // storing the angle attribute
5173 if ( nStartAngle != nEndAngle )
5175 XPolygon aXPoly( aPolyBoundRect.Center(), aPolyBoundRect.GetWidth() / 2, aPolyBoundRect.GetHeight() / 2,
5176 (USHORT)nStartAngle / 10, (USHORT)nEndAngle / 10, TRUE );
5177 Rectangle aPolyPieRect( aXPoly.GetBoundRect() );
5179 double fYScale, fXScale;
5180 double fYOfs, fXOfs;
5182 Point aP( aObjData.aBoundRect.Center() );
5183 Size aS( aObjData.aBoundRect.GetSize() );
5184 aP.X() -= aS.Width() / 2;
5185 aP.Y() -= aS.Height() / 2;
5186 Rectangle aLogicRect( aP, aS );
5188 fYOfs = fXOfs = 0.0;
5190 if ( aPolyBoundRect.GetWidth() && aPolyPieRect.GetWidth() )
5192 fXScale = (double)aLogicRect.GetWidth() / (double)aPolyPieRect.GetWidth();
5193 if ( nSpFlags & SP_FFLIPH )
5194 fXOfs = ( (double)aPolyPieRect.Right() - (double)aPolyBoundRect.Right() ) * fXScale;
5195 else
5196 fXOfs = ( (double)aPolyBoundRect.Left() - (double)aPolyPieRect.Left() ) * fXScale;
5198 if ( aPolyBoundRect.GetHeight() && aPolyPieRect.GetHeight() )
5200 fYScale = (double)aLogicRect.GetHeight() / (double)aPolyPieRect.GetHeight();
5201 if ( nSpFlags & SP_FFLIPV )
5202 fYOfs = ( (double)aPolyPieRect.Bottom() - (double)aPolyBoundRect.Bottom() ) * fYScale;
5203 else
5204 fYOfs = ((double)aPolyBoundRect.Top() - (double)aPolyPieRect.Top() ) * fYScale;
5207 fXScale = (double)aPolyBoundRect.GetWidth() / (double)aPolyPieRect.GetWidth();
5208 fYScale = (double)aPolyBoundRect.GetHeight() / (double)aPolyPieRect.GetHeight();
5210 Rectangle aOldBoundRect( aObjData.aBoundRect );
5211 aObjData.aBoundRect = Rectangle( Point( aLogicRect.Left() + (sal_Int32)fXOfs, aLogicRect.Top() + (sal_Int32)fYOfs ),
5212 Size( (sal_Int32)( aLogicRect.GetWidth() * fXScale ), (sal_Int32)( aLogicRect.GetHeight() * fYScale ) ) );
5214 // creating the text frame -> scaling into (0,0),(21600,21600) destination coordinate system
5215 double fTextFrameScaleX = (double)21600 / (double)aPolyBoundRect.GetWidth();
5216 double fTextFrameScaleY = (double)21600 / (double)aPolyBoundRect.GetHeight();
5217 sal_Int32 nLeft = (sal_Int32)(( aPolyPieRect.Left() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
5218 sal_Int32 nTop = (sal_Int32)(( aPolyPieRect.Top() - aPolyBoundRect.Top() ) * fTextFrameScaleY );
5219 sal_Int32 nRight = (sal_Int32)(( aPolyPieRect.Right() - aPolyBoundRect.Left() ) * fTextFrameScaleX );
5220 sal_Int32 nBottom= (sal_Int32)(( aPolyPieRect.Bottom()- aPolyBoundRect.Top() ) * fTextFrameScaleY );
5221 com::sun::star::uno::Sequence< com::sun::star::drawing::EnhancedCustomShapeTextFrame > aTextFrame( 1 );
5222 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.First, nLeft );
5223 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].TopLeft.Second, nTop );
5224 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.First, nRight );
5225 EnhancedCustomShape2d::SetEnhancedCustomShapeParameter( aTextFrame[ 0 ].BottomRight.Second,nBottom );
5226 PropertyValue aProp;
5227 aProp.Name = sTextFrames;
5228 aProp.Value <<= aTextFrame;
5229 aGeometryItem.SetPropertyValue( sPath, aProp );
5231 // sj: taking care of the different rotation points, since the new arc is having a bigger snaprect
5232 if ( mnFix16Angle )
5234 sal_Int32 nAngle = mnFix16Angle;
5235 if ( nSpFlags & SP_FFLIPH )
5236 nAngle = 36000 - nAngle;
5237 if ( nSpFlags & SP_FFLIPV )
5238 nAngle = -nAngle;
5239 double a = nAngle * F_PI18000;
5240 double ss = sin( a );
5241 double cc = cos( a );
5242 Point aP1( aOldBoundRect.TopLeft() );
5243 Point aC1( aObjData.aBoundRect.Center() );
5244 Point aP2( aOldBoundRect.TopLeft() );
5245 Point aC2( aOldBoundRect.Center() );
5246 RotatePoint( aP1, aC1, ss, cc );
5247 RotatePoint( aP2, aC2, ss, cc );
5248 aObjData.aBoundRect.Move( aP2.X() - aP1.X(), aP2.Y() - aP1.Y() );
5251 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeometryItem );
5252 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
5254 // now setting a new name, so the above correction is only done once when importing from ms
5255 SdrCustomShapeGeometryItem aGeoName( (SdrCustomShapeGeometryItem&)((SdrObjCustomShape*)pRet)->GetMergedItem( SDRATTR_CUSTOMSHAPE_GEOMETRY ) );
5256 const rtl::OUString sType( RTL_CONSTASCII_USTRINGPARAM ( "Type" ) );
5257 const rtl::OUString sName( RTL_CONSTASCII_USTRINGPARAM ( "mso-spt100" ) );
5258 PropertyValue aPropVal;
5259 aPropVal.Name = sType;
5260 aPropVal.Value <<= sName;
5261 aGeoName.SetPropertyValue( aPropVal );
5262 ((SdrObjCustomShape*)pRet)->SetMergedItem( aGeoName );
5264 else
5265 ((SdrObjCustomShape*)pRet)->MergeDefaultAttributes();
5267 pRet->SetSnapRect( aObjData.aBoundRect );
5268 EnhancedCustomShape2d aCustomShape2d( pRet );
5269 aTextRect = aCustomShape2d.GetTextRect();
5271 bIsCustomShape = TRUE;
5273 if( bIsConnector )
5275 if( nObjectRotation )
5277 double a = nObjectRotation * nPi180;
5278 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
5280 // Horizontal gespiegelt?
5281 if ( nSpFlags & SP_FFLIPH )
5283 Rectangle aBndRect( pRet->GetSnapRect() );
5284 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
5285 Point aBottom( aTop.X(), aTop.Y() + 1000 );
5286 pRet->NbcMirror( aTop, aBottom );
5288 // Vertikal gespiegelt?
5289 if ( nSpFlags & SP_FFLIPV )
5291 Rectangle aBndRect( pRet->GetSnapRect() );
5292 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
5293 Point aRight( aLeft.X() + 1000, aLeft.Y() );
5294 pRet->NbcMirror( aLeft, aRight );
5296 basegfx::B2DPolyPolygon aPoly( SdrObjCustomShape::GetLineGeometry( (SdrObjCustomShape*)pRet, sal_True ) );
5297 SdrObject::Free( pRet );
5299 pRet = new SdrEdgeObj();
5300 pRet->SetLogicRect( aObjData.aBoundRect );
5302 // Konnektoren
5303 MSO_ConnectorStyle eConnectorStyle = (MSO_ConnectorStyle)GetPropertyValue( DFF_Prop_cxstyle, mso_cxstyleStraight );
5305 ((SdrEdgeObj*)pRet)->ConnectToNode(TRUE, NULL);
5306 ((SdrEdgeObj*)pRet)->ConnectToNode(FALSE, NULL);
5308 Point aPoint1( aObjData.aBoundRect.TopLeft() );
5309 Point aPoint2( aObjData.aBoundRect.BottomRight() );
5311 // Rotationen beachten
5312 if ( nObjectRotation )
5314 double a = nObjectRotation * nPi180;
5315 Point aCenter( aObjData.aBoundRect.Center() );
5316 double ss = sin(a);
5317 double cc = cos(a);
5319 RotatePoint(aPoint1, aCenter, ss, cc);
5320 RotatePoint(aPoint2, aCenter, ss, cc);
5323 // Linie innerhalb des Bereiches zurechtdrehen/spiegeln
5324 if ( nSpFlags & SP_FFLIPH )
5326 INT32 n = aPoint1.X();
5327 aPoint1.X() = aPoint2.X();
5328 aPoint2.X() = n;
5330 if ( nSpFlags & SP_FFLIPV )
5332 INT32 n = aPoint1.Y();
5333 aPoint1.Y() = aPoint2.Y();
5334 aPoint2.Y() = n;
5336 nSpFlags &= ~( SP_FFLIPV | SP_FFLIPH );
5338 pRet->NbcSetPoint(aPoint1, 0L); // Startpunkt
5339 pRet->NbcSetPoint(aPoint2, 1L); // Endpunkt
5341 sal_Int32 n1HorzDist, n1VertDist, n2HorzDist, n2VertDist;
5342 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 0;
5343 switch( eConnectorStyle )
5345 case mso_cxstyleBent:
5347 aSet.Put( SdrEdgeKindItem( SDREDGE_ORTHOLINES ) );
5348 n1HorzDist = n1VertDist = n2HorzDist = n2VertDist = 630;
5350 break;
5351 case mso_cxstyleCurved:
5352 aSet.Put( SdrEdgeKindItem( SDREDGE_BEZIER ) );
5353 break;
5354 default: // mso_cxstyleStraight || mso_cxstyleNone
5355 aSet.Put( SdrEdgeKindItem( SDREDGE_ONELINE ) );
5356 break;
5358 aSet.Put( SdrEdgeNode1HorzDistItem( n1HorzDist ) );
5359 aSet.Put( SdrEdgeNode1VertDistItem( n1VertDist ) );
5360 aSet.Put( SdrEdgeNode2HorzDistItem( n2HorzDist ) );
5361 aSet.Put( SdrEdgeNode2VertDistItem( n2VertDist ) );
5363 ((SdrEdgeObj*)pRet)->SetEdgeTrackPath( aPoly );
5368 if ( pRet )
5370 if( nObjectRotation )
5372 double a = nObjectRotation * nPi180;
5373 pRet->NbcRotate( aObjData.aBoundRect.Center(), nObjectRotation, sin( a ), cos( a ) );
5375 // Horizontal gespiegelt?
5376 if ( nSpFlags & SP_FFLIPH )
5378 Rectangle aBndRect( pRet->GetSnapRect() );
5379 Point aTop( ( aBndRect.Left() + aBndRect.Right() ) >> 1, aBndRect.Top() );
5380 Point aBottom( aTop.X(), aTop.Y() + 1000 );
5381 pRet->NbcMirror( aTop, aBottom );
5383 // Vertikal gespiegelt?
5384 if ( nSpFlags & SP_FFLIPV )
5386 Rectangle aBndRect( pRet->GetSnapRect() );
5387 Point aLeft( aBndRect.Left(), ( aBndRect.Top() + aBndRect.Bottom() ) >> 1 );
5388 Point aRight( aLeft.X() + 1000, aLeft.Y() );
5389 pRet->NbcMirror( aLeft, aRight );
5395 // #i51348# #118052# name of the shape
5396 if( pRet )
5398 ::rtl::OUString aObjName = GetPropertyString( DFF_Prop_wzName, rSt );
5399 if( aObjName.getLength() > 0 )
5400 pRet->SetName( aObjName );
5403 pRet =
5404 ProcessObj( rSt, aObjData, pClientData, aTextRect, pRet);
5406 if ( mbTracing )
5407 mpTracer->RemoveAttribute( aObjData.nSpFlags & SP_FGROUP
5408 ? rtl::OUString::createFromAscii( "GroupShape" )
5409 : rtl::OUString::createFromAscii( "Shape" ) );
5410 return pRet;
5413 Rectangle SvxMSDffManager::GetGlobalChildAnchor( const DffRecordHeader& rHd, SvStream& rSt, Rectangle& aClientRect )
5415 Rectangle aChildAnchor;
5416 rHd.SeekToContent( rSt );
5417 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
5419 DffRecordHeader aShapeHd;
5420 rSt >> aShapeHd;
5421 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
5422 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
5424 DffRecordHeader aShapeHd2( aShapeHd );
5425 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
5426 rSt >> aShapeHd2;
5427 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
5429 DffRecordHeader aShapeAtom;
5430 rSt >> aShapeAtom;
5432 if ( aShapeAtom.nRecType == DFF_msofbtClientAnchor )
5434 if ( GetSvxMSDffSettings() & SVXMSDFF_SETTINGS_IMPORT_PPT )
5436 sal_Int32 l, t, r, b;
5437 if ( aShapeAtom.nRecLen == 16 )
5439 rSt >> l >> t >> r >> b;
5441 else
5443 INT16 ls, ts, rs, bs;
5444 rSt >> ts >> ls >> rs >> bs; // etwas seltsame Koordinatenreihenfolge ...
5445 l = ls, t = ts, r = rs, b = bs;
5447 Scale( l );
5448 Scale( t );
5449 Scale( r );
5450 Scale( b );
5451 aClientRect = Rectangle( l, t, r, b );
5453 break;
5455 else if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
5457 sal_Int32 l, o, r, u;
5458 rSt >> l >> o >> r >> u;
5459 Scale( l );
5460 Scale( o );
5461 Scale( r );
5462 Scale( u );
5463 Rectangle aChild( l, o, r, u );
5464 aChildAnchor.Union( aChild );
5465 break;
5467 aShapeAtom.SeekToEndOfRecord( rSt );
5470 aShapeHd.SeekToEndOfRecord( rSt );
5472 return aChildAnchor;
5475 void SvxMSDffManager::GetGroupAnchors( const DffRecordHeader& rHd, SvStream& rSt,
5476 Rectangle& rGroupClientAnchor, Rectangle& rGroupChildAnchor,
5477 const Rectangle& rClientRect, const Rectangle& rGlobalChildRect )
5479 sal_Bool bFirst = sal_True;
5480 rHd.SeekToContent( rSt );
5481 DffRecordHeader aShapeHd;
5482 while ( ( rSt.GetError() == 0 ) && ( rSt.Tell() < rHd.GetRecEndFilePos() ) )
5484 rSt >> aShapeHd;
5485 if ( ( aShapeHd.nRecType == DFF_msofbtSpContainer ) ||
5486 ( aShapeHd.nRecType == DFF_msofbtSpgrContainer ) )
5488 DffRecordHeader aShapeHd2( aShapeHd );
5489 if ( aShapeHd.nRecType == DFF_msofbtSpgrContainer )
5490 rSt >> aShapeHd2;
5491 while( ( rSt.GetError() == 0 ) && ( rSt.Tell() < aShapeHd2.GetRecEndFilePos() ) )
5493 DffRecordHeader aShapeAtom;
5494 rSt >> aShapeAtom;
5495 if ( aShapeAtom.nRecType == DFF_msofbtChildAnchor )
5497 sal_Int32 l, o, r, u;
5498 rSt >> l >> o >> r >> u;
5499 Scale( l );
5500 Scale( o );
5501 Scale( r );
5502 Scale( u );
5503 Rectangle aChild( l, o, r, u );
5505 if ( bFirst )
5507 if ( !rGlobalChildRect.IsEmpty() && !rClientRect.IsEmpty() && rGlobalChildRect.GetWidth() && rGlobalChildRect.GetHeight() )
5509 double fl = l;
5510 double fo = o;
5511 double fWidth = r - l;
5512 double fHeight= u - o;
5513 double fXScale = (double)rClientRect.GetWidth() / (double)rGlobalChildRect.GetWidth();
5514 double fYScale = (double)rClientRect.GetHeight() / (double)rGlobalChildRect.GetHeight();
5515 fl = ( ( l - rGlobalChildRect.Left() ) * fXScale ) + rClientRect.Left();
5516 fo = ( ( o - rGlobalChildRect.Top() ) * fYScale ) + rClientRect.Top();
5517 fWidth *= fXScale;
5518 fHeight *= fYScale;
5519 rGroupClientAnchor = Rectangle( Point( (sal_Int32)fl, (sal_Int32)fo ), Size( (sal_Int32)( fWidth + 1 ), (sal_Int32)( fHeight + 1 ) ) );
5521 bFirst = sal_False;
5523 else
5524 rGroupChildAnchor.Union( aChild );
5525 break;
5527 aShapeAtom.SeekToEndOfRecord( rSt );
5530 aShapeHd.SeekToEndOfRecord( rSt );
5534 SdrObject* SvxMSDffManager::ProcessObj(SvStream& rSt,
5535 DffObjData& rObjData,
5536 void* pData,
5537 Rectangle& rTextRect,
5538 SdrObject* pObj
5541 if( !rTextRect.IsEmpty() )
5543 SvxMSDffImportData& rImportData = *(SvxMSDffImportData*)pData;
5544 SvxMSDffImportRec* pImpRec = new SvxMSDffImportRec;
5545 SvxMSDffImportRec* pTextImpRec = pImpRec;
5547 // fill Import Record with data
5548 pImpRec->nShapeId = rObjData.nShapeId;
5549 pImpRec->eShapeType = rObjData.eShapeType;
5551 MSO_WrapMode eWrapMode( (MSO_WrapMode)GetPropertyValue(
5552 DFF_Prop_WrapText,
5553 mso_wrapSquare ) );
5554 rObjData.bClientAnchor = maShapeRecords.SeekToContent( rSt,
5555 DFF_msofbtClientAnchor,
5556 SEEK_FROM_CURRENT_AND_RESTART );
5557 if( rObjData.bClientAnchor )
5558 ProcessClientAnchor( rSt,
5559 maShapeRecords.Current()->nRecLen,
5560 pImpRec->pClientAnchorBuffer, pImpRec->nClientAnchorLen );
5562 rObjData.bClientData = maShapeRecords.SeekToContent( rSt,
5563 DFF_msofbtClientData,
5564 SEEK_FROM_CURRENT_AND_RESTART );
5565 if( rObjData.bClientData )
5566 ProcessClientData( rSt,
5567 maShapeRecords.Current()->nRecLen,
5568 pImpRec->pClientDataBuffer, pImpRec->nClientDataLen );
5571 // process user (== Winword) defined parameters in 0xF122 record
5572 if( maShapeRecords.SeekToContent( rSt,
5573 DFF_msofbtUDefProp,
5574 SEEK_FROM_CURRENT_AND_RESTART )
5575 && maShapeRecords.Current()->nRecLen )
5577 UINT32 nBytesLeft = maShapeRecords.Current()->nRecLen;
5578 UINT32 nUDData;
5579 UINT16 nPID;
5580 while( 5 < nBytesLeft )
5582 rSt >> nPID;
5583 if ( rSt.GetError() != 0 )
5584 break;
5585 rSt >> nUDData;
5586 switch( nPID )
5588 case 0x038F: pImpRec->nXAlign = nUDData; break;
5589 case 0x0390: pImpRec->nXRelTo = nUDData; break;
5590 case 0x0391: pImpRec->nYAlign = nUDData; break;
5591 case 0x0392: pImpRec->nYRelTo = nUDData; break;
5592 case 0x03BF: pImpRec->nLayoutInTableCell = nUDData; break;
5594 if ( rSt.GetError() != 0 )
5595 break;
5596 pImpRec->bHasUDefProp = TRUE;
5597 nBytesLeft -= 6;
5601 // Textrahmen, auch Title oder Outline
5602 SdrObject* pOrgObj = pObj;
5603 SdrRectObj* pTextObj = 0;
5604 UINT32 nTextId = GetPropertyValue( DFF_Prop_lTxid, 0 );
5605 if( nTextId )
5607 SfxItemSet aSet( pSdrModel->GetItemPool() );
5609 //Originally anything that as a mso_sptTextBox was created as a
5610 //textbox, this was changed for #88277# to be created as a simple
5611 //rect to keep impress happy. For the rest of us we'd like to turn
5612 //it back into a textbox again.
5613 FASTBOOL bTextFrame = (pImpRec->eShapeType == mso_sptTextBox);
5614 if (!bTextFrame)
5616 //Either
5617 //a) its a simple text object or
5618 //b) its a rectangle with text and square wrapping.
5619 bTextFrame =
5621 (pImpRec->eShapeType == mso_sptTextSimple) ||
5623 (pImpRec->eShapeType == mso_sptRectangle)
5624 && (eWrapMode == mso_wrapSquare)
5625 && ShapeHasText(pImpRec->nShapeId, rObjData.rSpHd.GetRecBegFilePos() )
5630 if (bTextFrame)
5632 SdrObject::Free( pObj );
5633 pObj = pOrgObj = 0;
5636 // Distance of Textbox to it's surrounding Customshape
5637 INT32 nTextLeft = GetPropertyValue( DFF_Prop_dxTextLeft, 91440L);
5638 INT32 nTextRight = GetPropertyValue( DFF_Prop_dxTextRight, 91440L );
5639 INT32 nTextTop = GetPropertyValue( DFF_Prop_dyTextTop, 45720L );
5640 INT32 nTextBottom = GetPropertyValue( DFF_Prop_dyTextBottom, 45720L );
5642 ScaleEmu( nTextLeft );
5643 ScaleEmu( nTextRight );
5644 ScaleEmu( nTextTop );
5645 ScaleEmu( nTextBottom );
5647 INT32 nTextRotationAngle=0;
5648 bool bVerticalText = false;
5649 if ( IsProperty( DFF_Prop_txflTextFlow ) )
5651 MSO_TextFlow eTextFlow = (MSO_TextFlow)(GetPropertyValue(
5652 DFF_Prop_txflTextFlow) & 0xFFFF);
5653 switch( eTextFlow )
5655 case mso_txflBtoT:
5656 nTextRotationAngle = 9000;
5657 break;
5658 case mso_txflVertN:
5659 case mso_txflTtoBN:
5660 nTextRotationAngle = 27000;
5661 break;
5662 case mso_txflTtoBA:
5663 bVerticalText = true;
5664 break;
5665 case mso_txflHorzA:
5666 bVerticalText = true;
5667 nTextRotationAngle = 9000;
5668 case mso_txflHorzN:
5669 default :
5670 break;
5674 if (nTextRotationAngle)
5676 while (nTextRotationAngle > 360000)
5677 nTextRotationAngle-=9000;
5678 switch (nTextRotationAngle)
5680 case 9000:
5682 long nWidth = rTextRect.GetWidth();
5683 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5684 rTextRect.Bottom() = rTextRect.Top() + nWidth;
5686 INT32 nOldTextLeft = nTextLeft;
5687 INT32 nOldTextRight = nTextRight;
5688 INT32 nOldTextTop = nTextTop;
5689 INT32 nOldTextBottom = nTextBottom;
5691 nTextLeft = nOldTextBottom;
5692 nTextRight = nOldTextTop;
5693 nTextTop = nOldTextLeft;
5694 nTextBottom = nOldTextRight;
5696 break;
5697 case 27000:
5699 long nWidth = rTextRect.GetWidth();
5700 rTextRect.Right() = rTextRect.Left() + rTextRect.GetHeight();
5701 rTextRect.Bottom() = rTextRect.Top() + nWidth;
5703 INT32 nOldTextLeft = nTextLeft;
5704 INT32 nOldTextRight = nTextRight;
5705 INT32 nOldTextTop = nTextTop;
5706 INT32 nOldTextBottom = nTextBottom;
5708 nTextLeft = nOldTextTop;
5709 nTextRight = nOldTextBottom;
5710 nTextTop = nOldTextRight;
5711 nTextBottom = nOldTextLeft;
5713 break;
5714 default:
5715 break;
5719 pTextObj = new SdrRectObj(OBJ_TEXT, rTextRect);
5720 pTextImpRec = new SvxMSDffImportRec(*pImpRec);
5722 // Die vertikalen Absatzeinrueckungen sind im BoundRect mit drin,
5723 // hier rausrechnen
5724 Rectangle aNewRect(rTextRect);
5725 aNewRect.Bottom() -= nTextTop + nTextBottom;
5726 aNewRect.Right() -= nTextLeft + nTextRight;
5728 // Nur falls es eine einfache Textbox ist, darf der Writer
5729 // das Objekt durch einen Rahmen ersetzen, ansonsten
5730 if( bTextFrame )
5732 SvxMSDffShapeInfo aTmpRec( 0, pImpRec->nShapeId );
5733 aTmpRec.bSortByShapeId = TRUE;
5735 USHORT nFound;
5736 if( pShapeInfos->Seek_Entry( &aTmpRec, &nFound ) )
5738 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject(nFound);
5739 pTextImpRec->bReplaceByFly = rInfo.bReplaceByFly;
5740 pTextImpRec->bLastBoxInChain = rInfo.bLastBoxInChain;
5744 if( !pObj )
5745 ApplyAttributes( rSt, aSet, rObjData );
5747 bool bFitText = false;
5748 if (GetPropertyValue(DFF_Prop_FitTextToShape) & 2)
5750 aSet.Put( SdrTextAutoGrowHeightItem( TRUE ) );
5751 aSet.Put( SdrTextMinFrameHeightItem(
5752 aNewRect.Bottom() - aNewRect.Top() ) );
5753 aSet.Put( SdrTextMinFrameWidthItem(
5754 aNewRect.Right() - aNewRect.Left() ) );
5755 bFitText = true;
5757 else
5759 aSet.Put( SdrTextAutoGrowHeightItem( FALSE ) );
5760 aSet.Put( SdrTextAutoGrowWidthItem( FALSE ) );
5763 switch ( (MSO_WrapMode)
5764 GetPropertyValue( DFF_Prop_WrapText, mso_wrapSquare ) )
5766 case mso_wrapNone :
5767 aSet.Put( SdrTextAutoGrowWidthItem( TRUE ) );
5768 if (bFitText)
5770 //can't do autowidth in flys #i107184#
5771 pTextImpRec->bReplaceByFly = false;
5773 break;
5774 case mso_wrapByPoints :
5775 aSet.Put( SdrTextContourFrameItem( TRUE ) );
5776 break;
5777 default: break;
5780 // Abstaende an den Raendern der Textbox setzen
5781 aSet.Put( SdrTextLeftDistItem( nTextLeft ) );
5782 aSet.Put( SdrTextRightDistItem( nTextRight ) );
5783 aSet.Put( SdrTextUpperDistItem( nTextTop ) );
5784 aSet.Put( SdrTextLowerDistItem( nTextBottom ) );
5785 pTextImpRec->nDxTextLeft = nTextLeft;
5786 pTextImpRec->nDyTextTop = nTextTop;
5787 pTextImpRec->nDxTextRight = nTextRight;
5788 pTextImpRec->nDyTextBottom = nTextBottom;
5790 // Textverankerung lesen
5791 if ( IsProperty( DFF_Prop_anchorText ) )
5793 MSO_Anchor eTextAnchor =
5794 (MSO_Anchor)GetPropertyValue( DFF_Prop_anchorText );
5796 SdrTextVertAdjust eTVA = SDRTEXTVERTADJUST_CENTER;
5797 BOOL bTVASet(FALSE);
5798 SdrTextHorzAdjust eTHA = SDRTEXTHORZADJUST_CENTER;
5799 BOOL bTHASet(FALSE);
5801 switch( eTextAnchor )
5803 case mso_anchorTop:
5805 eTVA = SDRTEXTVERTADJUST_TOP;
5806 bTVASet = TRUE;
5808 break;
5809 case mso_anchorTopCentered:
5811 eTVA = SDRTEXTVERTADJUST_TOP;
5812 bTVASet = TRUE;
5813 bTHASet = TRUE;
5815 break;
5817 case mso_anchorMiddle:
5818 bTVASet = TRUE;
5819 break;
5820 case mso_anchorMiddleCentered:
5822 bTVASet = TRUE;
5823 bTHASet = TRUE;
5825 break;
5826 case mso_anchorBottom:
5828 eTVA = SDRTEXTVERTADJUST_BOTTOM;
5829 bTVASet = TRUE;
5831 break;
5832 case mso_anchorBottomCentered:
5834 eTVA = SDRTEXTVERTADJUST_BOTTOM;
5835 bTVASet = TRUE;
5836 bTHASet = TRUE;
5838 break;
5840 case mso_anchorTopBaseline:
5841 case mso_anchorBottomBaseline:
5842 case mso_anchorTopCenteredBaseline:
5843 case mso_anchorBottomCenteredBaseline:
5844 break;
5846 default : break;
5848 // Einsetzen
5849 if ( bTVASet )
5850 aSet.Put( SdrTextVertAdjustItem( eTVA ) );
5851 if ( bTHASet )
5852 aSet.Put( SdrTextHorzAdjustItem( eTHA ) );
5855 pTextObj->SetMergedItemSet(aSet);
5856 pTextObj->SetModel(pSdrModel);
5858 if (bVerticalText)
5859 pTextObj->SetVerticalWriting(sal_True);
5861 if (nTextRotationAngle)
5863 long nMinWH = rTextRect.GetWidth() < rTextRect.GetHeight() ?
5864 rTextRect.GetWidth() : rTextRect.GetHeight();
5865 nMinWH /= 2;
5866 Point aPivot(rTextRect.TopLeft());
5867 aPivot.X() += nMinWH;
5868 aPivot.Y() += nMinWH;
5869 double a = nTextRotationAngle * nPi180;
5870 pTextObj->NbcRotate(aPivot, nTextRotationAngle, sin(a), cos(a));
5873 // rotate text with shape ?
5874 if ( mnFix16Angle )
5876 double a = mnFix16Angle * nPi180;
5877 pTextObj->NbcRotate( rObjData.aBoundRect.Center(), mnFix16Angle,
5878 sin( a ), cos( a ) );
5881 if( !pObj )
5883 pObj = pTextObj;
5885 else
5887 if( pTextObj != pObj )
5889 SdrObject* pGroup = new SdrObjGroup;
5890 pGroup->GetSubList()->NbcInsertObject( pObj );
5891 pGroup->GetSubList()->NbcInsertObject( pTextObj );
5892 if (pOrgObj == pObj)
5893 pOrgObj = pGroup;
5894 else
5895 pOrgObj = pObj;
5896 pObj = pGroup;
5900 else if( !pObj )
5902 // simple rectangular objects are ignored by ImportObj() :-(
5903 // this is OK for Draw but not for Calc and Writer
5904 // cause here these objects have a default border
5905 pObj = new SdrRectObj(rTextRect);
5906 pOrgObj = pObj;
5907 pObj->SetModel( pSdrModel );
5908 SfxItemSet aSet( pSdrModel->GetItemPool() );
5909 ApplyAttributes( rSt, aSet, rObjData );
5911 const SfxPoolItem* pPoolItem=NULL;
5912 SfxItemState eState = aSet.GetItemState( XATTR_FILLCOLOR,
5913 FALSE, &pPoolItem );
5914 if( SFX_ITEM_DEFAULT == eState )
5915 aSet.Put( XFillColorItem( String(),
5916 Color( mnDefaultColor ) ) );
5917 pObj->SetMergedItemSet(aSet);
5920 //Means that fBehindDocument is set
5921 if (GetPropertyValue(DFF_Prop_fPrint) & 0x20)
5922 pImpRec->bDrawHell = TRUE;
5923 else
5924 pImpRec->bDrawHell = FALSE;
5925 if (GetPropertyValue(DFF_Prop_fPrint) & 0x02)
5926 pImpRec->bHidden = TRUE;
5927 pTextImpRec->bDrawHell = pImpRec->bDrawHell;
5928 pTextImpRec->bHidden = pImpRec->bHidden;
5929 pImpRec->nNextShapeId = GetPropertyValue( DFF_Prop_hspNext, 0 );
5930 pTextImpRec->nNextShapeId=pImpRec->nNextShapeId;
5932 if ( nTextId )
5934 pTextImpRec->aTextId.nTxBxS = (UINT16)( nTextId >> 16 );
5935 pTextImpRec->aTextId.nSequence = (UINT16)nTextId;
5938 pTextImpRec->nDxWrapDistLeft = GetPropertyValue(
5939 DFF_Prop_dxWrapDistLeft, 114935L ) / 635L;
5940 pTextImpRec->nDyWrapDistTop = GetPropertyValue(
5941 DFF_Prop_dyWrapDistTop, 0 ) / 635L;
5942 pTextImpRec->nDxWrapDistRight = GetPropertyValue(
5943 DFF_Prop_dxWrapDistRight, 114935L ) / 635L;
5944 pTextImpRec->nDyWrapDistBottom = GetPropertyValue(
5945 DFF_Prop_dyWrapDistBottom, 0 ) / 635L;
5946 // 16.16 fraction times total image width or height, as appropriate.
5948 if (SeekToContent(DFF_Prop_pWrapPolygonVertices, rSt))
5950 delete pTextImpRec->pWrapPolygon;
5951 sal_uInt16 nNumElemVert, nNumElemMemVert, nElemSizeVert;
5952 rSt >> nNumElemVert >> nNumElemMemVert >> nElemSizeVert;
5953 if (nNumElemVert && ((nElemSizeVert == 8) || (nElemSizeVert == 4)))
5955 pTextImpRec->pWrapPolygon = new Polygon(nNumElemVert);
5956 for (sal_uInt16 i = 0; i < nNumElemVert; ++i)
5958 sal_Int32 nX, nY;
5959 if (nElemSizeVert == 8)
5960 rSt >> nX >> nY;
5961 else
5963 sal_Int16 nSmallX, nSmallY;
5964 rSt >> nSmallX >> nSmallY;
5965 nX = nSmallX;
5966 nY = nSmallY;
5968 (*(pTextImpRec->pWrapPolygon))[i].X() = nX;
5969 (*(pTextImpRec->pWrapPolygon))[i].Y() = nY;
5974 pImpRec->nCropFromTop = GetPropertyValue(
5975 DFF_Prop_cropFromTop, 0 );
5976 pImpRec->nCropFromBottom = GetPropertyValue(
5977 DFF_Prop_cropFromBottom, 0 );
5978 pImpRec->nCropFromLeft = GetPropertyValue(
5979 DFF_Prop_cropFromLeft, 0 );
5980 pImpRec->nCropFromRight = GetPropertyValue(
5981 DFF_Prop_cropFromRight, 0 );
5983 pImpRec->bVFlip = (rObjData.nSpFlags & SP_FFLIPV) ? true : false;
5984 pImpRec->bHFlip = (rObjData.nSpFlags & SP_FFLIPH) ? true : false;
5986 UINT32 nLineFlags = GetPropertyValue( DFF_Prop_fNoLineDrawDash );
5987 pImpRec->eLineStyle = (nLineFlags & 8)
5988 ? (MSO_LineStyle)GetPropertyValue(
5989 DFF_Prop_lineStyle,
5990 mso_lineSimple )
5991 : (MSO_LineStyle)USHRT_MAX;
5992 pTextImpRec->eLineStyle = pImpRec->eLineStyle;
5994 if( pImpRec->nShapeId )
5996 // Import-Record-Liste ergaenzen
5997 if( pOrgObj )
5999 pImpRec->pObj = pOrgObj;
6000 rImportData.aRecords.Insert( pImpRec );
6003 if( pTextObj && (pOrgObj != pTextObj) )
6005 // Modify ShapeId (must be unique)
6006 pImpRec->nShapeId |= 0x8000000;
6007 pTextImpRec->pObj = pTextObj;
6008 rImportData.aRecords.Insert( pTextImpRec );
6011 // Eintrag in Z-Order-Liste um Zeiger auf dieses Objekt ergaenzen
6012 /*Only store objects which are not deep inside the tree*/
6013 if( ( rObjData.nCalledByGroup == 0 )
6015 ( (rObjData.nSpFlags & SP_FGROUP)
6016 && (rObjData.nCalledByGroup < 2) )
6018 StoreShapeOrder( pImpRec->nShapeId,
6019 ( ( (ULONG)pImpRec->aTextId.nTxBxS ) << 16 )
6020 + pImpRec->aTextId.nSequence, pObj );
6022 else
6023 delete pImpRec;
6026 return pObj;
6029 void SvxMSDffManager::StoreShapeOrder(ULONG nId,
6030 ULONG nTxBx,
6031 SdrObject* pObject,
6032 SwFlyFrmFmt* pFly,
6033 short nHdFtSection) const
6035 USHORT nShpCnt = pShapeOrders->Count();
6036 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
6038 SvxMSDffShapeOrder& rOrder
6039 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
6041 if( rOrder.nShapeId == nId )
6043 rOrder.nTxBxComp = nTxBx;
6044 rOrder.pObj = pObject;
6045 rOrder.pFly = pFly;
6046 rOrder.nHdFtSection = nHdFtSection;
6052 void SvxMSDffManager::ExchangeInShapeOrder( SdrObject* pOldObject,
6053 ULONG nTxBx,
6054 SwFlyFrmFmt* pFly,
6055 SdrObject* pObject) const
6057 USHORT nShpCnt = pShapeOrders->Count();
6058 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
6060 SvxMSDffShapeOrder& rOrder
6061 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
6063 if( rOrder.pObj == pOldObject )
6065 rOrder.pFly = pFly;
6066 rOrder.pObj = pObject;
6067 rOrder.nTxBxComp = nTxBx;
6073 void SvxMSDffManager::RemoveFromShapeOrder( SdrObject* pObject ) const
6075 USHORT nShpCnt = pShapeOrders->Count();
6076 for (USHORT nShapeNum=0; nShapeNum < nShpCnt; nShapeNum++)
6078 SvxMSDffShapeOrder& rOrder
6079 = *(SvxMSDffShapeOrder*)(pShapeOrders->GetObject( nShapeNum ));
6081 if( rOrder.pObj == pObject )
6083 rOrder.pObj = 0;
6084 rOrder.pFly = 0;
6085 rOrder.nTxBxComp = 0;
6093 //---------------------------------------------------------------------------
6094 // Hilfs Deklarationen
6095 //---------------------------------------------------------------------------
6097 /*struct SvxMSDffBLIPInfo -> in's Header-File
6099 USHORT nBLIPType; // Art des BLIP: z.B. 6 fuer PNG
6100 ULONG nFilePos; // Offset des BLIP im Daten-Stream
6101 ULONG nBLIPSize; // Anzahl Bytes, die der BLIP im Stream einnimmt
6102 SvxMSDffBLIPInfo(USHORT nBType, ULONG nFPos, ULONG nBSize):
6103 nBLIPType( nBType ), nFilePos( nFPos ), nBLIPSize( nBSize ){}
6107 SV_IMPL_PTRARR( SvxMSDffBLIPInfos, SvxMSDffBLIPInfo_Ptr );
6109 SV_IMPL_PTRARR( SvxMSDffShapeOrders, SvxMSDffShapeOrder_Ptr );
6111 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeInfos, SvxMSDffShapeInfo_Ptr );
6113 SV_IMPL_OP_PTRARR_SORT( SvxMSDffShapeTxBxSort, SvxMSDffShapeOrder_Ptr );
6116 // Liste aller SvxMSDffImportRec fuer eine Gruppe
6117 SV_IMPL_OP_PTRARR_SORT(MSDffImportRecords, MSDffImportRec_Ptr)
6119 //---------------------------------------------------------------------------
6120 // exportierte Klasse: oeffentliche Methoden
6121 //---------------------------------------------------------------------------
6123 SvxMSDffManager::SvxMSDffManager(SvStream& rStCtrl_,
6124 const String& rBaseURL,
6125 long nOffsDgg_,
6126 SvStream* pStData_,
6127 SdrModel* pSdrModel_,// s. unten: SetModel()
6128 long nApplicationScale,
6129 ColorData mnDefaultColor_,
6130 ULONG nDefaultFontHeight_,
6131 SvStream* pStData2_,
6132 MSFilterTracer* pTracer )
6133 :DffPropertyReader( *this ),
6134 pFormModel( NULL ),
6135 pBLIPInfos( new SvxMSDffBLIPInfos ),
6136 pShapeInfos( new SvxMSDffShapeInfos ),
6137 pShapeOrders( new SvxMSDffShapeOrders ),
6138 nDefaultFontHeight( nDefaultFontHeight_),
6139 nOffsDgg( nOffsDgg_ ),
6140 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen,
6141 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt
6142 maBaseURL( rBaseURL ),
6143 mpFidcls( NULL ),
6144 rStCtrl( rStCtrl_ ),
6145 pStData( pStData_ ),
6146 pStData2( pStData2_ ),
6147 nSvxMSDffSettings( 0 ),
6148 nSvxMSDffOLEConvFlags( 0 ),
6149 pEscherBlipCache( NULL ),
6150 mnDefaultColor( mnDefaultColor_),
6151 mpTracer( pTracer ),
6152 mbTracing( sal_False )
6154 if ( mpTracer )
6156 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
6157 aAny >>= mbTracing;
6159 SetModel( pSdrModel_, nApplicationScale );
6161 // FilePos des/der Stream(s) merken
6162 ULONG nOldPosCtrl = rStCtrl.Tell();
6163 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6165 // Falls kein Datenstream angegeben, gehen wir davon aus,
6166 // dass die BLIPs im Steuerstream stehen.
6167 if( !pStData )
6168 pStData = &rStCtrl;
6170 SetDefaultPropSet( rStCtrl, nOffsDgg );
6172 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
6173 GetCtrlData( nOffsDgg );
6175 // Text-Box-Story-Ketten-Infos ueberpruefen
6176 CheckTxBxStoryChain();
6178 // alte FilePos des/der Stream(s) restaurieren
6179 rStCtrl.Seek( nOldPosCtrl );
6180 if( &rStCtrl != pStData )
6181 pStData->Seek( nOldPosData );
6184 SvxMSDffManager::SvxMSDffManager( SvStream& rStCtrl_, const String& rBaseURL, MSFilterTracer* pTracer )
6185 :DffPropertyReader( *this ),
6186 pFormModel( NULL ),
6187 pBLIPInfos( new SvxMSDffBLIPInfos ),
6188 pShapeInfos( new SvxMSDffShapeInfos ),
6189 pShapeOrders( new SvxMSDffShapeOrders ),
6190 nDefaultFontHeight( 24 ),
6191 nOffsDgg( 0 ),
6192 nBLIPCount( USHRT_MAX ), // mit Error initialisieren, da wir erst pruefen,
6193 nShapeCount( USHRT_MAX ), // ob Kontroll-Stream korrekte Daten enthaellt
6194 maBaseURL( rBaseURL ),
6195 mpFidcls( NULL ),
6196 rStCtrl( rStCtrl_ ),
6197 pStData( 0 ),
6198 pStData2( 0 ),
6199 nSvxMSDffSettings( 0 ),
6200 nSvxMSDffOLEConvFlags( 0 ),
6201 pEscherBlipCache( NULL ),
6202 mnDefaultColor( COL_DEFAULT ),
6203 mpTracer( pTracer ),
6204 mbTracing( sal_False )
6206 if ( mpTracer )
6208 uno::Any aAny( mpTracer->GetProperty( rtl::OUString::createFromAscii( "On" ) ) );
6209 aAny >>= mbTracing;
6211 SetModel( NULL, 0 );
6214 SvxMSDffManager::~SvxMSDffManager()
6216 if ( pEscherBlipCache )
6218 void* pPtr;
6219 for ( pPtr = pEscherBlipCache->First(); pPtr; pPtr = pEscherBlipCache->Next() )
6220 delete (EscherBlipCacheEntry*)pPtr;
6221 delete pEscherBlipCache;
6223 delete pBLIPInfos;
6224 delete pShapeInfos;
6225 delete pShapeOrders;
6226 delete pFormModel;
6227 delete[] mpFidcls;
6230 void SvxMSDffManager::InitSvxMSDffManager( long nOffsDgg_, SvStream* pStData_, sal_uInt32 nOleConvFlags )
6232 nOffsDgg = nOffsDgg_;
6233 pStData = pStData_;
6234 nSvxMSDffOLEConvFlags = nOleConvFlags;
6236 // FilePos des/der Stream(s) merken
6237 ULONG nOldPosCtrl = rStCtrl.Tell();
6239 SetDefaultPropSet( rStCtrl, nOffsDgg );
6241 // insert fidcl cluster table
6242 GetFidclData( nOffsDgg );
6244 // Steuer Stream auslesen, im Erfolgsfall nBLIPCount setzen
6245 GetCtrlData( nOffsDgg );
6247 // Text-Box-Story-Ketten-Infos ueberpruefen
6248 CheckTxBxStoryChain();
6250 // alte FilePos des/der Stream(s) restaurieren
6251 rStCtrl.Seek( nOldPosCtrl );
6254 void SvxMSDffManager::SetDgContainer( SvStream& rSt )
6256 UINT32 nFilePos = rSt.Tell();
6257 DffRecordHeader aDgContHd;
6258 rSt >> aDgContHd;
6259 // insert this container only if there is also a DgAtom
6260 if ( SeekToRec( rSt, DFF_msofbtDg, aDgContHd.GetRecEndFilePos() ) )
6262 DffRecordHeader aRecHd;
6263 rSt >> aRecHd;
6264 UINT32 nDrawingId = aRecHd.nRecInstance;
6265 maDgOffsetTable.Insert( nDrawingId, (void*)nFilePos );
6266 rSt.Seek( nFilePos );
6270 void SvxMSDffManager::GetFidclData( long nOffsDggL )
6272 if ( nOffsDggL )
6274 UINT32 nDummy, nMerk = rStCtrl.Tell();
6275 rStCtrl.Seek( nOffsDggL );
6277 DffRecordHeader aRecHd;
6278 rStCtrl >> aRecHd;
6280 DffRecordHeader aDggAtomHd;
6281 if ( SeekToRec( rStCtrl, DFF_msofbtDgg, aRecHd.GetRecEndFilePos(), &aDggAtomHd ) )
6283 aDggAtomHd.SeekToContent( rStCtrl );
6284 rStCtrl >> mnCurMaxShapeId
6285 >> mnIdClusters
6286 >> nDummy
6287 >> mnDrawingsSaved;
6289 if ( mnIdClusters-- > 2 )
6291 if ( aDggAtomHd.nRecLen == ( mnIdClusters * sizeof( FIDCL ) + 16 ) )
6293 mpFidcls = new FIDCL[ mnIdClusters ];
6294 for ( UINT32 i = 0; i < mnIdClusters; i++ )
6296 rStCtrl >> mpFidcls[ i ].dgid
6297 >> mpFidcls[ i ].cspidCur;
6302 rStCtrl.Seek( nMerk );
6306 void SvxMSDffManager::CheckTxBxStoryChain()
6308 SvxMSDffShapeInfos* pOld = pShapeInfos;
6309 USHORT nCnt = pOld->Count();
6310 pShapeInfos = new SvxMSDffShapeInfos( (nCnt < 255)
6311 ? nCnt
6312 : 255 );
6313 // altes Info-Array ueberarbeiten
6314 // (ist sortiert nach nTxBxComp)
6315 ULONG nChain = ULONG_MAX;
6316 USHORT nObjMark = 0;
6317 BOOL bSetReplaceFALSE = FALSE;
6318 USHORT nObj;
6319 for( nObj = 0; nObj < nCnt; ++nObj )
6321 SvxMSDffShapeInfo* pObj = pOld->GetObject( nObj );
6322 if( pObj->nTxBxComp )
6324 pObj->bLastBoxInChain = FALSE;
6325 // Gruppenwechsel ?
6326 // --> OD 2008-07-28 #156763#
6327 // the text id also contains an internal drawing container id
6328 // to distinguish between text id of drawing objects in different
6329 // drawing containers.
6330 // if( nChain != (pObj->nTxBxComp & 0xFFFF0000) )
6331 if( nChain != pObj->nTxBxComp )
6332 // <--
6334 // voriger war letzter seiner Gruppe
6335 if( nObj )
6336 pOld->GetObject( nObj-1 )->bLastBoxInChain = TRUE;
6337 // Merker und Hilfs-Flag zuruecksetzen
6338 nObjMark = nObj;
6339 // --> OD 2008-07-28 #156763#
6340 // nChain = pObj->nTxBxComp & 0xFFFF0000;
6341 nChain = pObj->nTxBxComp;
6342 // <--
6343 bSetReplaceFALSE = !pObj->bReplaceByFly;
6345 else
6346 if( !pObj->bReplaceByFly )
6348 // Objekt, das NICHT durch Rahmen ersetzt werden darf ?
6349 // Hilfs-Flag setzen
6350 bSetReplaceFALSE = TRUE;
6351 // ggfs Flag in Anfang der Gruppe austragen
6352 for( USHORT nObj2 = nObjMark; nObj2 < nObj; ++nObj2 )
6353 pOld->GetObject( nObj2 )->bReplaceByFly = FALSE;
6356 if( bSetReplaceFALSE )
6358 pObj->bReplaceByFly = FALSE;
6361 // alle Shape-Info-Objekte in pShapeInfos umkopieren
6362 // (aber nach nShapeId sortieren)
6363 pObj->bSortByShapeId = TRUE;
6364 // --> OD 2008-07-28 #156763#
6365 pObj->nTxBxComp = pObj->nTxBxComp & 0xFFFF0000;
6366 // <--
6367 pShapeInfos->Insert( pObj );
6369 // voriger war letzter seiner Gruppe
6370 if( nObj )
6371 pOld->GetObject( nObj-1 )->bLastBoxInChain = TRUE;
6372 // urspruengliches Array freigeben, ohne Objekte zu zerstoeren
6373 pOld->Remove((USHORT)0, nCnt);
6374 delete pOld;
6378 /*****************************************************************************
6380 Einlesen der Shape-Infos im Ctor:
6381 ---------------------------------
6382 merken der Shape-Ids und zugehoerigen Blip-Nummern und TextBox-Infos
6383 ========= ============ =============
6384 und merken des File-Offsets fuer jedes Blip
6385 ============
6386 ******************************************************************************/
6387 void SvxMSDffManager::GetCtrlData( long nOffsDgg_ )
6389 // Start Offset unbedingt merken, falls wir nochmal aufsetzen muessen
6390 long nOffsDggL = nOffsDgg_;
6392 // Kontroll Stream positionieren
6393 rStCtrl.Seek( nOffsDggL );
6395 BYTE nVer;
6396 USHORT nInst;
6397 USHORT nFbt;
6398 UINT32 nLength;
6399 if( !this->ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) ) return;
6401 BOOL bOk;
6402 ULONG nPos = nOffsDggL + DFF_COMMON_RECORD_HEADER_SIZE;
6404 // Fall A: erst Drawing Group Container, dann n Mal Drawing Container
6405 if( DFF_msofbtDggContainer == nFbt )
6407 GetDrawingGroupContainerData( rStCtrl, nLength );
6409 rStCtrl.Seek( STREAM_SEEK_TO_END );
6410 UINT32 nMaxStrPos = rStCtrl.Tell();
6412 nPos += nLength;
6413 // --> OD 2008-07-28 #156763#
6414 unsigned long nDrawingContainerId = 1;
6415 // <--
6418 rStCtrl.Seek( nPos );
6420 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength ) && ( DFF_msofbtDgContainer == nFbt );
6422 if( !bOk )
6424 nPos++;
6425 rStCtrl.Seek( nPos );
6426 bOk = ReadCommonRecordHeader( rStCtrl, nVer, nInst, nFbt, nLength )
6427 && ( DFF_msofbtDgContainer == nFbt );
6429 if( bOk )
6431 // --> OD 2008-07-28 #156763#
6432 GetDrawingContainerData( rStCtrl, nLength, nDrawingContainerId );
6433 // <--
6435 nPos += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6436 // --> OD 2008-07-28 #156763#
6437 ++nDrawingContainerId;
6438 // <--
6440 while( nPos < nMaxStrPos && bOk );
6445 // ab hier: Drawing Group Container d.h. Dokument - weit gueltige Daten
6446 // ======================= ========
6448 void SvxMSDffManager::GetDrawingGroupContainerData( SvStream& rSt, ULONG nLenDgg )
6450 BYTE nVer;
6451 USHORT nInst;
6452 USHORT nFbt;
6453 UINT32 nLength;
6455 ULONG nLenBStoreCont = 0, nLenFBSE = 0, nRead = 0;
6457 // Nach einem BStore Container suchen
6460 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6461 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6462 if( DFF_msofbtBstoreContainer == nFbt )
6464 nLenBStoreCont = nLength; break;
6466 rSt.SeekRel( nLength );
6468 while( nRead < nLenDgg );
6470 if( !nLenBStoreCont ) return;
6472 // Im BStore Container alle Header der Container und Atome auslesen und die
6473 // relevanten Daten aller enthaltenen FBSEs in unserem Pointer Array ablegen.
6474 // Dabei zaehlen wir die gefundenen FBSEs im Member nBLIPCount mit.
6476 const ULONG nSkipBLIPLen = 20; // bis zu nBLIPLen zu ueberspringende Bytes
6477 const ULONG nSkipBLIPPos = 4; // dahinter bis zu nBLIPPos zu skippen
6479 sal_uInt32 nBLIPLen = 0, nBLIPPos = 0;
6481 nRead = 0;
6484 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6485 nRead += DFF_COMMON_RECORD_HEADER_SIZE + nLength;
6486 if( DFF_msofbtBSE == nFbt )
6488 nLenFBSE = nLength;
6489 // ist FBSE gross genug fuer unsere Daten
6490 BOOL bOk = ( nSkipBLIPLen + 4 + nSkipBLIPPos + 4 <= nLenFBSE );
6492 if( bOk )
6494 rSt.SeekRel( nSkipBLIPLen );
6495 rSt >> nBLIPLen;
6496 rSt.SeekRel( nSkipBLIPPos );
6497 rSt >> nBLIPPos;
6498 bOk = rSt.GetError() == 0;
6500 nLength -= nSkipBLIPLen+ 4 + nSkipBLIPPos + 4;
6503 if( bOk )
6505 // Besonderheit:
6506 // Falls nBLIPLen kleiner ist als nLenFBSE UND nBLIPPos Null ist,
6507 // nehmen wir an, dass das Bild IM FBSE drin steht!
6508 if( (!nBLIPPos) && (nBLIPLen < nLenFBSE) )
6509 nBLIPPos = rSt.Tell() + 4;
6511 // Das hat ja fein geklappt!
6512 // Wir merken uns, dass wir einen FBSE mehr im Pointer Array haben.
6513 nBLIPPos = Calc_nBLIPPos(nBLIPPos, rSt.Tell());
6515 if( USHRT_MAX == nBLIPCount )
6516 nBLIPCount = 1;
6517 else
6518 nBLIPCount++;
6520 // Jetzt die Infos fuer spaetere Zugriffe speichern
6521 pBLIPInfos->Insert( new SvxMSDffBLIPInfo( nInst, nBLIPPos, nBLIPLen ),
6522 pBLIPInfos->Count() );
6525 rSt.SeekRel( nLength );
6527 while( nRead < nLenBStoreCont );
6531 // ab hier: Drawing Container d.h. Seiten (Blatt, Dia) - weit gueltige Daten
6532 // ================= ======
6534 void SvxMSDffManager::GetDrawingContainerData( SvStream& rSt, ULONG nLenDg,
6535 const unsigned long nDrawingContainerId )
6537 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6539 ULONG nReadDg = 0;
6541 // Wir stehen in einem Drawing Container (je einer pro Seite)
6542 // und muessen nun
6543 // alle enthaltenen Shape Group Container abklappern
6546 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return;
6547 nReadDg += DFF_COMMON_RECORD_HEADER_SIZE;
6548 // Patriarch gefunden (der oberste Shape Group Container) ?
6549 if( DFF_msofbtSpgrContainer == nFbt )
6551 if(!this->GetShapeGroupContainerData( rSt, nLength, TRUE, nDrawingContainerId )) return;
6553 else
6554 // blanker Shape Container ? (ausserhalb vom Shape Group Container)
6555 if( DFF_msofbtSpContainer == nFbt )
6557 if(!this->GetShapeContainerData( rSt, nLength, ULONG_MAX, nDrawingContainerId )) return;
6559 else
6560 rSt.SeekRel( nLength );
6561 nReadDg += nLength;
6563 while( nReadDg < nLenDg );
6566 BOOL SvxMSDffManager::GetShapeGroupContainerData( SvStream& rSt,
6567 ULONG nLenShapeGroupCont,
6568 BOOL bPatriarch,
6569 const unsigned long nDrawingContainerId )
6571 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6572 long nStartShapeGroupCont = rSt.Tell();
6573 // Wir stehen in einem Shape Group Container (ggfs. mehrere pro Seite)
6574 // und muessen nun
6575 // alle enthaltenen Shape Container abklappern
6576 BOOL bFirst = !bPatriarch;
6577 ULONG nReadSpGrCont = 0;
6580 if( !this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength ) )
6581 return FALSE;
6582 nReadSpGrCont += DFF_COMMON_RECORD_HEADER_SIZE;
6583 // Shape Container ?
6584 if( DFF_msofbtSpContainer == nFbt )
6586 ULONG nGroupOffs = bFirst ? nStartShapeGroupCont - DFF_COMMON_RECORD_HEADER_SIZE : ULONG_MAX;
6587 if ( !this->GetShapeContainerData( rSt, nLength, nGroupOffs, nDrawingContainerId ) )
6588 return FALSE;
6589 bFirst = FALSE;
6591 else
6592 // eingeschachtelter Shape Group Container ?
6593 if( DFF_msofbtSpgrContainer == nFbt )
6595 if ( !this->GetShapeGroupContainerData( rSt, nLength, FALSE, nDrawingContainerId ) )
6596 return FALSE;
6598 else
6599 rSt.SeekRel( nLength );
6600 nReadSpGrCont += nLength;
6602 while( nReadSpGrCont < nLenShapeGroupCont );
6603 // den Stream wieder korrekt positionieren
6604 rSt.Seek( nStartShapeGroupCont + nLenShapeGroupCont );
6605 return TRUE;
6608 BOOL SvxMSDffManager::GetShapeContainerData( SvStream& rSt,
6609 ULONG nLenShapeCont,
6610 ULONG nPosGroup,
6611 const unsigned long nDrawingContainerId )
6613 BYTE nVer;USHORT nInst;USHORT nFbt;UINT32 nLength;
6614 long nStartShapeCont = rSt.Tell();
6615 // Wir stehen in einem Shape Container (ggfs. mehrere pro Sh. Group)
6616 // und muessen nun
6617 // die Shape Id und File-Pos (fuer spaetere, erneute Zugriffe)
6618 // und den ersten BStore Verweis (falls vorhanden) entnehmen
6619 ULONG nLenShapePropTbl = 0;
6620 ULONG nReadSpCont = 0;
6622 // File Offset des Shape-Containers bzw. der Gruppe(!) vermerken
6624 ULONG nStartOffs = (ULONG_MAX > nPosGroup) ?
6625 nPosGroup : nStartShapeCont - DFF_COMMON_RECORD_HEADER_SIZE;
6626 SvxMSDffShapeInfo aInfo( nStartOffs );
6628 // duerfte das Shape durch einen Rahmen ersetzt werden ?
6629 // (vorausgesetzt, es zeigt sich, dass es eine TextBox ist,
6630 // und der Text nicht gedreht ist)
6631 BOOL bCanBeReplaced = (ULONG_MAX > nPosGroup) ? FALSE : TRUE;
6633 // wir wissen noch nicht, ob es eine TextBox ist
6634 MSO_SPT eShapeType = mso_sptNil;
6635 MSO_WrapMode eWrapMode = mso_wrapSquare;
6636 // BOOL bIsTextBox = FALSE;
6638 // Shape analysieren
6642 if(!this->ReadCommonRecordHeader( rSt, nVer, nInst, nFbt, nLength)) return FALSE;
6643 nReadSpCont += DFF_COMMON_RECORD_HEADER_SIZE;
6644 // FSP ?
6645 if( ( DFF_msofbtSp == nFbt ) && ( 4 <= nLength ) )
6647 // Wir haben den FSP gefunden: Shape Typ und Id vermerken!
6648 eShapeType = (MSO_SPT)nInst;
6649 rSt >> aInfo.nShapeId;
6650 rSt.SeekRel( nLength - 4 );
6651 nReadSpCont += nLength;
6653 else if( DFF_msofbtOPT == nFbt ) // Shape Property Table ?
6655 // Wir haben die Property Table gefunden:
6656 // nach der Blip Property suchen!
6657 ULONG nPropRead = 0;
6658 USHORT nPropId;
6659 sal_uInt32 nPropVal;
6660 nLenShapePropTbl = nLength;
6661 // UINT32 nPropCount = nInst;
6662 long nStartShapePropTbl = rSt.Tell();
6663 // UINT32 nComplexDataFilePos = nStartShapePropTbl + (nPropCount * 6);
6666 rSt >> nPropId
6667 >> nPropVal;
6668 nPropRead += 6;
6670 switch( nPropId )
6672 case DFF_Prop_txflTextFlow :
6673 //Writer can now handle vertical textflows in its
6674 //native frames, to only need to do this for the
6675 //other two formats
6677 //Writer will handle all textflow except BtoT
6678 if (GetSvxMSDffSettings() &
6679 (SVXMSDFF_SETTINGS_IMPORT_PPT |
6680 SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6682 if( 0 != nPropVal )
6683 bCanBeReplaced = false;
6685 else if (
6686 (nPropVal != mso_txflHorzN) &&
6687 (nPropVal != mso_txflTtoBA)
6690 bCanBeReplaced = false;
6692 break;
6693 case DFF_Prop_cdirFont :
6694 //Writer can now handle right to left and left
6695 //to right in its native frames, so only do
6696 //this for the other two formats.
6697 if (GetSvxMSDffSettings() &
6698 (SVXMSDFF_SETTINGS_IMPORT_PPT |
6699 SVXMSDFF_SETTINGS_IMPORT_EXCEL))
6701 if( 0 != nPropVal )
6702 bCanBeReplaced = FALSE;
6704 break;
6705 case DFF_Prop_Rotation :
6706 if( 0 != nPropVal )
6707 bCanBeReplaced = FALSE;
6708 break;
6710 case DFF_Prop_gtextFStrikethrough :
6711 if( ( 0x20002000 & nPropVal ) == 0x20002000 )
6712 bCanBeReplaced = FALSE;
6713 break;
6715 case DFF_Prop_fc3DLightFace :
6716 if( ( 0x00080008 & nPropVal ) == 0x00080008 )
6717 bCanBeReplaced = FALSE;
6718 break;
6720 case DFF_Prop_WrapText :
6721 eWrapMode = (MSO_WrapMode)nPropVal;
6722 break;
6724 default:
6726 // Bit gesetzt und gueltig?
6727 if( 0x4000 == ( nPropId & 0xC000 ) )
6729 // Blip Property gefunden: BStore Idx vermerken!
6730 nPropRead = nLenShapePropTbl;
6732 else if( 0x8000 & nPropId )
6734 // komplexe Prop gefunden:
6735 // Laenge ist immer 6, nur die Laenge der nach der
6736 // eigentlichen Prop-Table anhaengenden Extra-Daten
6737 // ist unterschiedlich
6738 nPropVal = 6;
6741 break;
6745 //JP 21.04.99: Bug 64510
6746 // alte Version, die unter OS/2 zu Compilerfehlern fuehrt und damit arge
6747 // Performance einbussen hat.
6749 if( 0x4000 == ( nPropId & 0xC000 ) )// Bit gesetzt und gueltig?
6751 // Blip Property gefunden: BStore Idx vermerken!
6752 aInfo.nBStoreIdx = nPropVal; // Index im BStore Container
6753 break;
6755 else
6756 if( ( ( (DFF_Prop_txflTextFlow == nPropId)
6757 || (DFF_Prop_Rotation == nPropId)
6758 || (DFF_Prop_cdirFont == nPropId) )
6759 && (0 != nPropVal) )
6761 || ( (DFF_Prop_gtextFStrikethrough == nPropId)
6762 && ( (0x20002000 & nPropVal) == 0x20002000) ) // also DFF_Prop_gtextFVertical
6763 || ( (DFF_Prop_fc3DLightFace == nPropId)
6764 && ( (0x00080008 & nPropVal) == 0x00080008) ) // also DFF_Prop_f3D
6767 bCanBeReplaced = FALSE; // Mist: gedrehter Text oder 3D-Objekt!
6769 else
6770 if( DFF_Prop_WrapText == nPropId )
6772 eWrapMode = (MSO_WrapMode)nPropVal;
6774 ////////////////////////////////////////////////////////////////
6775 ////////////////////////////////////////////////////////////////
6776 // keine weitere Property-Auswertung: folge beim Shape-Import //
6777 ////////////////////////////////////////////////////////////////
6778 ////////////////////////////////////////////////////////////////
6779 else
6780 if( 0x8000 & nPropId )
6782 // komplexe Prop gefunden: Laenge lesen und ueberspringen
6783 if(!SkipBytes( rSt, nPropVal )) return FALSE;
6784 nPropRead += nPropVal;
6788 while( nPropRead < nLenShapePropTbl );
6789 rSt.Seek( nStartShapePropTbl + nLenShapePropTbl );
6790 nReadSpCont += nLenShapePropTbl;
6792 else if( ( DFF_msofbtClientTextbox == nFbt ) && ( 4 == nLength ) ) // Text-Box-Story-Eintrag gefunden
6794 rSt >> aInfo.nTxBxComp;
6795 // --> OD 2008-07-28 #156763#
6796 // Add internal drawing container id to text id.
6797 // Note: The text id uses the first two bytes, while the internal
6798 // drawing container id used the second two bytes.
6799 aInfo.nTxBxComp = ( aInfo.nTxBxComp & 0xFFFF0000 ) +
6800 nDrawingContainerId;
6801 DBG_ASSERT( (aInfo.nTxBxComp & 0x0000FFFF) == nDrawingContainerId,
6802 "<SvxMSDffManager::GetShapeContainerData(..)> - internal drawing container Id could not be correctly merged into DFF_msofbtClientTextbox value." );
6803 // <--
6805 else
6807 rSt.SeekRel( nLength );
6808 nReadSpCont += nLength;
6811 while( nReadSpCont < nLenShapeCont );
6814 // Jetzt ggfs. die Infos fuer spaetere Zugriffe auf das Shape speichern
6816 if( aInfo.nShapeId )
6818 // fuer Textboxen ggfs. ersetzen durch Rahmen erlauben
6819 if( bCanBeReplaced
6820 && aInfo.nTxBxComp
6821 && (
6822 ( eShapeType == mso_sptTextSimple )
6823 || ( eShapeType == mso_sptTextBox )
6824 || ( ( ( eShapeType == mso_sptRectangle )
6825 || ( eShapeType == mso_sptRoundRectangle )
6827 ) ) )
6829 aInfo.bReplaceByFly = TRUE;
6831 pShapeInfos->Insert( new SvxMSDffShapeInfo( aInfo ) );
6832 pShapeOrders->Insert( new SvxMSDffShapeOrder( aInfo.nShapeId ),
6833 pShapeOrders->Count() );
6836 // und den Stream wieder korrekt positionieren
6837 rSt.Seek( nStartShapeCont + nLenShapeCont );
6838 return TRUE;
6843 /*****************************************************************************
6845 Zugriff auf ein Shape zur Laufzeit (ueber die Shape-Id)
6846 ----------------------------------
6847 ******************************************************************************/
6848 BOOL SvxMSDffManager::GetShape(ULONG nId, SdrObject*& rpShape,
6849 SvxMSDffImportData& rData)
6851 SvxMSDffShapeInfo aTmpRec(0, nId);
6852 aTmpRec.bSortByShapeId = TRUE;
6854 USHORT nFound;
6855 if( pShapeInfos->Seek_Entry(&aTmpRec, &nFound) )
6857 SvxMSDffShapeInfo& rInfo = *pShapeInfos->GetObject( nFound );
6859 // eventuell altes Errorflag loeschen
6860 if( rStCtrl.GetError() )
6861 rStCtrl.ResetError();
6862 // FilePos des/der Stream(s) merken
6863 ULONG nOldPosCtrl = rStCtrl.Tell();
6864 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6865 // das Shape im Steuer Stream anspringen
6866 rStCtrl.Seek( rInfo.nFilePos );
6868 // Falls missglueckt, den Fehlerstatus zuruecksetzen und Pech gehabt!
6869 if( rStCtrl.GetError() )
6870 rStCtrl.ResetError();
6871 else
6872 rpShape = ImportObj( rStCtrl, &rData, rData.aParentRect, rData.aParentRect );
6874 // alte FilePos des/der Stream(s) restaurieren
6875 rStCtrl.Seek( nOldPosCtrl );
6876 if( &rStCtrl != pStData )
6877 pStData->Seek( nOldPosData );
6878 return ( 0 != rpShape );
6880 return FALSE;
6885 /* Zugriff auf ein BLIP zur Laufzeit (bei bereits bekannter Blip-Nr)
6886 ---------------------------------
6887 ******************************************************************************/
6888 BOOL SvxMSDffManager::GetBLIP( ULONG nIdx_, Graphic& rData, Rectangle* pVisArea ) const
6890 BOOL bOk = FALSE; // Ergebnisvariable initialisieren
6891 if ( pStData )
6893 // check if a graphic for this blipId is already imported
6894 if ( nIdx_ && pEscherBlipCache )
6896 EscherBlipCacheEntry* pEntry;
6897 for ( pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->First(); pEntry;
6898 pEntry = (EscherBlipCacheEntry*)pEscherBlipCache->Next() )
6900 if ( pEntry->nBlip == nIdx_ )
6901 { /* if this entry is available, then it should be possible
6902 to get the Graphic via GraphicObject */
6903 GraphicObject aGraphicObject( pEntry->aUniqueID );
6904 rData = aGraphicObject.GetGraphic();
6905 if ( rData.GetType() != GRAPHIC_NONE )
6906 bOk = sal_True;
6907 else
6908 delete (EscherBlipCacheEntry*)pEscherBlipCache->Remove();
6909 break;
6913 if ( !bOk )
6915 USHORT nIdx = USHORT( nIdx_ );
6916 if( !nIdx || (pBLIPInfos->Count() < nIdx) ) return FALSE;
6918 // eventuell alte(s) Errorflag(s) loeschen
6919 if( rStCtrl.GetError() )
6920 rStCtrl.ResetError();
6921 if( ( &rStCtrl != pStData )
6922 && pStData->GetError() )
6923 pStData->ResetError();
6925 // FilePos des/der Stream(s) merken
6926 ULONG nOldPosCtrl = rStCtrl.Tell();
6927 ULONG nOldPosData = pStData ? pStData->Tell() : nOldPosCtrl;
6929 // passende Info-Struct aus unserem Pointer Array nehmen
6930 SvxMSDffBLIPInfo& rInfo = *(*pBLIPInfos)[ nIdx-1 ];
6932 // das BLIP Atom im Daten Stream anspringen
6933 pStData->Seek( rInfo.nFilePos );
6934 // ggfs. Fehlerstatus zuruecksetzen
6935 if( pStData->GetError() )
6936 pStData->ResetError();
6937 else
6938 bOk = GetBLIPDirect( *pStData, rData, pVisArea );
6939 if( pStData2 && !bOk )
6941 // Fehler, aber zweite Chance: es gibt noch einen zweiten
6942 // Datenstream, in dem die Grafik liegen koennte!
6943 if( pStData2->GetError() )
6944 pStData2->ResetError();
6945 ULONG nOldPosData2 = pStData2->Tell();
6946 // das BLIP Atom im zweiten Daten Stream anspringen
6947 pStData2->Seek( rInfo.nFilePos );
6948 // ggfs. Fehlerstatus zuruecksetzen
6949 if( pStData2->GetError() )
6950 pStData2->ResetError();
6951 else
6952 bOk = GetBLIPDirect( *pStData2, rData, pVisArea );
6953 // alte FilePos des zweiten Daten-Stream restaurieren
6954 pStData2->Seek( nOldPosData2 );
6956 // alte FilePos des/der Stream(s) restaurieren
6957 rStCtrl.Seek( nOldPosCtrl );
6958 if( &rStCtrl != pStData )
6959 pStData->Seek( nOldPosData );
6961 if ( bOk )
6963 // create new BlipCacheEntry for this graphic
6964 GraphicObject aGraphicObject( rData );
6965 if ( !pEscherBlipCache )
6966 const_cast <SvxMSDffManager*> (this)->pEscherBlipCache = new List();
6967 EscherBlipCacheEntry* pNewEntry = new EscherBlipCacheEntry( nIdx_, aGraphicObject.GetUniqueID() );
6968 pEscherBlipCache->Insert( pNewEntry, LIST_APPEND );
6972 return bOk;
6975 /* Zugriff auf ein BLIP zur Laufzeit (mit korrekt positioniertem Stream)
6976 ---------------------------------
6977 ******************************************************************************/
6978 BOOL SvxMSDffManager::GetBLIPDirect( SvStream& rBLIPStream, Graphic& rData, Rectangle* pVisArea ) const
6980 ULONG nOldPos = rBLIPStream.Tell();
6982 int nRes = GRFILTER_OPENERROR; // Fehlervariable initialisieren
6984 // nachschauen, ob es sich auch wirklich um ein BLIP handelt
6985 UINT32 nLength;
6986 USHORT nInst, nFbt( 0 );
6987 BYTE nVer;
6988 if( ReadCommonRecordHeader( rBLIPStream, nVer, nInst, nFbt, nLength) && ( 0xF018 <= nFbt ) && ( 0xF117 >= nFbt ) )
6990 Size aMtfSize100;
6991 BOOL bMtfBLIP = FALSE;
6992 BOOL bZCodecCompression = FALSE;
6993 // Nun exakt auf den Beginn der eingebetteten Grafik positionieren
6994 ULONG nSkip = ( nInst & 0x0001 ) ? 32 : 16;
6996 switch( nInst & 0xFFFE )
6998 case 0x216 : // Metafile header then compressed WMF
6999 case 0x3D4 : // Metafile header then compressed EMF
7000 case 0x542 : // Metafile hd. then compressed PICT
7002 rBLIPStream.SeekRel( nSkip + 20 );
7004 // read in size of metafile in EMUS
7005 rBLIPStream >> aMtfSize100.Width() >> aMtfSize100.Height();
7007 // scale to 1/100mm
7008 aMtfSize100.Width() /= 360, aMtfSize100.Height() /= 360;
7010 if ( pVisArea ) // seem that we currently are skipping the visarea position
7011 *pVisArea = Rectangle( Point(), aMtfSize100 );
7013 // skip rest of header
7014 nSkip = 6;
7015 bMtfBLIP = bZCodecCompression = TRUE;
7017 break;
7018 case 0x46A : // One byte tag then JPEG (= JFIF) data
7019 case 0x6E0 : // One byte tag then PNG data
7020 case 0x7A8 :
7021 nSkip += 1; // One byte tag then DIB data
7022 break;
7024 rBLIPStream.SeekRel( nSkip );
7026 SvStream* pGrStream = &rBLIPStream;
7027 SvMemoryStream* pOut = NULL;
7028 if( bZCodecCompression )
7030 pOut = new SvMemoryStream( 0x8000, 0x4000 );
7031 ZCodec aZCodec( 0x8000, 0x8000 );
7032 aZCodec.BeginCompression();
7033 aZCodec.Decompress( rBLIPStream, *pOut );
7034 aZCodec.EndCompression();
7035 pOut->Seek( STREAM_SEEK_TO_BEGIN );
7036 pGrStream = pOut;
7039 //#define DBG_EXTRACTGRAPHICS
7040 #ifdef DBG_EXTRACTGRAPHICS
7042 static sal_Int32 nCount;
7044 String aFileName( String( RTL_CONSTASCII_STRINGPARAM( "dbggfx" ) ) );
7045 aFileName.Append( String::CreateFromInt32( nCount++ ) );
7046 switch( nInst &~ 1 )
7048 case 0x216 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".wmf" ) ) ); break;
7049 case 0x3d4 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".emf" ) ) ); break;
7050 case 0x542 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".pct" ) ) ); break;
7051 case 0x46a : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".jpg" ) ) ); break;
7052 case 0x6e0 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".png" ) ) ); break;
7053 case 0x7a8 : aFileName.Append( String( RTL_CONSTASCII_STRINGPARAM( ".bmp" ) ) ); break;
7056 String aURLStr;
7058 if( ::utl::LocalFileHelper::ConvertPhysicalNameToURL( Application::GetAppFileName(), aURLStr ) )
7060 INetURLObject aURL( aURLStr );
7062 aURL.removeSegment();
7063 aURL.removeFinalSlash();
7064 aURL.Append( aFileName );
7066 SvStream* pDbgOut = ::utl::UcbStreamHelper::CreateStream( aURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_TRUNC | STREAM_WRITE );
7068 if( pDbgOut )
7070 if ( bZCodecCompression )
7072 pOut->Seek( STREAM_SEEK_TO_END );
7073 pDbgOut->Write( pOut->GetData(), pOut->Tell() );
7074 pOut->Seek( STREAM_SEEK_TO_BEGIN );
7076 else
7078 sal_Int32 nDbgLen = nLength - nSkip;
7079 if ( nDbgLen )
7081 sal_Char* pDat = new sal_Char[ nDbgLen ];
7082 pGrStream->Read( pDat, nDbgLen );
7083 pDbgOut->Write( pDat, nDbgLen );
7084 pGrStream->SeekRel( -nDbgLen );
7085 delete[] pDat;
7089 delete pDbgOut;
7092 #endif
7094 if( ( nInst & 0xFFFE ) == 0x7A8 )
7095 { // DIBs direkt holen
7096 Bitmap aNew;
7097 if( aNew.Read( *pGrStream, FALSE ) )
7099 rData = Graphic( aNew );
7100 nRes = GRFILTER_OK;
7103 else
7104 { // und unsere feinen Filter darauf loslassen
7105 GraphicFilter* pGF = GetGrfFilter();
7106 String aEmptyStr;
7107 nRes = pGF->ImportGraphic( rData, aEmptyStr, *pGrStream, GRFILTER_FORMAT_DONTKNOW );
7109 // SJ: I40472, sometimes the aspect ratio (aMtfSize100) does not match and we get scaling problems,
7110 // then it is better to use the prefsize that is stored within the metafile. Bug #72846# for what the
7111 // scaling has been implemented does not happen anymore.
7113 // For pict graphics we will furthermore scale the metafile, because font scaling leads to error if the
7114 // dxarray is empty (this has been solved in wmf/emf but not for pict)
7115 if( bMtfBLIP && ( GRFILTER_OK == nRes ) && ( rData.GetType() == GRAPHIC_GDIMETAFILE ) && ( ( nInst & 0xFFFE ) == 0x542 ) )
7117 if ( ( aMtfSize100.Width() >= 1000 ) && ( aMtfSize100.Height() >= 1000 ) )
7118 { // #75956#, scaling does not work properly, if the graphic is less than 1cm
7119 GDIMetaFile aMtf( rData.GetGDIMetaFile() );
7120 const Size aOldSize( aMtf.GetPrefSize() );
7122 if( aOldSize.Width() && ( aOldSize.Width() != aMtfSize100.Width() ) &&
7123 aOldSize.Height() && ( aOldSize.Height() != aMtfSize100.Height() ) )
7125 aMtf.Scale( (double) aMtfSize100.Width() / aOldSize.Width(),
7126 (double) aMtfSize100.Height() / aOldSize.Height() );
7127 aMtf.SetPrefSize( aMtfSize100 );
7128 aMtf.SetPrefMapMode( MAP_100TH_MM );
7129 rData = aMtf;
7134 // ggfs. Fehlerstatus zuruecksetzen
7135 if ( ERRCODE_IO_PENDING == pGrStream->GetError() )
7136 pGrStream->ResetError();
7137 delete pOut;
7139 rBLIPStream.Seek( nOldPos ); // alte FilePos des Streams restaurieren
7141 return ( GRFILTER_OK == nRes ); // Ergebniss melden
7144 /* static */
7145 BOOL SvxMSDffManager::ReadCommonRecordHeader(DffRecordHeader& rRec, SvStream& rIn)
7147 rRec.nFilePos = rIn.Tell();
7148 return SvxMSDffManager::ReadCommonRecordHeader( rIn,rRec.nRecVer,
7149 rRec.nRecInstance,
7150 rRec.nRecType,
7151 rRec.nRecLen );
7155 /* auch static */
7156 BOOL SvxMSDffManager::ReadCommonRecordHeader( SvStream& rSt,
7157 BYTE& rVer,
7158 USHORT& rInst,
7159 USHORT& rFbt,
7160 UINT32& rLength )
7162 sal_uInt16 nTmp;
7163 rSt >> nTmp >> rFbt >> rLength;
7164 rVer = sal::static_int_cast< BYTE >(nTmp & 15);
7165 rInst = nTmp >> 4;
7166 return rSt.GetError() == 0;
7172 BOOL SvxMSDffManager::ProcessClientAnchor(SvStream& rStData, ULONG nDatLen,
7173 char*& rpBuff, UINT32& rBuffLen ) const
7175 if( nDatLen )
7177 rpBuff = new char[ nDatLen ];
7178 rBuffLen = nDatLen;
7179 rStData.Read( rpBuff, nDatLen );
7181 return TRUE;
7184 BOOL SvxMSDffManager::ProcessClientData(SvStream& rStData, ULONG nDatLen,
7185 char*& rpBuff, UINT32& rBuffLen ) const
7187 if( nDatLen )
7189 rpBuff = new char[ nDatLen ];
7190 rBuffLen = nDatLen;
7191 rStData.Read( rpBuff, nDatLen );
7193 return TRUE;
7197 void SvxMSDffManager::ProcessClientAnchor2( SvStream& /* rSt */, DffRecordHeader& /* rHd */ , void* /* pData */, DffObjData& /* rObj */ )
7199 return; // wird von SJ im Draw ueberladen
7202 ULONG SvxMSDffManager::Calc_nBLIPPos( ULONG nOrgVal, ULONG /* nStreamPos */ ) const
7204 return nOrgVal;
7207 BOOL SvxMSDffManager::GetOLEStorageName( long /* nOLEId */, String&, SvStorageRef&, uno::Reference < embed::XStorage >& ) const
7209 return FALSE;
7212 BOOL SvxMSDffManager::ShapeHasText( ULONG /* nShapeId */, ULONG /* nFilePos */ ) const
7214 return TRUE;
7217 // --> OD 2004-12-14 #i32596# - add new parameter <_nCalledByGroup>
7218 SdrObject* SvxMSDffManager::ImportOLE( long nOLEId,
7219 const Graphic& rGrf,
7220 const Rectangle& rBoundRect,
7221 const Rectangle& rVisArea,
7222 const int /* _nCalledByGroup */,
7223 sal_Int64 nAspect ) const
7224 // <--
7226 SdrObject* pRet = 0;
7227 String sStorageName;
7228 SvStorageRef xSrcStg;
7229 ErrCode nError = ERRCODE_NONE;
7230 uno::Reference < embed::XStorage > xDstStg;
7231 if( GetOLEStorageName( nOLEId, sStorageName, xSrcStg, xDstStg ))
7232 pRet = CreateSdrOLEFromStorage( sStorageName, xSrcStg, xDstStg,
7233 rGrf, rBoundRect, rVisArea, pStData, nError,
7234 nSvxMSDffOLEConvFlags, nAspect );
7235 return pRet;
7238 const GDIMetaFile* SvxMSDffManager::lcl_GetMetaFileFromGrf_Impl( const Graphic& rGrf,
7239 GDIMetaFile& rMtf )
7241 const GDIMetaFile* pMtf;
7242 if( GRAPHIC_BITMAP == rGrf.GetType() )
7244 Point aPt;
7245 const Size aSz(lcl_GetPrefSize(rGrf, MAP_100TH_MM));
7247 VirtualDevice aVirtDev;
7248 aVirtDev.EnableOutput( FALSE );
7249 MapMode aMM(MAP_100TH_MM);
7250 aVirtDev.SetMapMode( aMM );
7252 rMtf.Record( &aVirtDev );
7253 rGrf.Draw( &aVirtDev, aPt, aSz );
7254 rMtf.Stop();
7255 rMtf.SetPrefMapMode(aMM);
7256 rMtf.SetPrefSize( aSz );
7258 pMtf = &rMtf;
7260 else
7261 pMtf = &rGrf.GetGDIMetaFile();
7262 return pMtf;
7265 BOOL SvxMSDffManager::MakeContentStream( SotStorage * pStor, const GDIMetaFile & rMtf )
7267 String aPersistStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( SVEXT_PERSIST_STREAM ) ) );
7268 SotStorageStreamRef xStm = pStor->OpenSotStream( aPersistStream );
7269 xStm->SetVersion( pStor->GetVersion() );
7270 xStm->SetBufferSize( 8192 );
7272 USHORT nAspect = ASPECT_CONTENT;
7273 ULONG nAdviseModes = 2;
7275 Impl_OlePres aEle( FORMAT_GDIMETAFILE );
7276 // Die Groesse in 1/100 mm umrechnen
7277 // Falls eine nicht anwendbare MapUnit (Device abhaengig) verwendet wird,
7278 // versucht SV einen BestMatchden richtigen Wert zu raten.
7279 Size aSize = rMtf.GetPrefSize();
7280 MapMode aMMSrc = rMtf.GetPrefMapMode();
7281 MapMode aMMDst( MAP_100TH_MM );
7282 aSize = OutputDevice::LogicToLogic( aSize, aMMSrc, aMMDst );
7283 aEle.SetSize( aSize );
7284 aEle.SetAspect( nAspect );
7285 aEle.SetAdviseFlags( nAdviseModes );
7286 aEle.SetMtf( rMtf );
7287 aEle.Write( *xStm );
7289 xStm->SetBufferSize( 0 );
7290 return xStm->GetError() == SVSTREAM_OK;
7293 struct ClsIDs {
7294 UINT32 nId;
7295 const sal_Char* pSvrName;
7296 const sal_Char* pDspName;
7298 static ClsIDs aClsIDs[] = {
7300 { 0x000212F0, "MSWordArt", "Microsoft Word Art" },
7301 { 0x000212F0, "MSWordArt.2", "Microsoft Word Art 2.0" },
7303 // MS Apps
7304 { 0x00030000, "ExcelWorksheet", "Microsoft Excel Worksheet" },
7305 { 0x00030001, "ExcelChart", "Microsoft Excel Chart" },
7306 { 0x00030002, "ExcelMacrosheet", "Microsoft Excel Macro" },
7307 { 0x00030003, "WordDocument", "Microsoft Word Document" },
7308 { 0x00030004, "MSPowerPoint", "Microsoft PowerPoint" },
7309 { 0x00030005, "MSPowerPointSho", "Microsoft PowerPoint Slide Show"},
7310 { 0x00030006, "MSGraph", "Microsoft Graph" },
7311 { 0x00030007, "MSDraw", "Microsoft Draw" },
7312 { 0x00030008, "Note-It", "Microsoft Note-It" },
7313 { 0x00030009, "WordArt", "Microsoft Word Art" },
7314 { 0x0003000a, "PBrush", "Microsoft PaintBrush Picture" },
7315 { 0x0003000b, "Equation", "Microsoft Equation Editor" },
7316 { 0x0003000c, "Package", "Package" },
7317 { 0x0003000d, "SoundRec", "Sound" },
7318 { 0x0003000e, "MPlayer", "Media Player" },
7319 // MS Demos
7320 { 0x0003000f, "ServerDemo", "OLE 1.0 Server Demo" },
7321 { 0x00030010, "Srtest", "OLE 1.0 Test Demo" },
7322 { 0x00030011, "SrtInv", "OLE 1.0 Inv Demo" },
7323 { 0x00030012, "OleDemo", "OLE 1.0 Demo" },
7325 // Coromandel / Dorai Swamy / 718-793-7963
7326 { 0x00030013, "CoromandelIntegra", "Coromandel Integra" },
7327 { 0x00030014, "CoromandelObjServer","Coromandel Object Server" },
7329 // 3-d Visions Corp / Peter Hirsch / 310-325-1339
7330 { 0x00030015, "StanfordGraphics", "Stanford Graphics" },
7332 // Deltapoint / Nigel Hearne / 408-648-4000
7333 { 0x00030016, "DGraphCHART", "DeltaPoint Graph Chart" },
7334 { 0x00030017, "DGraphDATA", "DeltaPoint Graph Data" },
7336 // Corel / Richard V. Woodend / 613-728-8200 x1153
7337 { 0x00030018, "PhotoPaint", "Corel PhotoPaint" },
7338 { 0x00030019, "CShow", "Corel Show" },
7339 { 0x0003001a, "CorelChart", "Corel Chart" },
7340 { 0x0003001b, "CDraw", "Corel Draw" },
7342 // Inset Systems / Mark Skiba / 203-740-2400
7343 { 0x0003001c, "HJWIN1.0", "Inset Systems" },
7345 // Mark V Systems / Mark McGraw / 818-995-7671
7346 { 0x0003001d, "ObjMakerOLE", "MarkV Systems Object Maker" },
7348 // IdentiTech / Mike Gilger / 407-951-9503
7349 { 0x0003001e, "FYI", "IdentiTech FYI" },
7350 { 0x0003001f, "FYIView", "IdentiTech FYI Viewer" },
7352 // Inventa Corporation / Balaji Varadarajan / 408-987-0220
7353 { 0x00030020, "Stickynote", "Inventa Sticky Note" },
7355 // ShapeWare Corp. / Lori Pearce / 206-467-6723
7356 { 0x00030021, "ShapewareVISIO10", "Shapeware Visio 1.0" },
7357 { 0x00030022, "ImportServer", "Spaheware Import Server" },
7359 // test app SrTest
7360 { 0x00030023, "SrvrTest", "OLE 1.0 Server Test" },
7362 // test app ClTest. Doesn't really work as a server but is in reg db
7363 { 0x00030025, "Cltest", "OLE 1.0 Client Test" },
7365 // Microsoft ClipArt Gallery Sherry Larsen-Holmes
7366 { 0x00030026, "MS_ClipArt_Gallery", "Microsoft ClipArt Gallery" },
7367 // Microsoft Project Cory Reina
7368 { 0x00030027, "MSProject", "Microsoft Project" },
7370 // Microsoft Works Chart
7371 { 0x00030028, "MSWorksChart", "Microsoft Works Chart" },
7373 // Microsoft Works Spreadsheet
7374 { 0x00030029, "MSWorksSpreadsheet", "Microsoft Works Spreadsheet" },
7376 // AFX apps - Dean McCrory
7377 { 0x0003002A, "MinSvr", "AFX Mini Server" },
7378 { 0x0003002B, "HierarchyList", "AFX Hierarchy List" },
7379 { 0x0003002C, "BibRef", "AFX BibRef" },
7380 { 0x0003002D, "MinSvrMI", "AFX Mini Server MI" },
7381 { 0x0003002E, "TestServ", "AFX Test Server" },
7383 // Ami Pro
7384 { 0x0003002F, "AmiProDocument", "Ami Pro Document" },
7386 // WordPerfect Presentations For Windows
7387 { 0x00030030, "WPGraphics", "WordPerfect Presentation" },
7388 { 0x00030031, "WPCharts", "WordPerfect Chart" },
7390 // MicroGrafx Charisma
7391 { 0x00030032, "Charisma", "MicroGrafx Charisma" },
7392 { 0x00030033, "Charisma_30", "MicroGrafx Charisma 3.0" },
7393 { 0x00030034, "CharPres_30", "MicroGrafx Charisma 3.0 Pres" },
7394 // MicroGrafx Draw
7395 { 0x00030035, "Draw", "MicroGrafx Draw" },
7396 // MicroGrafx Designer
7397 { 0x00030036, "Designer_40", "MicroGrafx Designer 4.0" },
7399 // STAR DIVISION
7400 // { 0x000424CA, "StarMath", "StarMath 1.0" },
7401 { 0x00043AD2, "FontWork", "Star FontWork" },
7402 // { 0x000456EE, "StarMath2", "StarMath 2.0" },
7404 { 0, "", "" } };
7407 BOOL SvxMSDffManager::ConvertToOle2( SvStream& rStm, UINT32 nReadLen,
7408 const GDIMetaFile * pMtf, const SotStorageRef& rDest )
7410 BOOL bMtfRead = FALSE;
7411 SotStorageStreamRef xOle10Stm = rDest->OpenSotStream( String::CreateFromAscii( RTL_CONSTASCII_STRINGPARAM( "\1Ole10Native" ) ),
7412 STREAM_WRITE| STREAM_SHARE_DENYALL );
7413 if( xOle10Stm->GetError() )
7414 return FALSE;
7416 UINT32 nType;
7417 UINT32 nRecType;
7418 UINT32 nStrLen;
7419 String aSvrName;
7420 UINT32 nDummy0;
7421 UINT32 nDummy1;
7422 UINT32 nDataLen;
7423 BYTE * pData;
7424 UINT32 nBytesRead = 0;
7427 rStm >> nType;
7428 rStm >> nRecType;
7429 rStm >> nStrLen;
7430 if( nStrLen )
7432 if( 0x10000L > nStrLen )
7434 sal_Char * pBuf = new sal_Char[ nStrLen ];
7435 rStm.Read( pBuf, nStrLen );
7436 aSvrName.Assign( String( pBuf, (USHORT) nStrLen-1, gsl_getSystemTextEncoding() ) );
7437 delete[] pBuf;
7439 else
7440 break;
7442 rStm >> nDummy0;
7443 rStm >> nDummy1;
7444 rStm >> nDataLen;
7446 nBytesRead += 6 * sizeof( UINT32 ) + nStrLen + nDataLen;
7448 if( !rStm.IsEof() && nReadLen > nBytesRead && nDataLen )
7450 if( xOle10Stm.Is() )
7452 pData = new BYTE[ nDataLen ];
7453 if( !pData )
7454 return FALSE;
7456 rStm.Read( pData, nDataLen );
7458 // write to ole10 stream
7459 *xOle10Stm << nDataLen;
7460 xOle10Stm->Write( pData, nDataLen );
7461 xOle10Stm = SotStorageStreamRef();
7463 // set the compobj stream
7464 ClsIDs* pIds;
7465 for( pIds = aClsIDs; pIds->nId; pIds++ )
7467 if( COMPARE_EQUAL == aSvrName.CompareToAscii( pIds->pSvrName ) )
7468 break;
7470 // SvGlobalName* pClsId = NULL;
7471 String aShort, aFull;
7472 if( pIds->nId )
7474 // gefunden!
7475 ULONG nCbFmt = SotExchange::RegisterFormatName( aSvrName );
7476 rDest->SetClass( SvGlobalName( pIds->nId, 0, 0, 0xc0,0,0,0,0,0,0,0x46 ), nCbFmt,
7477 String( pIds->pDspName, RTL_TEXTENCODING_ASCII_US ) );
7479 else
7481 ULONG nCbFmt = SotExchange::RegisterFormatName( aSvrName );
7482 rDest->SetClass( SvGlobalName(), nCbFmt, aSvrName );
7485 delete[] pData;
7487 else if( nRecType == 5 && !pMtf )
7489 ULONG nPos = rStm.Tell();
7490 UINT16 sz[4];
7491 rStm.Read( sz, 8 );
7492 //rStm.SeekRel( 8 );
7493 Graphic aGraphic;
7494 if( ERRCODE_NONE == GraphicConverter::Import( rStm, aGraphic ) && aGraphic.GetType() )
7496 const GDIMetaFile& rMtf = aGraphic.GetGDIMetaFile();
7497 MakeContentStream( rDest, rMtf );
7498 bMtfRead = TRUE;
7500 // set behind the data
7501 rStm.Seek( nPos + nDataLen );
7503 else
7504 rStm.SeekRel( nDataLen );
7506 } while( !rStm.IsEof() && nReadLen >= nBytesRead );
7508 if( !bMtfRead && pMtf )
7510 MakeContentStream( rDest, *pMtf );
7511 return TRUE;
7514 return FALSE;
7517 const char* GetInternalServerName_Impl( const SvGlobalName& aGlobName )
7519 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 )
7520 || aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
7521 return "swriter";
7522 else if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 )
7523 || aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
7524 return "scalc";
7525 else if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 )
7526 || aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
7527 return "simpress";
7528 else if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 )
7529 || aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
7530 return "sdraw";
7531 else if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 )
7532 || aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
7533 return "smath";
7534 else if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 )
7535 || aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
7536 return "schart";
7537 return 0;
7540 ::rtl::OUString GetFilterNameFromClassID_Impl( const SvGlobalName& aGlobName )
7542 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_60 ) )
7543 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Writer)" ) );
7545 if ( aGlobName == SvGlobalName( SO3_SW_OLE_EMBED_CLASSID_8 ) )
7546 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "writer8" ) );
7548 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_60 ) )
7549 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Calc)" ) );
7551 if ( aGlobName == SvGlobalName( SO3_SC_OLE_EMBED_CLASSID_8 ) )
7552 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "calc8" ) );
7554 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_60 ) )
7555 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Impress)" ) );
7557 if ( aGlobName == SvGlobalName( SO3_SIMPRESS_OLE_EMBED_CLASSID_8 ) )
7558 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "impress8" ) );
7560 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_60 ) )
7561 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Draw)" ) );
7563 if ( aGlobName == SvGlobalName( SO3_SDRAW_OLE_EMBED_CLASSID_8 ) )
7564 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "draw8" ) );
7566 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_60 ) )
7567 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Math)" ) );
7569 if ( aGlobName == SvGlobalName( SO3_SM_OLE_EMBED_CLASSID_8 ) )
7570 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "math8" ) );
7572 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_60 ) )
7573 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "StarOffice XML (Chart)" ) );
7575 if ( aGlobName == SvGlobalName( SO3_SCH_OLE_EMBED_CLASSID_8 ) )
7576 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "chart8" ) );
7578 return ::rtl::OUString();
7581 com::sun::star::uno::Reference < com::sun::star::embed::XEmbeddedObject > SvxMSDffManager::CheckForConvertToSOObj( UINT32 nConvertFlags,
7582 SotStorage& rSrcStg, const uno::Reference < embed::XStorage >& rDestStorage,
7583 const Graphic& rGrf,
7584 const Rectangle& rVisArea )
7586 uno::Reference < embed::XEmbeddedObject > xObj;
7587 SvGlobalName aStgNm = rSrcStg.GetClassName();
7588 const char* pName = GetInternalServerName_Impl( aStgNm );
7589 String sStarName;
7590 if ( pName )
7591 sStarName = String::CreateFromAscii( pName );
7592 else if ( nConvertFlags )
7594 static struct _ObjImpType
7596 UINT32 nFlag;
7597 const char* pFactoryNm;
7598 // GlobalNameId
7599 UINT32 n1;
7600 USHORT n2, n3;
7601 BYTE b8, b9, b10, b11, b12, b13, b14, b15;
7602 } aArr[] = {
7603 { OLE_MATHTYPE_2_STARMATH, "smath",
7604 0x0002ce02L, 0x0000, 0x0000,
7605 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7606 { OLE_MATHTYPE_2_STARMATH, "smath",
7607 0x00021700L, 0x0000, 0x0000,
7608 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7609 { OLE_WINWORD_2_STARWRITER, "swriter",
7610 0x00020906L, 0x0000, 0x0000,
7611 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7612 { OLE_EXCEL_2_STARCALC, "scalc", // Excel table
7613 0x00020810L, 0x0000, 0x0000,
7614 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7615 { OLE_EXCEL_2_STARCALC, "scalc", // Excel chart
7616 0x00020820L, 0x0000, 0x0000,
7617 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7618 // 114465: additional Excel OLE chart classId to above.
7619 { OLE_EXCEL_2_STARCALC, "scalc",
7620 0x00020821L, 0x0000, 0x0000,
7621 0xc0,0x00,0x00,0x00,0x00,0x00,0x00,0x46 },
7622 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint presentation
7623 0x64818d10L, 0x4f9b, 0x11cf,
7624 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7625 { OLE_POWERPOINT_2_STARIMPRESS, "simpress", // PowerPoint slide
7626 0x64818d11L, 0x4f9b, 0x11cf,
7627 0x86,0xea,0x00,0xaa,0x00,0xb9,0x29,0xe8 },
7628 { 0, 0,
7629 0, 0, 0,
7630 0, 0, 0, 0, 0, 0, 0, 0 }
7633 for( const _ObjImpType* pArr = aArr; pArr->nFlag; ++pArr )
7635 if( nConvertFlags & pArr->nFlag )
7637 SvGlobalName aTypeName( pArr->n1, pArr->n2, pArr->n3,
7638 pArr->b8, pArr->b9, pArr->b10, pArr->b11,
7639 pArr->b12, pArr->b13, pArr->b14, pArr->b15 );
7641 if ( aStgNm == aTypeName )
7643 sStarName = String::CreateFromAscii( pArr->pFactoryNm );
7644 break;
7650 if ( sStarName.Len() )
7652 //TODO/MBA: check if (and when) storage and stream will be destroyed!
7653 const SfxFilter* pFilter = 0;
7654 SvMemoryStream* pStream = new SvMemoryStream;
7655 if ( pName )
7657 // TODO/LATER: perhaps we need to retrieve VisArea and Metafile from the storage also
7658 SotStorageStreamRef xStr = rSrcStg.OpenSotStream( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "package_stream" ) ), STREAM_STD_READ );
7659 *xStr >> *pStream;
7661 else
7663 SfxFilterMatcher aMatch( sStarName );
7664 SotStorageRef xStorage = new SotStorage( FALSE, *pStream );
7665 rSrcStg.CopyTo( xStorage );
7666 xStorage->Commit();
7667 xStorage.Clear();
7668 String aType = SfxFilter::GetTypeFromStorage( rSrcStg );
7669 if ( aType.Len() )
7670 pFilter = aMatch.GetFilter4EA( aType );
7673 //#define DBG_EXTRACTOLESTREAMS
7674 #ifdef DBG_EXTRACTOLESTREAMS
7675 static sal_Int32 nCount(0);
7676 String aTmpName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("/tmp/embedded_stream_")));
7677 aTmpName += String::CreateFromInt32(nCount++);
7678 aTmpName += String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(".bin"));
7679 SvFileStream aTmpStream(aTmpName,STREAM_READ|STREAM_WRITE|STREAM_TRUNC);
7680 pStream->Seek(0);
7681 *pStream >> aTmpStream;
7682 aTmpStream.Close();
7683 #endif
7685 if ( pName || pFilter )
7687 //Reuse current ole name
7688 String aDstStgName(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7689 aDstStgName += String::CreateFromInt32(nMSOleObjCntr);
7691 ::rtl::OUString aFilterName;
7692 if ( pFilter )
7693 aFilterName = pFilter->GetName();
7694 else
7695 aFilterName = GetFilterNameFromClassID_Impl( aStgNm );
7697 uno::Sequence < beans::PropertyValue > aMedium( aFilterName.getLength() ? 3 : 2);
7698 aMedium[0].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "InputStream" ) );
7699 uno::Reference < io::XInputStream > xStream = new ::utl::OSeekableInputStreamWrapper( *pStream );
7700 aMedium[0].Value <<= xStream;
7701 aMedium[1].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "URL" ) );
7702 aMedium[1].Value <<= ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "private:stream" ) );
7704 if ( aFilterName.getLength() )
7706 aMedium[2].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "FilterName" ) );
7707 aMedium[2].Value <<= aFilterName;
7710 ::rtl::OUString aName( aDstStgName );
7711 comphelper::EmbeddedObjectContainer aCnt( rDestStorage );
7712 xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7714 if ( !xObj.is() )
7716 if( aFilterName.getLength() )
7718 // throw the filter parameter away as workaround
7719 aMedium.realloc( 2 );
7720 xObj = aCnt.InsertEmbeddedObject( aMedium, aName );
7723 if ( !xObj.is() )
7724 return xObj;
7727 // TODO/LATER: ViewAspect must be passed from outside!
7728 sal_Int64 nViewAspect = embed::Aspects::MSOLE_CONTENT;
7730 // JP 26.10.2001: Bug 93374 / 91928 the writer
7731 // objects need the correct visarea needs the
7732 // correct visarea, but this is not true for
7733 // PowerPoint (see bugdoc 94908b)
7734 // SJ: 19.11.2001 bug 94908, also chart objects
7735 // needs the correct visarea
7737 // If pName is set this is an own embedded object, it should have the correct size internally
7738 // TODO/LATER: it might make sence in future to set the size stored in internal object
7739 if( !pName && ( sStarName.EqualsAscii( "swriter" ) || sStarName.EqualsAscii( "scalc" ) ) )
7741 MapMode aMapMode( VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nViewAspect ) ) );
7742 Size aSz;
7743 if ( rVisArea.IsEmpty() )
7744 aSz = lcl_GetPrefSize(rGrf, aMapMode );
7745 else
7747 aSz = rVisArea.GetSize();
7748 aSz = OutputDevice::LogicToLogic( aSz, MapMode( MAP_100TH_MM ), aMapMode );
7751 // don't modify the object
7752 //TODO/LATER: remove those hacks, that needs to be done differently!
7753 //xIPObj->EnableSetModified( FALSE );
7754 awt::Size aSize;
7755 aSize.Width = aSz.Width();
7756 aSize.Height = aSz.Height();
7757 xObj->setVisualAreaSize( nViewAspect, aSize );
7758 //xIPObj->EnableSetModified( TRUE );
7760 else if ( sStarName.EqualsAscii( "smath" ) )
7761 { // SJ: force the object to recalc its visarea
7762 //TODO/LATER: wait for PrinterChangeNotification
7763 //xIPObj->OnDocumentPrinterChanged( NULL );
7768 return xObj;
7771 // TODO/MBA: code review and testing!
7772 SdrOle2Obj* SvxMSDffManager::CreateSdrOLEFromStorage(
7773 const String& rStorageName,
7774 SotStorageRef& rSrcStorage,
7775 const uno::Reference < embed::XStorage >& xDestStorage,
7776 const Graphic& rGrf,
7777 const Rectangle& rBoundRect,
7778 const Rectangle& rVisArea,
7779 SvStream* pDataStrm,
7780 ErrCode& rError,
7781 UINT32 nConvertFlags,
7782 sal_Int64 nReccomendedAspect )
7784 sal_Int64 nAspect = nReccomendedAspect;
7785 SdrOle2Obj* pRet = 0;
7786 if( rSrcStorage.Is() && xDestStorage.is() && rStorageName.Len() )
7788 comphelper::EmbeddedObjectContainer aCnt( xDestStorage );
7789 // Ist der 01Ole-Stream ueberhaupt vorhanden ?
7790 // ( ist er z.B. bei FontWork nicht )
7791 // Wenn nicht -> Einbindung als Grafik
7792 BOOL bValidStorage = FALSE;
7793 String aDstStgName( String::CreateFromAscii(
7794 RTL_CONSTASCII_STRINGPARAM(MSO_OLE_Obj)));
7796 aDstStgName += String::CreateFromInt32( ++nMSOleObjCntr );
7799 SvStorageRef xObjStg = rSrcStorage->OpenSotStorage( rStorageName,
7800 STREAM_READWRITE| STREAM_SHARE_DENYALL );
7801 if( xObjStg.Is() )
7804 BYTE aTestA[10]; // exist the \1CompObj-Stream ?
7805 SvStorageStreamRef xSrcTst = xObjStg->OpenSotStream(
7806 String(RTL_CONSTASCII_STRINGPARAM("\1CompObj"),
7807 RTL_TEXTENCODING_MS_1252 ));
7808 bValidStorage = xSrcTst.Is() && sizeof( aTestA ) ==
7809 xSrcTst->Read( aTestA, sizeof( aTestA ) );
7810 if( !bValidStorage )
7812 // or the \1Ole-Stream ?
7813 xSrcTst = xObjStg->OpenSotStream(
7814 String(RTL_CONSTASCII_STRINGPARAM("\1Ole"),
7815 RTL_TEXTENCODING_MS_1252 ));
7816 bValidStorage = xSrcTst.Is() && sizeof(aTestA) ==
7817 xSrcTst->Read(aTestA, sizeof(aTestA));
7821 if( bValidStorage )
7823 if ( nAspect != embed::Aspects::MSOLE_ICON )
7825 // check whether the object is iconified one
7826 // usually this information is already known, the only exception
7827 // is a kind of embedded objects in Word documents
7828 // TODO/LATER: should the caller be notified if the aspect changes in future?
7830 SvStorageStreamRef xObjInfoSrc = xObjStg->OpenSotStream(
7831 String( RTL_CONSTASCII_STRINGPARAM( "\3ObjInfo" ) ),
7832 STREAM_STD_READ | STREAM_NOCREATE );
7833 if ( xObjInfoSrc.Is() && !xObjInfoSrc->GetError() )
7835 BYTE nByte = 0;
7836 *xObjInfoSrc >> nByte;
7837 if ( ( nByte >> 4 ) & embed::Aspects::MSOLE_ICON )
7838 nAspect = embed::Aspects::MSOLE_ICON;
7842 uno::Reference < embed::XEmbeddedObject > xObj( CheckForConvertToSOObj(
7843 nConvertFlags, *xObjStg, xDestStorage, rGrf, rVisArea ));
7844 if ( xObj.is() )
7846 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7848 // TODO/LATER: need MediaType
7849 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7851 // TODO/MBA: check setting of PersistName
7852 pRet = new SdrOle2Obj( aObj, String(), rBoundRect, false);
7853 // we have the Object, don't create another
7854 bValidStorage = false;
7860 if( bValidStorage )
7862 // object is not an own object
7863 SotStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName, STREAM_READWRITE );
7865 if ( xObjStor.Is() )
7867 SotStorageRef xSrcStor = rSrcStorage->OpenSotStorage( rStorageName, STREAM_READ );
7868 xSrcStor->CopyTo( xObjStor );
7870 if( !xObjStor->GetError() )
7871 xObjStor->Commit();
7873 if( xObjStor->GetError() )
7875 rError = xObjStor->GetError();
7876 bValidStorage = FALSE;
7878 else if( !xObjStor.Is() )
7879 bValidStorage = FALSE;
7882 else if( pDataStrm )
7884 UINT32 nLen, nDummy;
7885 *pDataStrm >> nLen >> nDummy;
7886 if( SVSTREAM_OK != pDataStrm->GetError() ||
7887 // Id in BugDoc - exist there other Ids?
7888 // The ConvertToOle2 - does not check for consistent
7889 0x30008 != nDummy )
7890 bValidStorage = FALSE;
7891 else
7893 // or is it an OLE-1 Stream in the DataStream?
7894 SvStorageRef xObjStor = SotStorage::OpenOLEStorage( xDestStorage, aDstStgName );
7895 //TODO/MBA: remove metafile conversion from ConvertToOle2
7896 //when is this code used?!
7897 GDIMetaFile aMtf;
7898 bValidStorage = ConvertToOle2( *pDataStrm, nLen, &aMtf, xObjStor );
7899 xObjStor->Commit();
7903 if( bValidStorage )
7905 uno::Reference < embed::XEmbeddedObject > xObj = aCnt.GetEmbeddedObject( aDstStgName );
7906 if( xObj.is() )
7908 // the visual area must be retrieved from the metafile (object doesn't know it so far)
7910 if ( nAspect != embed::Aspects::MSOLE_ICON )
7912 // working with visual area can switch the object to running state
7913 awt::Size aAwtSz;
7916 // the provided visual area should be used, if there is any
7917 if ( rVisArea.IsEmpty() )
7919 MapUnit aMapUnit = VCLUnoHelper::UnoEmbed2VCLMapUnit( xObj->getMapUnit( nAspect ) );
7920 Size aSz(lcl_GetPrefSize(rGrf, MapMode(aMapUnit)));
7921 aAwtSz.Width = aSz.Width();
7922 aAwtSz.Height = aSz.Height();
7924 else
7926 aAwtSz.Width = rVisArea.GetWidth();
7927 aAwtSz.Height = rVisArea.GetHeight();
7929 //xInplaceObj->EnableSetModified( FALSE );
7930 xObj->setVisualAreaSize( nAspect, aAwtSz );
7931 //xInplaceObj->EnableSetModified( TRUE );*/
7933 catch( uno::Exception& )
7935 OSL_ENSURE( sal_False, "Could not set visual area of the object!\n" );
7939 svt::EmbeddedObjectRef aObj( xObj, nAspect );
7941 // TODO/LATER: need MediaType
7942 aObj.SetGraphic( rGrf, ::rtl::OUString() );
7944 pRet = new SdrOle2Obj( aObj, aDstStgName, rBoundRect, false);
7949 return pRet;
7952 SdrObject* SvxMSDffManager::GetAutoForm( MSO_SPT eTyp ) const
7954 SdrObject* pRet = NULL;
7956 if(120 >= UINT16(eTyp))
7958 pRet = new SdrRectObj();
7961 DBG_ASSERT(pRet, "SvxMSDffManager::GetAutoForm -> UNKNOWN AUTOFORM");
7963 return pRet;
7966 sal_Bool SvxMSDffManager::SetPropValue( const uno::Any& rAny, const uno::Reference< ::com::sun::star::beans::XPropertySet > & rXPropSet,
7967 const String& rPropName, sal_Bool bTestPropertyAvailability )
7969 sal_Bool bRetValue = sal_True;
7970 if ( bTestPropertyAvailability )
7972 bRetValue = sal_False;
7975 uno::Reference< beans::XPropertySetInfo >
7976 aXPropSetInfo( rXPropSet->getPropertySetInfo() );
7977 if ( aXPropSetInfo.is() )
7978 bRetValue = aXPropSetInfo->hasPropertyByName( rPropName );
7980 catch( uno::Exception& )
7982 bRetValue = sal_False;
7985 if ( bRetValue )
7989 rXPropSet->setPropertyValue( rPropName, rAny );
7990 bRetValue = sal_True;
7992 catch( uno::Exception& )
7994 bRetValue = sal_False;
7997 return bRetValue;
8000 SvxMSDffImportRec::SvxMSDffImportRec()
8001 : pObj( 0 ),
8002 pWrapPolygon(0),
8003 pClientAnchorBuffer( 0 ),
8004 nClientAnchorLen( 0 ),
8005 pClientDataBuffer( 0 ),
8006 nClientDataLen( 0 ),
8007 nXAlign( 0 ), // position n cm from left
8008 nXRelTo( 2 ), // relative to column
8009 nYAlign( 0 ), // position n cm below
8010 nYRelTo( 2 ), // relative to paragraph
8011 nLayoutInTableCell( 0 ), // element is laid out in table cell
8012 nTextRotationAngle( 0 ),
8013 nDxTextLeft( 144 ),
8014 nDyTextTop( 72 ),
8015 nDxTextRight( 144 ),
8016 nDyTextBottom( 72 ),
8017 nDxWrapDistLeft( 0 ),
8018 nDyWrapDistTop( 0 ),
8019 nDxWrapDistRight( 0 ),
8020 nDyWrapDistBottom(0 ),
8021 nCropFromTop( 0 ),
8022 nCropFromBottom( 0 ),
8023 nCropFromLeft( 0 ),
8024 nCropFromRight( 0 ),
8025 aTextId( 0, 0 ),
8026 nNextShapeId( 0 ),
8027 nShapeId( 0 ),
8028 eShapeType( mso_sptNil )
8030 eLineStyle = mso_lineSimple; // GPF-Bug #66227#
8031 bDrawHell = FALSE;
8032 bHidden = FALSE;
8033 // bInGroup = FALSE;
8034 bReplaceByFly = FALSE;
8035 bLastBoxInChain = TRUE;
8036 bHasUDefProp = FALSE; // was the DFF_msofbtUDefProp record set?
8037 bVFlip = FALSE;
8038 bHFlip = FALSE;
8039 bAutoWidth = FALSE;
8042 SvxMSDffImportRec::SvxMSDffImportRec(const SvxMSDffImportRec& rCopy)
8043 : pObj( rCopy.pObj ),
8044 nXAlign( rCopy.nXAlign ),
8045 nXRelTo( rCopy.nXRelTo ),
8046 nYAlign( rCopy.nYAlign ),
8047 nYRelTo( rCopy.nYRelTo ),
8048 nLayoutInTableCell( rCopy.nLayoutInTableCell ),
8049 nTextRotationAngle( rCopy.nTextRotationAngle ),
8050 nDxTextLeft( rCopy.nDxTextLeft ),
8051 nDyTextTop( rCopy.nDyTextTop ),
8052 nDxTextRight( rCopy.nDxTextRight ),
8053 nDyTextBottom( rCopy.nDyTextBottom ),
8054 nDxWrapDistLeft( rCopy.nDxWrapDistLeft ),
8055 nDyWrapDistTop( rCopy.nDyWrapDistTop ),
8056 nDxWrapDistRight( rCopy.nDxWrapDistRight ),
8057 nDyWrapDistBottom(rCopy.nDyWrapDistBottom ),
8058 nCropFromTop( rCopy.nCropFromTop ),
8059 nCropFromBottom( rCopy.nCropFromBottom ),
8060 nCropFromLeft( rCopy.nCropFromLeft ),
8061 nCropFromRight( rCopy.nCropFromRight ),
8062 aTextId( rCopy.aTextId ),
8063 nNextShapeId( rCopy.nNextShapeId ),
8064 nShapeId( rCopy.nShapeId ),
8065 eShapeType( rCopy.eShapeType )
8067 eLineStyle = rCopy.eLineStyle; // GPF-Bug #66227#
8068 bDrawHell = rCopy.bDrawHell;
8069 bHidden = rCopy.bHidden;
8070 // bInGroup = rCopy.bInGroup;
8071 bReplaceByFly = rCopy.bReplaceByFly;
8072 bAutoWidth = rCopy.bAutoWidth;
8073 bLastBoxInChain = rCopy.bLastBoxInChain;
8074 bHasUDefProp = rCopy.bHasUDefProp;
8075 bVFlip = rCopy.bVFlip;
8076 bHFlip = rCopy.bHFlip;
8077 nClientAnchorLen = rCopy.nClientAnchorLen;
8078 if( rCopy.nClientAnchorLen )
8080 pClientAnchorBuffer = new char[ nClientAnchorLen ];
8081 memcpy( pClientAnchorBuffer,
8082 rCopy.pClientAnchorBuffer,
8083 nClientAnchorLen );
8085 else
8086 pClientAnchorBuffer = 0;
8088 nClientDataLen = rCopy.nClientDataLen;
8089 if( rCopy.nClientDataLen )
8091 pClientDataBuffer = new char[ nClientDataLen ];
8092 memcpy( pClientDataBuffer,
8093 rCopy.pClientDataBuffer,
8094 nClientDataLen );
8096 else
8097 pClientDataBuffer = 0;
8099 if (rCopy.pWrapPolygon)
8100 pWrapPolygon = new Polygon(*rCopy.pWrapPolygon);
8101 else
8102 pWrapPolygon = 0;
8105 SvxMSDffImportRec::~SvxMSDffImportRec()
8107 if (pClientAnchorBuffer)
8108 delete[] pClientAnchorBuffer;
8109 if (pClientDataBuffer)
8110 delete[] pClientDataBuffer;
8111 if (pWrapPolygon)
8112 delete pWrapPolygon;
8115 /* vi:set tabstop=4 shiftwidth=4 expandtab: */
8117 void SvxMSDffManager::insertShapeId( sal_Int32 nShapeId, SdrObject* pShape )
8119 maShapeIdContainer[nShapeId] = pShape;
8122 void SvxMSDffManager::removeShapeId( SdrObject* pShape )
8124 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.begin() );
8125 const SvxMSDffShapeIdContainer::iterator aEnd( maShapeIdContainer.end() );
8126 while( aIter != aEnd )
8128 if( (*aIter).second == pShape )
8130 maShapeIdContainer.erase( aIter );
8131 break;
8136 SdrObject* SvxMSDffManager::getShapeForId( sal_Int32 nShapeId )
8138 SvxMSDffShapeIdContainer::iterator aIter( maShapeIdContainer.find(nShapeId) );
8139 return aIter != maShapeIdContainer.end() ? (*aIter).second : 0;